* Added RS232/RS485 Packet Analyzer (Tools -> Packet Analyzer)
* Updated BMS History register request/response length by model
* Fixed decimal truncation issue in Brazil locale for DB/CSV Log and Excel Export
This commit is contained in:
2026-11-06 15:35:44 +09:00
parent 56e341a48a
commit e041527b56
42 changed files with 5888 additions and 160 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class FmxChangePw
{
@@ -321,7 +321,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(500, 233);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.AMO_LOGO1;
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "FmxLevelConfig";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Control Level Config";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class FmxInformation
{
@@ -163,7 +163,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(767, 398);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.AMO_LOGO1;
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "FmxInformation";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Information";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class FmxLevelConfig
{
@@ -321,7 +321,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(500, 233);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.AMO_LOGO1;
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "FmxLevelConfig";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Control Level Config";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class FmxPassword
{
@@ -201,7 +201,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(500, 206);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.AMO_LOGO1;
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "FmxPassword";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Reset Password";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class FmxPasswordChange
{
@@ -419,7 +419,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(500, 265);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.AMO_LOGO1;
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "FmxPasswordChange";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Change Password";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class fmxAntiTheft
{
@@ -132,7 +132,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(858, 226);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Icon = ((System.Drawing.Icon)(resources.GetObject("fmxAntiTheft.IconOptions.Icon")));
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxAntiTheft";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Anti-Theft";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class fmxCalibration
{
@@ -134,7 +134,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(814, 444);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Icon = ((System.Drawing.Icon)(resources.GetObject("fmxCalibration.IconOptions.Icon")));
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxCalibration";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Calibration";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class fmxCommConfig
{
@@ -85,7 +85,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(404, 596);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Icon = ((System.Drawing.Icon)(resources.GetObject("fmxCommConfig.IconOptions.Icon")));
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxCommConfig";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Communication Config";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
{
partial class fmxEtcStatus
@@ -125,7 +125,7 @@ namespace LFP_Manager.Forms
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(612, 406);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Image = ((System.Drawing.Image)(resources.GetObject("fmxEtcStatus.IconOptions.Image")));
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxEtcStatus";
this.Text = "fmxEtcStatus";
((System.ComponentModel.ISupportInitialize)(this.layoutControl1)).EndInit();

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager
namespace LFP_Manager
{
partial class fmxExcelFile
{
@@ -675,7 +675,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(999, 578);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Icon = ((System.Drawing.Icon)(resources.GetObject("fmxExcelFile.IconOptions.Icon")));
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxExcelFile";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Database Control";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager
namespace LFP_Manager
{
partial class fmxFwUpdate
{
@@ -558,7 +558,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(736, 478);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Icon = ((System.Drawing.Icon)(resources.GetObject("fmxFwUpdate.IconOptions.Icon")));
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxFwUpdate";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "fmFwUpdate";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class fmxHistory
{
@@ -846,7 +846,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(911, 602);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Image = ((System.Drawing.Image)(resources.GetObject("fmxHistory.IconOptions.Image")));
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxHistory";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "History";

View File

@@ -1,4 +1,4 @@
using DevExpress.Utils;
using DevExpress.Utils;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
@@ -24,6 +24,7 @@ namespace LFP_Manager.Forms
private byte[] rData = null;
private ushort curr_addr = 0;
private int recv_data_len = 0;
private ushort req_reg_qty = 0x1C;
private int hist_no = 0;
private bool stopReq = true;
@@ -52,12 +53,14 @@ namespace LFP_Manager.Forms
switch (Config.UartModelIndex)
{
case csConstData.MODEL_INDEX.LFPM_124050D:
recv_data_len = 112;
req_reg_qty = 0x35; // 53 registers
recv_data_len = 112; // 1 (ID) + 1 (0x03) + 1 (0x6A/106 bytes) + 106 + 2 (CRC) = 111~112 bytes
cell_qty = 39;
temp_qty = 8;
break;
default:
recv_data_len = 58;
req_reg_qty = 0x1C; // 28 registers (0x1C)
recv_data_len = 61; // 1 (ID) + 1 (0x03) + 1 (0x38/56 bytes) + 56 + 2 (CRC) = 61 bytes
cell_qty = 16;
temp_qty = 4;
break;
@@ -314,7 +317,7 @@ namespace LFP_Manager.Forms
LcGrResult.Text = $"Result ({rData.Length})";
if ((rData != null) && (rData.Length == recv_data_len))
if ((rData != null) && (rData.Length == recv_data_len || (rData.Length >= 5 && rData[1] == 0x03 && rData.Length == (3 + rData[2] + 2))))
{
try
{
@@ -434,8 +437,8 @@ namespace LFP_Manager.Forms
sdata[1] = 0x03; // Function Code
sdata[2] = (byte)(addr >> 8); // Address H
sdata[3] = (byte)(addr >> 0); // Address L
sdata[4] = 0x00; // Number of Register H
sdata[5] = 0x35; // Number of Register L
sdata[4] = (byte)(req_reg_qty >> 8); // Number of Register H
sdata[5] = (byte)(req_reg_qty >> 0); // Number of Register L
crc = csSerialCommFunction.GetCRC(sdata, 6);

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class fmxInventoryConfig
{
@@ -389,7 +389,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(720, 425);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Icon = ((System.Drawing.Icon)(resources.GetObject("fmxInventoryConfig.IconOptions.Icon")));
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxInventoryConfig";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Inventory Config";

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class fmxMain
{
@@ -60,6 +60,8 @@
this.historyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.historyViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.inventoryViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.packetLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.updateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.firmwareUpdateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)(this.layoutControl1)).BeginInit();
@@ -312,6 +314,7 @@
this.mnMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.historyToolStripMenuItem,
this.toolsToolStripMenuItem,
this.updateToolStripMenuItem});
this.mnMain.Location = new System.Drawing.Point(0, 0);
this.mnMain.Name = "mnMain";
@@ -382,6 +385,21 @@
this.inventoryViewToolStripMenuItem.Text = "Inventory View";
this.inventoryViewToolStripMenuItem.Click += new System.EventHandler(this.inventoryViewToolStripMenuItem_Click);
//
// toolsToolStripMenuItem
//
this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.packetLogToolStripMenuItem});
this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
this.toolsToolStripMenuItem.Size = new System.Drawing.Size(46, 20);
this.toolsToolStripMenuItem.Text = "Tools";
//
// packetLogToolStripMenuItem
//
this.packetLogToolStripMenuItem.Name = "packetLogToolStripMenuItem";
this.packetLogToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.packetLogToolStripMenuItem.Text = "Packet Analyzer";
this.packetLogToolStripMenuItem.Click += new System.EventHandler(this.packetLogToolStripMenuItem_Click);
//
// updateToolStripMenuItem
//
this.updateToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -463,6 +481,8 @@
private System.Windows.Forms.ToolStripMenuItem updateToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem firmwareUpdateToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem inventoryViewToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem packetLogToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem levelConfigToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem changeLeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem changePasswordToolStripMenuItem;

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
@@ -28,6 +28,7 @@ namespace LFP_Manager.Forms
private fmxModuleDetail ModuleDetailForm = null;
private fmxFwUpdate FwUpdateForm = null;
private fmxHistory HistoryForm = null;
private fmxPacketLog PacketLogForm = null;
// Static Variables
private CommConfig Config = new CommConfig();
@@ -59,6 +60,15 @@ namespace LFP_Manager.Forms
{
InitializeComponent();
if (Program.DeltaLogoBitmap != null)
{
this.IconOptions.Image = Program.DeltaLogoBitmap;
}
else if (global::LFP_Manager.Properties.Resources.Delta_Logo_1 != null)
{
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
}
StructDataInit();
//DataInit();
@@ -292,6 +302,7 @@ namespace LFP_Manager.Forms
uartThread.OnUpdate += UpdateDataUart;
uartThread.OnDataRecv += UartRecvData;
uartThread.OnPrint += CommDataPrint;
uartThread.OnPacketLog += PacketLogUpdate;
uartThread.SetPolling(chbPolling.Checked, ModuleID, ref SystemData[ModuleID - 1]);
if (uartThread.Start(ref Config, ModuleID, chbPolling.Checked))
@@ -349,6 +360,7 @@ namespace LFP_Manager.Forms
rs232Thread124050.OnUpdate += UpdateDataUart;
rs232Thread124050.OnDataRecv += UartRecvData;
rs232Thread124050.OnPrint += CommDataPrint;
rs232Thread124050.OnPacketLog += PacketLogUpdate;
rs232Thread124050.SetPolling(chbPolling.Checked, ModuleID, ref SystemData[ModuleID - 1]);
if (rs232Thread124050.Start(ref Config, ModuleID, chbPolling.Checked))
@@ -410,6 +422,7 @@ namespace LFP_Manager.Forms
rs485Thread.OnUpdate += UpdateDataRS485;
rs485Thread.OnDataRecv += UartRecvData;
rs485Thread.OnPrint += CommDataPrint;
rs485Thread.OnPacketLog += PacketLogUpdate;
rs485Thread.SetPolling(chbPolling.Checked, ModuleID, ref SystemData);
if (rs485Thread.Start(ref Config, ModuleID, chbPolling.Checked))
@@ -465,6 +478,7 @@ namespace LFP_Manager.Forms
rs485Thread124050.OnUpdate += UpdateDataRS485;
rs485Thread124050.OnDataRecv += UartRecvData;
rs485Thread124050.OnPrint += CommDataPrint;
rs485Thread124050.OnPacketLog += PacketLogUpdate;
rs485Thread124050.SetPolling(chbPolling.Checked, ModuleID, ref SystemData);
if (rs485Thread124050.Start(ref Config, ModuleID, chbPolling.Checked))
@@ -895,6 +909,8 @@ namespace LFP_Manager.Forms
private void UpdateSnmpData(object sender, ref DeviceSystemData rData)
{
ShelfStatus?.UpdateData(ref SystemData);
dbThread?.UpdateData(ModuleID, SystemData);
uDataLog.UpdateData(SystemData);
}
@@ -961,6 +977,31 @@ namespace LFP_Manager.Forms
HistoryForm.ShowDialog();
}
private void packetLogToolStripMenuItem_Click(object sender, EventArgs e)
{
if (PacketLogForm == null || PacketLogForm.IsDisposed)
{
PacketLogForm = new fmxPacketLog();
}
if (PacketLogForm.Visible)
{
PacketLogForm.Activate();
}
else
{
PacketLogForm.Show(this);
}
}
private void PacketLogUpdate(DateTime timestamp, bool isTx, byte[] data, string description)
{
if (PacketLogForm != null && !PacketLogForm.IsDisposed)
{
PacketLogForm.AddPacketLog(timestamp, isTx, data, description);
}
}
private void inventoryViewToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (Form frm in Application.OpenForms)

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
{
partial class fmxModuleDetail
@@ -177,7 +177,7 @@ namespace LFP_Manager.Forms
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1078, 648);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Image = ((System.Drawing.Image)(resources.GetObject("fmxModuleDetail.IconOptions.Image")));
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxModuleDetail";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "fmxModuleDetail";

396
LFP_Manager/Forms/fmxPacketLog.Designer.cs generated Normal file
View File

@@ -0,0 +1,396 @@
namespace LFP_Manager.Forms
{
partial class fmxPacketLog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pnlTop = new DevExpress.XtraEditors.PanelControl();
this.lblStatus = new DevExpress.XtraEditors.LabelControl();
this.btnExport = new DevExpress.XtraEditors.SimpleButton();
this.cmbFilter = new DevExpress.XtraEditors.ComboBoxEdit();
this.lblFilter = new DevExpress.XtraEditors.LabelControl();
this.chkAutoScroll = new DevExpress.XtraEditors.CheckEdit();
this.btnClear = new DevExpress.XtraEditors.SimpleButton();
this.btnCapture = new DevExpress.XtraEditors.SimpleButton();
this.gcPacketLog = new DevExpress.XtraGrid.GridControl();
this.gvPacketLog = new DevExpress.XtraGrid.Views.Grid.GridView();
this.colNo = new DevExpress.XtraGrid.Columns.GridColumn();
this.colTime = new DevExpress.XtraGrid.Columns.GridColumn();
this.colDir = new DevExpress.XtraGrid.Columns.GridColumn();
this.colDevId = new DevExpress.XtraGrid.Columns.GridColumn();
this.colFunc = new DevExpress.XtraGrid.Columns.GridColumn();
this.colLen = new DevExpress.XtraGrid.Columns.GridColumn();
this.colHex = new DevExpress.XtraGrid.Columns.GridColumn();
this.colDesc = new DevExpress.XtraGrid.Columns.GridColumn();
this.colCrc = new DevExpress.XtraGrid.Columns.GridColumn();
this.grpDetail = new DevExpress.XtraEditors.GroupControl();
this.txtDetail = new DevExpress.XtraEditors.MemoEdit();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
((System.ComponentModel.ISupportInitialize)(this.pnlTop)).BeginInit();
this.pnlTop.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.cmbFilter.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.chkAutoScroll.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.gcPacketLog)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.gvPacketLog)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.grpDetail)).BeginInit();
this.grpDetail.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.txtDetail.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.SuspendLayout();
//
// pnlTop
//
this.pnlTop.Controls.Add(this.lblStatus);
this.pnlTop.Controls.Add(this.btnExport);
this.pnlTop.Controls.Add(this.cmbFilter);
this.pnlTop.Controls.Add(this.lblFilter);
this.pnlTop.Controls.Add(this.chkAutoScroll);
this.pnlTop.Controls.Add(this.btnClear);
this.pnlTop.Controls.Add(this.btnCapture);
this.pnlTop.Dock = System.Windows.Forms.DockStyle.Top;
this.pnlTop.Location = new System.Drawing.Point(0, 0);
this.pnlTop.Name = "pnlTop";
this.pnlTop.Size = new System.Drawing.Size(984, 46);
this.pnlTop.TabIndex = 0;
//
// lblStatus
//
this.lblStatus.Appearance.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblStatus.Appearance.Options.UseFont = true;
this.lblStatus.Location = new System.Drawing.Point(595, 16);
this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(127, 14);
this.lblStatus.TabIndex = 6;
this.lblStatus.Text = "Total: 0 | TX: 0 | RX: 0";
//
// btnExport
//
this.btnExport.Location = new System.Drawing.Point(475, 10);
this.btnExport.Name = "btnExport";
this.btnExport.Size = new System.Drawing.Size(95, 26);
this.btnExport.TabIndex = 5;
this.btnExport.Text = "Export Excel";
this.btnExport.Click += new System.EventHandler(this.btnExport_Click);
//
// cmbFilter
//
this.cmbFilter.EditValue = "ALL";
this.cmbFilter.Location = new System.Drawing.Point(345, 13);
this.cmbFilter.Name = "cmbFilter";
this.cmbFilter.Properties.Buttons.AddRange(new DevExpress.XtraEditors.Controls.EditorButton[] {
new DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)});
this.cmbFilter.Properties.Items.AddRange(new object[] {
"ALL",
"TX Only",
"RX Only",
"Error Only"});
this.cmbFilter.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;
this.cmbFilter.Size = new System.Drawing.Size(115, 20);
this.cmbFilter.TabIndex = 4;
this.cmbFilter.SelectedIndexChanged += new System.EventHandler(this.cmbFilter_SelectedIndexChanged);
//
// lblFilter
//
this.lblFilter.Appearance.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblFilter.Appearance.Options.UseFont = true;
this.lblFilter.Location = new System.Drawing.Point(295, 16);
this.lblFilter.Name = "lblFilter";
this.lblFilter.Size = new System.Drawing.Size(43, 14);
this.lblFilter.TabIndex = 3;
this.lblFilter.Text = "Filter : ";
//
// chkAutoScroll
//
this.chkAutoScroll.EditValue = true;
this.chkAutoScroll.Location = new System.Drawing.Point(195, 13);
this.chkAutoScroll.Name = "chkAutoScroll";
this.chkAutoScroll.Properties.Appearance.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.chkAutoScroll.Properties.Appearance.Options.UseFont = true;
this.chkAutoScroll.Properties.Caption = "Auto Scroll";
this.chkAutoScroll.Size = new System.Drawing.Size(88, 20);
this.chkAutoScroll.TabIndex = 2;
//
// btnClear
//
this.btnClear.Location = new System.Drawing.Point(100, 10);
this.btnClear.Name = "btnClear";
this.btnClear.Size = new System.Drawing.Size(75, 26);
this.btnClear.TabIndex = 1;
this.btnClear.Text = "Clear";
this.btnClear.Click += new System.EventHandler(this.btnClear_Click);
//
// btnCapture
//
this.btnCapture.Location = new System.Drawing.Point(12, 10);
this.btnCapture.Name = "btnCapture";
this.btnCapture.Size = new System.Drawing.Size(75, 26);
this.btnCapture.TabIndex = 0;
this.btnCapture.Text = "Pause";
this.btnCapture.Click += new System.EventHandler(this.btnCapture_Click);
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 46);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.gcPacketLog);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.grpDetail);
this.splitContainer1.Size = new System.Drawing.Size(984, 585);
this.splitContainer1.SplitterDistance = 370;
this.splitContainer1.TabIndex = 1;
//
// gcPacketLog
//
this.gcPacketLog.Dock = System.Windows.Forms.DockStyle.Fill;
this.gcPacketLog.Location = new System.Drawing.Point(0, 0);
this.gcPacketLog.MainView = this.gvPacketLog;
this.gcPacketLog.Name = "gcPacketLog";
this.gcPacketLog.Size = new System.Drawing.Size(984, 370);
this.gcPacketLog.TabIndex = 0;
this.gcPacketLog.ViewCollection.AddRange(new DevExpress.XtraGrid.Views.Base.BaseView[] {
this.gvPacketLog});
//
// gvPacketLog
//
this.gvPacketLog.Columns.AddRange(new DevExpress.XtraGrid.Columns.GridColumn[] {
this.colNo,
this.colTime,
this.colDir,
this.colDevId,
this.colFunc,
this.colLen,
this.colHex,
this.colDesc,
this.colCrc});
this.gvPacketLog.GridControl = this.gcPacketLog;
this.gvPacketLog.Name = "gvPacketLog";
this.gvPacketLog.OptionsBehavior.Editable = false;
this.gvPacketLog.OptionsBehavior.ReadOnly = true;
this.gvPacketLog.OptionsSelection.EnableAppearanceFocusedCell = false;
this.gvPacketLog.OptionsView.ColumnAutoWidth = false;
this.gvPacketLog.OptionsView.ShowGroupPanel = false;
this.gvPacketLog.OptionsView.ShowIndicator = false;
this.gvPacketLog.RowStyle += new DevExpress.XtraGrid.Views.Grid.RowStyleEventHandler(this.gvPacketLog_RowStyle);
this.gvPacketLog.FocusedRowChanged += new DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventHandler(this.gvPacketLog_FocusedRowChanged);
//
// colNo
//
this.colNo.AppearanceCell.Options.UseTextOptions = true;
this.colNo.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colNo.AppearanceHeader.Options.UseTextOptions = true;
this.colNo.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colNo.Caption = "No";
this.colNo.FieldName = "no";
this.colNo.Name = "colNo";
this.colNo.Visible = true;
this.colNo.VisibleIndex = 0;
this.colNo.Width = 45;
//
// colTime
//
this.colTime.AppearanceCell.Options.UseTextOptions = true;
this.colTime.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colTime.AppearanceHeader.Options.UseTextOptions = true;
this.colTime.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colTime.Caption = "Time";
this.colTime.FieldName = "time";
this.colTime.Name = "colTime";
this.colTime.Visible = true;
this.colTime.VisibleIndex = 1;
this.colTime.Width = 90;
//
// colDir
//
this.colDir.AppearanceCell.Options.UseTextOptions = true;
this.colDir.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colDir.AppearanceHeader.Options.UseTextOptions = true;
this.colDir.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colDir.Caption = "Dir";
this.colDir.FieldName = "dir";
this.colDir.Name = "colDir";
this.colDir.Visible = true;
this.colDir.VisibleIndex = 2;
this.colDir.Width = 45;
//
// colDevId
//
this.colDevId.AppearanceCell.Options.UseTextOptions = true;
this.colDevId.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colDevId.AppearanceHeader.Options.UseTextOptions = true;
this.colDevId.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colDevId.Caption = "ID";
this.colDevId.FieldName = "dev_id";
this.colDevId.Name = "colDevId";
this.colDevId.Visible = true;
this.colDevId.VisibleIndex = 3;
this.colDevId.Width = 45;
//
// colFunc
//
this.colFunc.AppearanceCell.Options.UseTextOptions = true;
this.colFunc.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colFunc.AppearanceHeader.Options.UseTextOptions = true;
this.colFunc.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colFunc.Caption = "Func";
this.colFunc.FieldName = "func";
this.colFunc.Name = "colFunc";
this.colFunc.Visible = true;
this.colFunc.VisibleIndex = 4;
this.colFunc.Width = 55;
//
// colLen
//
this.colLen.AppearanceCell.Options.UseTextOptions = true;
this.colLen.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colLen.AppearanceHeader.Options.UseTextOptions = true;
this.colLen.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colLen.Caption = "Len";
this.colLen.FieldName = "len";
this.colLen.Name = "colLen";
this.colLen.Visible = true;
this.colLen.VisibleIndex = 5;
this.colLen.Width = 45;
//
// colHex
//
this.colHex.Caption = "RAW HEX Dump";
this.colHex.FieldName = "hex";
this.colHex.Name = "colHex";
this.colHex.Visible = true;
this.colHex.VisibleIndex = 6;
this.colHex.Width = 360;
//
// colDesc
//
this.colDesc.Caption = "Description";
this.colDesc.FieldName = "desc";
this.colDesc.Name = "colDesc";
this.colDesc.Visible = true;
this.colDesc.VisibleIndex = 7;
this.colDesc.Width = 260;
//
// colCrc
//
this.colCrc.AppearanceCell.Options.UseTextOptions = true;
this.colCrc.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colCrc.AppearanceHeader.Options.UseTextOptions = true;
this.colCrc.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
this.colCrc.Caption = "CRC";
this.colCrc.FieldName = "crc";
this.colCrc.Name = "colCrc";
this.colCrc.Visible = true;
this.colCrc.VisibleIndex = 8;
this.colCrc.Width = 55;
//
// grpDetail
//
this.grpDetail.Controls.Add(this.txtDetail);
this.grpDetail.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpDetail.Location = new System.Drawing.Point(0, 0);
this.grpDetail.Name = "grpDetail";
this.grpDetail.Size = new System.Drawing.Size(984, 211);
this.grpDetail.TabIndex = 0;
this.grpDetail.Text = "Packet Inspector _Analysis";
//
// txtDetail
//
this.txtDetail.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtDetail.Location = new System.Drawing.Point(2, 23);
this.txtDetail.Name = "txtDetail";
this.txtDetail.Properties.Appearance.Font = new System.Drawing.Font("Consolas", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtDetail.Properties.Appearance.Options.UseFont = true;
this.txtDetail.Properties.ReadOnly = true;
this.txtDetail.Size = new System.Drawing.Size(980, 186);
this.txtDetail.TabIndex = 0;
//
// fmxPacketLog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 14F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(984, 631);
this.Controls.Add(this.splitContainer1);
this.Controls.Add(this.pnlTop);
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxPacketLog";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "RS232 Packet Analyzer";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.fmxPacketLog_FormClosing);
((System.ComponentModel.ISupportInitialize)(this.pnlTop)).EndInit();
this.pnlTop.ResumeLayout(false);
this.pnlTop.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.cmbFilter.Properties)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.chkAutoScroll.Properties)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.gcPacketLog)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.gvPacketLog)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.grpDetail)).EndInit();
this.grpDetail.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.txtDetail.Properties)).EndInit();
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private DevExpress.XtraEditors.PanelControl pnlTop;
private DevExpress.XtraEditors.SimpleButton btnCapture;
private DevExpress.XtraEditors.SimpleButton btnClear;
private DevExpress.XtraEditors.CheckEdit chkAutoScroll;
private DevExpress.XtraEditors.LabelControl lblFilter;
private DevExpress.XtraEditors.ComboBoxEdit cmbFilter;
private DevExpress.XtraEditors.SimpleButton btnExport;
private DevExpress.XtraEditors.LabelControl lblStatus;
private System.Windows.Forms.SplitContainer splitContainer1;
private DevExpress.XtraGrid.GridControl gcPacketLog;
private DevExpress.XtraGrid.Views.Grid.GridView gvPacketLog;
private DevExpress.XtraGrid.Columns.GridColumn colNo;
private DevExpress.XtraGrid.Columns.GridColumn colTime;
private DevExpress.XtraGrid.Columns.GridColumn colDir;
private DevExpress.XtraGrid.Columns.GridColumn colDevId;
private DevExpress.XtraGrid.Columns.GridColumn colFunc;
private DevExpress.XtraGrid.Columns.GridColumn colLen;
private DevExpress.XtraGrid.Columns.GridColumn colHex;
private DevExpress.XtraGrid.Columns.GridColumn colDesc;
private DevExpress.XtraGrid.Columns.GridColumn colCrc;
private DevExpress.XtraEditors.GroupControl grpDetail;
private DevExpress.XtraEditors.MemoEdit txtDetail;
}
}

View File

@@ -0,0 +1,425 @@
using System;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid;
using LFP_Manager.Function;
namespace LFP_Manager.Forms
{
public partial class fmxPacketLog : DevExpress.XtraEditors.XtraForm
{
private DataTable packetTable = null;
private int packetIndex = 0;
private int txCount = 0;
private int rxCount = 0;
private bool isCapturing = true;
private const int MAX_LOG_COUNT = 5000;
public fmxPacketLog()
{
InitializeComponent();
InitDataTable();
}
private void InitDataTable()
{
packetTable = new DataTable();
packetTable.Columns.Add("no", typeof(int));
packetTable.Columns.Add("time", typeof(string));
packetTable.Columns.Add("dir", typeof(string));
packetTable.Columns.Add("dev_id", typeof(string));
packetTable.Columns.Add("func", typeof(string));
packetTable.Columns.Add("len", typeof(int));
packetTable.Columns.Add("hex", typeof(string));
packetTable.Columns.Add("desc", typeof(string));
packetTable.Columns.Add("crc", typeof(string));
packetTable.Columns.Add("raw_bytes", typeof(object));
gcPacketLog.DataSource = packetTable;
ApplyFilter();
}
public void AddPacketLog(DateTime timestamp, bool isTx, byte[] data, string description = null)
{
if (!isCapturing || data == null || data.Length == 0) return;
if (string.IsNullOrEmpty(description))
{
description = GetAutoDescription(data, isTx);
}
if (this.InvokeRequired)
{
this.BeginInvoke(new Action(() => AddPacketLogRow(timestamp, isTx, data, description)));
}
else
{
AddPacketLogRow(timestamp, isTx, data, description);
}
}
private string GetAutoDescription(byte[] data, bool isTx)
{
if (data == null || data.Length < 2) return "-";
byte devId = data[0];
byte func = data[1];
if (isTx)
{
if (data.Length >= 6)
{
ushort regAddr = (ushort)((data[2] << 8) | data[3]);
ushort regCount = (ushort)((data[4] << 8) | data[5]);
switch (func)
{
case 0x01: return string.Format("Req: Read Coils (Addr:0x{0:X4}, Qty:{1})", regAddr, regCount);
case 0x02: return string.Format("Req: Read Discrete Inputs (Addr:0x{0:X4}, Qty:{1})", regAddr, regCount);
case 0x03: return string.Format("Req: Read Holding Regs (Addr:0x{0:X4}, Qty:{1})", regAddr, regCount);
case 0x04: return string.Format("Req: Read Input Regs (Addr:0x{0:X4}, Qty:{1})", regAddr, regCount);
case 0x05: return string.Format("Req: Write Single Coil (Addr:0x{0:X4}, Val:0x{1:X4})", regAddr, regCount);
case 0x06: return string.Format("Req: Write Single Reg (Addr:0x{0:X4}, Val:0x{1:X4})", regAddr, regCount);
case 0x10: return string.Format("Req: Write Multiple Regs (Addr:0x{0:X4}, Qty:{1})", regAddr, regCount);
}
}
return string.Format("Req: Func 0x{0:X2} (Slave 0x{1:X2})", func, devId);
}
else
{
if (func > 0x80)
{
byte err = data.Length > 2 ? data[2] : (byte)0;
return string.Format("Resp: Exception (0x{0:X2} - {1})", err, GetExceptionName(err));
}
switch (func)
{
case 0x01:
case 0x02:
case 0x03:
case 0x04:
int byteCount = data.Length > 2 ? data[2] : 0;
return string.Format("Resp: OK ({0} bytes data)", byteCount);
case 0x05:
case 0x06:
case 0x10:
return "Resp: Write Success";
default:
return string.Format("Resp: Func 0x{0:X2}", func);
}
}
}
private void AddPacketLogRow(DateTime timestamp, bool isTx, byte[] data, string description)
{
try
{
if (packetTable == null) return;
// Max rows management
if (packetTable.Rows.Count >= MAX_LOG_COUNT)
{
for (int i = 0; i < 500; i++)
{
if (packetTable.Rows.Count > 0)
packetTable.Rows.RemoveAt(0);
}
}
packetIndex++;
if (isTx) txCount++;
else rxCount++;
string dir = isTx ? "TX" : "RX";
string devId = data.Length > 0 ? string.Format("0x{0:X2}", data[0]) : "-";
string func = data.Length > 1 ? string.Format("0x{0:X2}", data[1]) : "-";
int len = data.Length;
StringBuilder sbHex = new StringBuilder(data.Length * 3);
for (int i = 0; i < data.Length; i++)
{
sbHex.AppendFormat("{0:X2} ", data[i]);
}
string hex = sbHex.ToString().TrimEnd();
// CRC Check
string crcResult = "OK";
if (data.Length >= 4)
{
byte[] calcCrc = csSerialCommFunction.GetCRC(data, data.Length - 2);
byte rxCrcH = data[data.Length - 2];
byte rxCrcL = data[data.Length - 1];
if (calcCrc[1] != rxCrcH || calcCrc[0] != rxCrcL)
{
crcResult = "ERR";
}
}
DataRow row = packetTable.NewRow();
row["no"] = packetIndex;
row["time"] = timestamp.ToString("HH:mm:ss.fff");
row["dir"] = dir;
row["dev_id"] = devId;
row["func"] = func;
row["len"] = len;
row["hex"] = hex;
row["desc"] = description;
row["crc"] = crcResult;
row["raw_bytes"] = data;
packetTable.Rows.Add(row);
lblStatus.Text = string.Format("Total: {0} | TX: {1} | RX: {2}", packetIndex, txCount, rxCount);
if (chkAutoScroll.Checked && gvPacketLog.RowCount > 0)
{
gvPacketLog.MoveLast();
}
}
catch
{
}
}
private void gvPacketLog_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
{
DataRow row = gvPacketLog.GetFocusedDataRow();
if (row == null)
{
txtDetail.Text = string.Empty;
return;
}
byte[] rawBytes = row["raw_bytes"] as byte[];
string dir = row["dir"].ToString();
string desc = row["desc"].ToString();
string time = row["time"].ToString();
txtDetail.Text = AnalyzePacket(rawBytes, dir, desc, time);
}
private string AnalyzePacket(byte[] data, string dir, string desc, string time)
{
if (data == null || data.Length == 0) return "No Data";
StringBuilder sb = new StringBuilder();
sb.AppendLine("================================================================================");
sb.AppendLine(string.Format("[{0}] {1} (Length: {2} bytes) - {3}", dir, desc, data.Length, time));
sb.AppendLine("================================================================================");
// 1. Raw HEX Dump formatted
sb.AppendLine("[RAW HEX DUMP]");
for (int i = 0; i < data.Length; i += 16)
{
sb.AppendFormat("{0:X4}: ", i);
int count = Math.Min(16, data.Length - i);
for (int j = 0; j < count; j++)
{
sb.AppendFormat("{0:X2} ", data[i + j]);
}
sb.AppendLine();
}
sb.AppendLine();
// 2. Modbus Protocol Interpretation
sb.AppendLine("[MODBUS FRAME INTERPRETATION]");
if (data.Length >= 2)
{
byte devId = data[0];
byte funcCode = data[1];
sb.AppendLine(string.Format(" - Device (Slave) Address : 0x{0:X2} ({0})", devId));
sb.AppendLine(string.Format(" - Function Code : 0x{0:X2} ({1})", funcCode, GetFunctionCodeName(funcCode)));
if (dir == "TX")
{
if (data.Length >= 6)
{
ushort regAddr = (ushort)((data[2] << 8) | data[3]);
ushort regCount = (ushort)((data[4] << 8) | data[5]);
sb.AppendLine(string.Format(" - Target Register Address: 0x{0:X4} ({0})", regAddr));
sb.AppendLine(string.Format(" - Register Count / Value : 0x{0:X4} ({0})", regCount));
}
}
else // RX
{
if (funcCode == 0x03 && data.Length >= 3)
{
byte byteCount = data[2];
sb.AppendLine(string.Format(" - Data Byte Count : {0} bytes ({1} registers)", byteCount, byteCount / 2));
int regIndex = 0;
for (int p = 3; p + 1 < data.Length - 2; p += 2)
{
ushort val = (ushort)((data[p] << 8) | data[p + 1]);
sb.AppendLine(string.Format(" [Reg +{0:D2}] Offset 0x{1:X2} : 0x{2:X4} ({3})", regIndex++, p - 3, val, (short)val));
}
}
else if (funcCode > 0x80)
{
byte errCode = data.Length > 2 ? data[2] : (byte)0;
sb.AppendLine(string.Format(" - Modbus Exception Code : 0x{0:X2} ({1})", errCode, GetExceptionName(errCode)));
}
}
// CRC Check
if (data.Length >= 4)
{
byte[] calcCrc = csSerialCommFunction.GetCRC(data, data.Length - 2);
byte rxCrcH = data[data.Length - 2];
byte rxCrcL = data[data.Length - 1];
bool crcOk = (calcCrc[1] == rxCrcH && calcCrc[0] == rxCrcL);
sb.AppendLine(string.Format(" - CRC16 Checksum : [H:0x{0:X2}, L:0x{1:X2}] (Calc: 0x{2:X2}{3:X2}) -> {4}",
rxCrcH, rxCrcL, calcCrc[1], calcCrc[0], crcOk ? "VALID (OK)" : "INVALID (MISMATCH)"));
}
}
return sb.ToString();
}
private string GetFunctionCodeName(byte func)
{
switch (func)
{
case 0x01: return "Read Coil Status (0x01)";
case 0x02: return "Read Input Status (0x02)";
case 0x03: return "Read Holding Registers (0x03)";
case 0x04: return "Read Input Registers (0x04)";
case 0x05: return "Force Single Coil (0x05)";
case 0x06: return "Preset Single Register (0x06)";
case 0x10: return "Preset Multiple Registers (0x10)";
default:
if (func > 0x80) return string.Format("Exception Response (0x{0:X2})", func);
return string.Format("Custom / Unknown (0x{0:X2})", func);
}
}
private string GetExceptionName(byte err)
{
switch (err)
{
case 0x01: return "Illegal Function";
case 0x02: return "Illegal Data Address";
case 0x03: return "Illegal Data Value";
case 0x04: return "Slave Device Failure";
case 0x05: return "Acknowledge";
case 0x06: return "Slave Device Busy";
default: return "Unknown Exception";
}
}
private void gvPacketLog_RowStyle(object sender, RowStyleEventArgs e)
{
if (e.RowHandle < 0) return;
DataRow row = gvPacketLog.GetDataRow(e.RowHandle);
if (row == null) return;
string dir = row["dir"].ToString();
string crc = row["crc"].ToString();
if (crc == "ERR")
{
e.Appearance.ForeColor = Color.Red;
e.Appearance.Font = new Font(e.Appearance.Font, FontStyle.Bold);
}
else if (dir == "TX")
{
e.Appearance.ForeColor = Color.DarkBlue;
}
else if (dir == "RX")
{
e.Appearance.ForeColor = Color.DarkGreen;
}
}
private void btnCapture_Click(object sender, EventArgs e)
{
isCapturing = !isCapturing;
btnCapture.Text = isCapturing ? "Pause" : "Resume";
btnCapture.Appearance.ForeColor = isCapturing ? Color.Black : Color.DarkRed;
}
private void btnClear_Click(object sender, EventArgs e)
{
packetTable?.Rows.Clear();
packetIndex = 0;
txCount = 0;
rxCount = 0;
lblStatus.Text = "Total: 0 | TX: 0 | RX: 0";
txtDetail.Text = string.Empty;
}
private void cmbFilter_SelectedIndexChanged(object sender, EventArgs e)
{
ApplyFilter();
}
private void ApplyFilter()
{
if (packetTable == null) return;
string selected = cmbFilter.Text;
DataView dv = packetTable.DefaultView;
if (selected == "TX Only")
{
dv.RowFilter = "dir = 'TX'";
}
else if (selected == "RX Only")
{
dv.RowFilter = "dir = 'RX'";
}
else if (selected == "Error Only")
{
dv.RowFilter = "crc = 'ERR'";
}
else
{
dv.RowFilter = string.Empty;
}
}
private void btnExport_Click(object sender, EventArgs e)
{
if (packetTable == null || packetTable.Rows.Count == 0)
{
MessageBox.Show("No packet logs to export.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
SaveFileDialog sDialog = new SaveFileDialog();
sDialog.Title = "Export Packet Logs";
sDialog.DefaultExt = "xls";
sDialog.Filter = "Excel files (*.xls)|*.xls|All files (*.*)|*.*";
if (sDialog.ShowDialog() == DialogResult.OK)
{
try
{
DataTable exportTable = packetTable.DefaultView.ToTable(false, "no", "time", "dir", "dev_id", "func", "len", "hex", "desc", "crc");
csExcelExport.ExportToExcelExt(exportTable, sDialog.FileName);
MessageBox.Show("Complete Exporting Packet Log File.", "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void fmxPacketLog_FormClosing(object sender, FormClosingEventArgs e)
{
// Just hide on close so it can be re-opened quickly
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
this.Hide();
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
namespace LFP_Manager.Forms
namespace LFP_Manager.Forms
{
partial class fmxParamConfig
{
@@ -698,7 +698,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(925, 777);
this.Controls.Add(this.layoutControl1);
this.IconOptions.Icon = ((System.Drawing.Icon)(resources.GetObject("fmxParamConfig.IconOptions.Icon")));
this.IconOptions.Image = global::LFP_Manager.Properties.Resources.Delta_Logo_1;
this.Name = "fmxParamConfig";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Parameter Config";

View File

@@ -1,6 +1,7 @@
using System;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.IO;
using System.Data.OleDb;
@@ -70,7 +71,7 @@ namespace LFP_Manager.Function
List<String> rowValues = new List<string>();
foreach (DataColumn column in dataTable.Columns)
{
rowValues.Add((row[column] != null && row[column] != DBNull.Value) ? row[column].ToString() : String.Empty);
rowValues.Add((row[column] != null && row[column] != DBNull.Value) ? Convert.ToString(row[column], CultureInfo.InvariantCulture) : String.Empty);
}
//command.CommandText = $"INSERT INTO [{tableName}]({String.Join(",", columnNames.Select(c => $"[{c}]"))}) VALUES ({String.Join(",", rowValues.Select(r => $"'{r}'").ToArray())});";
string a = String.Join(",", columnNames.Select(c => String.Format("[{0}]", c)));
@@ -156,7 +157,7 @@ namespace LFP_Manager.Function
List<String> rowValues = new List<string>();
foreach (DataColumn column in dataTable.Columns)
{
rowValues.Add((row[column] != null && row[column] != DBNull.Value) ? row[column].ToString().Trim('\0') : String.Empty);
rowValues.Add((row[column] != null && row[column] != DBNull.Value) ? Convert.ToString(row[column], CultureInfo.InvariantCulture).Trim('\0') : String.Empty);
}
//command.CommandText = $"INSERT INTO [{tableName}]({String.Join(",", columnNames.Select(c => $"[{c}]"))}) VALUES ({String.Join(",", rowValues.Select(r => $"'{r}'").ToArray())});";
string a = String.Join(",", columnNames.Select(c => String.Format("[{0}]", c)));

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -186,7 +186,8 @@ namespace LFP_Manager.Function
case 32: // Temperature #2
case 33: // Temperature #3
case 34: // Temperature #4
csUtils.MakeMaxAvgMinCellVoltage(ref aSystemData, 4);
aSystemData.ValueData.CellTemperature[index - 31] = (short)(Convert.ToDouble(sdata) * 10);
csUtils.MakeMaxAvgMinTemperature(ref aSystemData, 4);
break;
case 37: aSystemData.cellQty = (short)(Convert.ToDouble(sdata) * 1); break; // Cell Number

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\EntityFramework.6.5.1\build\EntityFramework.props" Condition="Exists('..\packages\EntityFramework.6.5.1\build\EntityFramework.props')" />
<Import Project="..\packages\SQLite.3.13.0\build\net45\SQLite.props" Condition="Exists('..\packages\SQLite.3.13.0\build\net45\SQLite.props')" />
@@ -47,7 +47,7 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>AMO_LOGO.ico</ApplicationIcon>
<ApplicationIcon>Delta_Logo_2.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Accessibility" />
@@ -471,6 +471,12 @@
<Compile Include="Forms\fmxCommConfig.Designer.cs">
<DependentUpon>fmxCommConfig.cs</DependentUpon>
</Compile>
<Compile Include="Forms\fmxPacketLog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\fmxPacketLog.Designer.cs">
<DependentUpon>fmxPacketLog.cs</DependentUpon>
</Compile>
<Compile Include="Forms\fmxMain.cs">
<SubType>Form</SubType>
</Compile>
@@ -554,6 +560,9 @@
<EmbeddedResource Include="Forms\fmxCommConfig.resx">
<DependentUpon>fmxCommConfig.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\fmxPacketLog.resx">
<DependentUpon>fmxPacketLog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\fmxFwUpdate.resx">
<DependentUpon>fmxFwUpdate.cs</DependentUpon>
</EmbeddedResource>
@@ -607,12 +616,15 @@
</ItemGroup>
<ItemGroup>
<None Include="Resources\AMO_LOGO.ico" />
<None Include="Resources\Delta_Logo_1.ico" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Content Include="AMO_LOGO.ico" />
<Content Include="Delta_Logo_1.ico" />
<Content Include="DB Schema\DB_SCHEMA_TABLE.sql" />
<Content Include="DB Schema\LOG_DB_SCHEMA_TABLE.sql" />
<Content Include="Delta_Logo_2.ico" />
<None Include="Resources\Delta_Logo_Small_250522.png" />
<None Include="Resources\AMO_LOGO1.ico" />
</ItemGroup>

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
@@ -15,9 +15,62 @@ namespace LFP_Manager
[STAThread]
static void Main()
{
EnsureDeltaLogoIcon();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new fmxMain());
}
public static System.Drawing.Bitmap DeltaLogoBitmap { get; private set; }
public static System.Drawing.Icon DeltaLogoIcon { get; private set; }
private static void EnsureDeltaLogoIcon()
{
try
{
string mediaPath = @"C:\Users\B1801003.AMOTECH\.gemini\antigravity-ide\brain\cbd44053-f528-42b6-844e-ed1cb6a3234d\media__1785212352524.png";
string projectRootIco = @"d:\Project\GUI\Delta (Brazil)\Common\LFP_Manager_DELTA_(V1.0.1.7)_AG\LFP_Manager\Delta_Logo_1.ico";
string projectResIco = @"d:\Project\GUI\Delta (Brazil)\Common\LFP_Manager_DELTA_(V1.0.1.7)_AG\LFP_Manager\Resources\Delta_Logo_1.ico";
if (System.IO.File.Exists(mediaPath))
{
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(mediaPath);
DeltaLogoBitmap = (System.Drawing.Bitmap)bmp.Clone();
IntPtr hIcon = bmp.GetHicon();
System.Drawing.Icon icon = System.Drawing.Icon.FromHandle(hIcon);
DeltaLogoIcon = (System.Drawing.Icon)icon.Clone();
try
{
using (System.IO.FileStream fs = new System.IO.FileStream(projectRootIco, System.IO.FileMode.Create))
{
icon.Save(fs);
}
}
catch { }
try
{
using (System.IO.FileStream fs = new System.IO.FileStream(projectResIco, System.IO.FileMode.Create))
{
icon.Save(fs);
}
}
catch { }
try
{
string exeDirIco = System.IO.Path.Combine(Application.StartupPath, "Delta_Logo_1.ico");
using (System.IO.FileStream fs = new System.IO.FileStream(exeDirIco, System.IO.FileMode.Create))
{
icon.Save(fs);
}
}
catch { }
}
}
catch { }
}
}
}

View File

@@ -1,4 +1,4 @@
using System.Reflection;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1.8")]
[assembly: AssemblyFileVersion("1.0.1.8")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]

View File

@@ -80,6 +80,26 @@ namespace LFP_Manager.Properties {
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap Delta_Logo_1 {
get {
object obj = ResourceManager.GetObject("Delta_Logo_1", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// (아이콘)과(와) 유사한 System.Drawing.Icon 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Icon Delta_Logo_2 {
get {
object obj = ResourceManager.GetObject("Delta_Logo_2", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
@@ -127,4 +127,10 @@
<data name="Delta_Logo_Small_250522" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Delta_Logo_Small_250522.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Delta_Logo_1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Delta_Logo_1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Delta_Logo_2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Delta_Logo_2.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -1,4 +1,4 @@
using DevExpress.XtraGauges.Core.Model;
using DevExpress.XtraGauges.Core.Model;
using LFP_Manager.DataStructure;
using LFP_Manager.Function;
using LFP_Manager.Utils;
@@ -39,6 +39,7 @@ namespace LFP_Manager.Threads
public event UartDataUpdateRS485 OnUpdate = null;
public event UartDataRecvRS485 OnDataRecv = null;
public event UartDataPrintRS485 OnPrint = null;
public event UartDataPacketRS485 OnPacketLog = null;
#endregion
@@ -467,6 +468,7 @@ namespace LFP_Manager.Threads
{
sPort.Write(txData, 0, txData.Length);
SafeRaiseOnPrint(csLog.trx_data_print(txData, txData.Length, 0));
OnPacketLog?.Invoke(DateTime.Now, true, txData, null);
}
catch (Exception ex)
{
@@ -514,6 +516,12 @@ namespace LFP_Manager.Threads
break;
case 1: // Packet OK, no error
SafeRaiseOnPrint(csLog.trx_data_print(ReadBuf, rPosition, 1));
if (OnPacketLog != null)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, null);
}
TimeOutCount[ModuleID - 1] = 0;
@@ -530,6 +538,12 @@ namespace LFP_Manager.Threads
goto StartSend;
case 2: // Fw Update Packet OK
SafeRaiseOnPrint(csLog.trx_data_print(ReadBuf, rPosition, 1));
if (OnPacketLog != null)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, "FW Update Response");
}
TimeOutCount[ModuleID - 1] = 0;
rFlag = false;
@@ -541,6 +555,12 @@ namespace LFP_Manager.Threads
}
goto StartSend;
case -1: // Packet error
if (OnPacketLog != null && rPosition > 0)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, "Packet Error / CRC Mismatch");
}
RecvPacketInit();
Thread.Sleep(100);
goto StartSend;

View File

@@ -1,4 +1,4 @@
using LFP_Manager.DataStructure;
using LFP_Manager.DataStructure;
using LFP_Manager.Function;
using SnmpSharpNet;
using System;
@@ -489,38 +489,48 @@ namespace LFP_Manager.Threads
j = 0;
for (i = 0; i < tSize; i++)
{
short tempVal = aSystemData.ValueData.CellTemperature[i];
if (tempVal == 0) continue; // 미연결 및 초기 0도 제외
if (j == 0)
{
max.value = aSystemData.ValueData.CellTemperature[i];
max.value = tempVal;
max.num = i;
min.value = aSystemData.ValueData.CellTemperature[i];
min.value = tempVal;
min.num = i;
}
if (max.value < aSystemData.ValueData.CellTemperature[i])
if (max.value < tempVal)
{
max.value = aSystemData.ValueData.CellTemperature[i];
max.value = tempVal;
max.num = i;
}
if (min.value > aSystemData.ValueData.CellTemperature[i])
if (min.value > tempVal)
{
min.value = aSystemData.ValueData.CellTemperature[i];
min.value = tempVal;
min.num = i;
}
sum += aSystemData.ValueData.CellTemperature[i];
sum += tempVal;
j++;
}
if (j == 0)
{ aSystemData.AvgData.avgTemp = 0; }
{
aSystemData.AvgData.avgTemp = 0;
aSystemData.AvgData.maxTemp = 0;
aSystemData.AvgData.maxTempNum = 0;
aSystemData.AvgData.minTemp = 0;
aSystemData.AvgData.minTempNum = 0;
}
else
{ aSystemData.AvgData.avgTemp = (short)(sum / j); }
aSystemData.AvgData.maxTemp = max.value;
aSystemData.AvgData.maxTempNum = max.num;
aSystemData.AvgData.minTemp = min.value;
aSystemData.AvgData.minTempNum = min.num;
{
aSystemData.AvgData.avgTemp = (short)(sum / j);
aSystemData.AvgData.maxTemp = max.value;
aSystemData.AvgData.maxTempNum = max.num;
aSystemData.AvgData.minTemp = min.value;
aSystemData.AvgData.minTempNum = min.num;
}
}
}
}

View File

@@ -1,4 +1,4 @@
using LFP_Manager.DataStructure;
using LFP_Manager.DataStructure;
using LFP_Manager.Function;
using LFP_Manager.Utils;
using SnmpSharpNet;
@@ -516,34 +516,55 @@ namespace LFP_Manager.Threads
return;
var temperatures = systemData.ValueData.CellTemperature;
var validCount = Math.Min((int)tempSize, temperatures.Length);
var limitCount = Math.Min((int)tempSize, temperatures.Length);
var sum = 0;
int validCount = 0;
short maxVal = 0, minVal = 0;
int maxIdx = 0, minIdx = 0;
for (int i = 0; i < limitCount; i++)
{
var temp = temperatures[i];
if (temp == 0) continue; // 미연결 및 초기 0도 제외
if (validCount == 0)
{
maxVal = minVal = temp;
maxIdx = minIdx = i;
}
sum += temp;
validCount++;
if (temp > maxVal)
{
maxVal = temp;
maxIdx = i;
}
if (temp < minVal)
{
minVal = temp;
minIdx = i;
}
}
if (validCount == 0)
{
systemData.AvgData.avgTemp = 0;
return;
systemData.AvgData.maxTemp = 0;
systemData.AvgData.maxTempNum = 0;
systemData.AvgData.minTemp = 0;
systemData.AvgData.minTempNum = 0;
}
var sum = 0;
var max = new { value = temperatures[0], index = 0 };
var min = new { value = temperatures[0], index = 0 };
for (int i = 0; i < validCount; i++)
else
{
var temp = temperatures[i];
sum += temp;
if (temp > max.value)
max = new { value = temp, index = i };
if (temp < min.value)
min = new { value = temp, index = i };
systemData.AvgData.avgTemp = (short)(sum / validCount);
systemData.AvgData.maxTemp = maxVal;
systemData.AvgData.maxTempNum = maxIdx;
systemData.AvgData.minTemp = minVal;
systemData.AvgData.minTempNum = minIdx;
}
systemData.AvgData.avgTemp = (short)(sum / validCount);
systemData.AvgData.maxTemp = max.value;
systemData.AvgData.maxTempNum = max.index;
systemData.AvgData.minTemp = min.value;
systemData.AvgData.minTempNum = min.index;
}
/// <summary>

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.IO.Ports;
@@ -44,6 +44,7 @@ namespace LFP_Manager.Threads
public event UartDataUpdate OnUpdate = null;
public event UartDataRecv OnDataRecv = null;
public event UartDataPrint OnPrint = null;
public event UartDataPacket OnPacketLog = null;
#endregion
@@ -632,6 +633,7 @@ namespace LFP_Manager.Threads
FlushBuff();
sPort.Write(txData, 0, txData.Length);
OnPrint?.Invoke(this, csLog.trx_data_print(txData, txData.Length, 0));
OnPacketLog?.Invoke(DateTime.Now, true, txData, null);
}
if (rFlag == true)
@@ -669,6 +671,12 @@ namespace LFP_Manager.Threads
break;
case 1: // Packet OK, no error
OnPrint?.Invoke(this, csLog.trx_data_print(ReadBuf, rPosition, 1));
if (OnPacketLog != null)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, null);
}
TimeOutCount = 0;
@@ -691,8 +699,8 @@ namespace LFP_Manager.Threads
WriteRegAddr = 0;
if (OnDataRecv != null)
{
byte[] adata = new byte[rPosition + 1];
for (int j = 0; j < adata.Length; j++) { adata[j] = ReadBuf[j]; }
byte[] adata = new byte[rPosition];
Array.Copy(ReadBuf, 0, adata, 0, rPosition);
OnDataRecv(adata);
}
}
@@ -701,20 +709,29 @@ namespace LFP_Manager.Threads
goto StartSend;
case 2: // Fw Update Packet OK
OnPrint?.Invoke(this, csLog.trx_data_print(ReadBuf, rPosition, 1));
if (OnPacketLog != null)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, "FW Update Response");
}
TimeOutCount = 0;
rFlag = false;
if (OnDataRecv != null)
{
byte[] adata = new byte[rPosition + 1];
for (int j = 0; j < adata.Length; j++)
{
adata[j] = ReadBuf[j];
}
byte[] adata = new byte[rPosition];
Array.Copy(ReadBuf, 0, adata, 0, rPosition);
OnDataRecv(adata);
}
goto StartSend;
case -1: // Packet error
if (OnPacketLog != null && rPosition > 0)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, "Packet Error / CRC Mismatch");
}
RecvPacketInit();
Thread.Sleep(100);
goto StartSend;

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.IO.Ports;
@@ -15,6 +15,7 @@ namespace LFP_Manager.Threads
public delegate void UartDataUpdateRS485(object sender, ref DeviceSystemData[] aSystemData);
public delegate void UartDataRecvRS485(byte[] data);
public delegate void UartDataPrintRS485(object sender, string msg);
public delegate void UartDataPacketRS485(DateTime timestamp, bool isTx, byte[] data, string description);
#endregion
class CsUartThreadDelta
@@ -50,6 +51,7 @@ namespace LFP_Manager.Threads
public event UartDataUpdateRS485 OnUpdate = null;
public event UartDataRecvRS485 OnDataRecv = null;
public event UartDataPrintRS485 OnPrint = null;
public event UartDataPacketRS485 OnPacketLog = null;
#endregion
@@ -451,6 +453,7 @@ namespace LFP_Manager.Threads
{
sPort.Write(txData, 0, txData.Length);
OnPrint?.Invoke(this, csLog.trx_data_print(txData, txData.Length, 0));
OnPacketLog?.Invoke(DateTime.Now, true, txData, null);
}
if (rFlag == true)
@@ -491,6 +494,12 @@ namespace LFP_Manager.Threads
break;
case 1: // Packet OK, no error
OnPrint?.Invoke(this, csLog.trx_data_print(ReadBuf, rPosition, 1));
if (OnPacketLog != null)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, null);
}
TimeOutCount[ModuleID - 1] = 0;
@@ -507,20 +516,29 @@ namespace LFP_Manager.Threads
goto StartSend;
case 2: // Fw Update Packet OK
OnPrint?.Invoke(this, csLog.trx_data_print(ReadBuf, rPosition, 1));
if (OnPacketLog != null)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, "FW Update Response");
}
TimeOutCount[ModuleID - 1] = 0;
rFlag = false;
if (OnDataRecv != null)
{
byte[] adata = new byte[rPosition + 1];
for (int j = 0; j < adata.Length; j++)
{
adata[j] = ReadBuf[j];
}
byte[] adata = new byte[rPosition];
Array.Copy(ReadBuf, 0, adata, 0, rPosition);
OnDataRecv(adata);
}
goto StartSend;
case -1: // Packet error
if (OnPacketLog != null && rPosition > 0)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, "Packet Error / CRC Mismatch");
}
RecvPacketInit();
Thread.Sleep(100);
goto StartSend;

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.IO.Ports;
@@ -15,6 +15,7 @@ namespace LFP_Manager.Threads
public delegate void UartDataUpdate(object sender, ref DeviceSystemData aSystemData);
public delegate void UartDataRecv(byte[] data);
public delegate void UartDataPrint(object sender, string msg);
public delegate void UartDataPacket(DateTime timestamp, bool isTx, byte[] data, string description);
#endregion
class csUartThread
@@ -50,6 +51,7 @@ namespace LFP_Manager.Threads
public event UartDataUpdate OnUpdate = null;
public event UartDataRecv OnDataRecv = null;
public event UartDataPrint OnPrint = null;
public event UartDataPacket OnPacketLog = null;
#endregion
@@ -643,6 +645,7 @@ namespace LFP_Manager.Threads
FlushBuff();
sPort.Write(txData, 0, txData.Length);
OnPrint?.Invoke(this, csLog.trx_data_print(txData, txData.Length, 0));
OnPacketLog?.Invoke(DateTime.Now, true, txData, null);
}
if (rFlag == true)
@@ -680,6 +683,12 @@ namespace LFP_Manager.Threads
break;
case 1: // Packet OK, no error
OnPrint?.Invoke(this, csLog.trx_data_print(ReadBuf, rPosition, 1));
if (OnPacketLog != null)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, null);
}
TimeOutCount = 0;
@@ -702,8 +711,8 @@ namespace LFP_Manager.Threads
WriteRegAddr = 0;
if (OnDataRecv != null)
{
byte[] adata = new byte[rPosition + 1];
for (int j = 0; j < adata.Length; j++) { adata[j] = ReadBuf[j]; }
byte[] adata = new byte[rPosition];
Array.Copy(ReadBuf, 0, adata, 0, rPosition);
OnDataRecv(adata);
}
}
@@ -712,20 +721,29 @@ namespace LFP_Manager.Threads
goto StartSend;
case 2: // Fw Update Packet OK
OnPrint?.Invoke(this, csLog.trx_data_print(ReadBuf, rPosition, 1));
if (OnPacketLog != null)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, "FW Update Response");
}
TimeOutCount = 0;
rFlag = false;
if (OnDataRecv != null)
{
byte[] adata = new byte[rPosition + 1];
for (int j = 0; j < adata.Length; j++)
{
adata[j] = ReadBuf[j];
}
byte[] adata = new byte[rPosition];
Array.Copy(ReadBuf, 0, adata, 0, rPosition);
OnDataRecv(adata);
}
goto StartSend;
case -1: // Packet error
if (OnPacketLog != null && rPosition > 0)
{
byte[] pData = new byte[rPosition];
Array.Copy(ReadBuf, 0, pData, 0, rPosition);
OnPacketLog(DateTime.Now, false, pData, "Packet Error / CRC Mismatch");
}
RecvPacketInit();
Thread.Sleep(100);
goto StartSend;

View File

@@ -1,8 +1,9 @@
using LFP_Manager.DataStructure;
using LFP_Manager.DataStructure;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
@@ -619,11 +620,11 @@ namespace LFP_Manager.Utils
new SQLiteParameter("alarm_status", systemData.StatusData.batteryStatus),
new SQLiteParameter("warning", systemData.StatusData.warning),
new SQLiteParameter("fault", systemData.StatusData.protection),
new SQLiteParameter("module_voltage", (systemData.ValueData.voltageOfPack / 10.0).ToString()),
new SQLiteParameter("module_current", (systemData.ValueData.current / 10.0).ToString()),
new SQLiteParameter("module_soc", (systemData.ValueData.rSOC / 10.0).ToString()),
new SQLiteParameter("module_soh", (systemData.ValueData.stateOfHealth / 10.0).ToString()),
new SQLiteParameter("module_cyclecount", systemData.ValueData.cycleCount.ToString())
new SQLiteParameter("module_voltage", (systemData.ValueData.voltageOfPack / 10.0).ToString(CultureInfo.InvariantCulture)),
new SQLiteParameter("module_current", (systemData.ValueData.current / 10.0).ToString(CultureInfo.InvariantCulture)),
new SQLiteParameter("module_soc", (systemData.ValueData.rSOC / 10.0).ToString(CultureInfo.InvariantCulture)),
new SQLiteParameter("module_soh", (systemData.ValueData.stateOfHealth / 10.0).ToString(CultureInfo.InvariantCulture)),
new SQLiteParameter("module_cyclecount", systemData.ValueData.cycleCount.ToString(CultureInfo.InvariantCulture))
};
// Add cell voltage parameters
@@ -631,7 +632,7 @@ namespace LFP_Manager.Utils
{
parameters.Add(new SQLiteParameter(
string.Format("cell_voltage_{0:00}", i + 1),
(systemData.ValueData.CellVoltage[i] / (float)cvUnit).ToString()));
(systemData.ValueData.CellVoltage[i] / (float)cvUnit).ToString(CultureInfo.InvariantCulture)));
}
// Add temperature parameters
@@ -639,12 +640,12 @@ namespace LFP_Manager.Utils
{
parameters.Add(new SQLiteParameter(
string.Format("temperature_{0:00}", i + 1),
(systemData.ValueData.CellTemperature[i] / 10.0).ToString()));
(systemData.ValueData.CellTemperature[i] / 10.0).ToString(CultureInfo.InvariantCulture)));
}
parameters.Add(new SQLiteParameter("ext1_temp", (systemData.ValueData.Ext1Temperature / 10.0).ToString()));
parameters.Add(new SQLiteParameter("ext2_temp", (systemData.ValueData.Ext2Temperature / 10.0).ToString()));
parameters.Add(new SQLiteParameter("chg_option", systemData.CalibrationData.ChaMode.Mode.ToString()));
parameters.Add(new SQLiteParameter("ext1_temp", (systemData.ValueData.Ext1Temperature / 10.0).ToString(CultureInfo.InvariantCulture)));
parameters.Add(new SQLiteParameter("ext2_temp", (systemData.ValueData.Ext2Temperature / 10.0).ToString(CultureInfo.InvariantCulture)));
parameters.Add(new SQLiteParameter("chg_option", systemData.CalibrationData.ChaMode.Mode.ToString(CultureInfo.InvariantCulture)));
return parameters.ToArray();
}
@@ -1071,6 +1072,7 @@ namespace LFP_Manager.Utils
{
connection.Open();
BeginTran(connection);
csDbUtils.RepairCommaDecimalsIfNeeded(connection);
// Insert data
using (SQLiteCommand command = connection.CreateCommand())
@@ -1303,6 +1305,7 @@ namespace LFP_Manager.Utils
{
connection.Open();
BeginTran(connection);
csDbUtils.RepairCommaDecimalsIfNeeded(connection);
// Insert data
using (SQLiteCommand command = connection.CreateCommand())

View File

@@ -1,7 +1,9 @@
using LFP_Manager.DataStructure;
using LFP_Manager.DataStructure;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Globalization;
using System.IO;
using System.Text;
using System.Windows.Forms;
@@ -564,24 +566,24 @@ namespace LFP_Manager.Utils
p[j++].Value = aSystemData.StatusData.batteryStatus; // 7 alarm_status
p[j++].Value = aSystemData.StatusData.warning; // 8 warning
p[j++].Value = aSystemData.StatusData.protection; // 9 fault
p[j++].Value = ((float)aSystemData.ValueData.voltageOfPack / 10).ToString(); // 10 module_voltage
p[j++].Value = ((float)aSystemData.ValueData.current / 10).ToString(); // 11 module_current
p[j++].Value = ((float)aSystemData.ValueData.rSOC / 10).ToString(); // 12 module_soc
p[j++].Value = ((float)aSystemData.ValueData.stateOfHealth / 10).ToString(); // 13 module_soh
p[j++].Value = ((float)aSystemData.ValueData.cycleCount / 1).ToString(); // 14 module_soh
p[j++].Value = ((float)aSystemData.ValueData.voltageOfPack / 10).ToString(CultureInfo.InvariantCulture); // 10 module_voltage
p[j++].Value = ((float)aSystemData.ValueData.current / 10).ToString(CultureInfo.InvariantCulture); // 11 module_current
p[j++].Value = ((float)aSystemData.ValueData.rSOC / 10).ToString(CultureInfo.InvariantCulture); // 12 module_soc
p[j++].Value = ((float)aSystemData.ValueData.stateOfHealth / 10).ToString(CultureInfo.InvariantCulture); // 13 module_soh
p[j++].Value = ((float)aSystemData.ValueData.cycleCount / 1).ToString(CultureInfo.InvariantCulture); // 14 module_soh
for (int i = 0; i < aSystemData.cellQty; i++)
{
p[j++].Value = ((float)aSystemData.ValueData.CellVoltage[i] / cvUnit).ToString(); // 15 cell_voltage_01
p[j++].Value = ((float)aSystemData.ValueData.CellVoltage[i] / cvUnit).ToString(CultureInfo.InvariantCulture); // 15 cell_voltage_01
}
for (int i = 0; i < aSystemData.tempQty; i++)
{
p[j++].Value = ((float)aSystemData.ValueData.CellTemperature[i] / 10).ToString(); // 30 temperature_01
p[j++].Value = ((float)aSystemData.ValueData.CellTemperature[i] / 10).ToString(CultureInfo.InvariantCulture); // 30 temperature_01
}
p[j++].Value = ((float)aSystemData.ValueData.Ext1Temperature / 10).ToString(); // 34 temperature_ext1 - FET Temp
p[j++].Value = ((float)aSystemData.ValueData.Ext2Temperature / 10).ToString(); // 35 temperature_ext2 - Lmt Temp
p[j++].Value = ((float)aSystemData.ValueData.Ext1Temperature / 10).ToString(CultureInfo.InvariantCulture); // 34 temperature_ext1 - FET Temp
p[j++].Value = ((float)aSystemData.ValueData.Ext2Temperature / 10).ToString(CultureInfo.InvariantCulture); // 35 temperature_ext2 - Lmt Temp
p[j++].Value = aSystemData.CalibrationData.ChaMode.Mode.ToString(); // 36 chg_option
p[j++].Value = aSystemData.CalibrationData.ChaMode.Mode.ToString(CultureInfo.InvariantCulture); // 36 chg_option
command.ExecuteNonQuery();
@@ -1011,6 +1013,57 @@ namespace LFP_Manager.Utils
#region SELECT QUARY
public static void RepairCommaDecimalsIfNeeded(SQLiteConnection connection)
{
try
{
bool hasCommaText = false;
using (SQLiteCommand checkCmd = connection.CreateCommand())
{
checkCmd.CommandText = "SELECT 1 FROM TModuleValue WHERE typeof(module_voltage) = 'text' OR typeof(cell_voltage_01) = 'text' LIMIT 1";
object res = checkCmd.ExecuteScalar();
hasCommaText = (res != null && res != DBNull.Value);
}
if (!hasCommaText) return;
List<string> numCols = new List<string>();
using (SQLiteCommand pragmaCmd = connection.CreateCommand())
{
pragmaCmd.CommandText = "PRAGMA table_info(TModuleValue);";
using (SQLiteDataReader reader = pragmaCmd.ExecuteReader())
{
while (reader.Read())
{
string colName = Convert.ToString(reader["name"]);
string colType = Convert.ToString(reader["type"]).ToUpperInvariant();
if (colType.Contains("NUMERIC") || colType.Contains("REAL") || colType.Contains("DOUBLE") || colType.Contains("FLOAT") || colType.Contains("DECIMAL"))
{
numCols.Add(colName);
}
}
}
}
if (numCols.Count == 0) return;
List<string> setClauses = new List<string>(numCols.Count);
foreach (string col in numCols)
{
setClauses.Add(string.Format("{0} = CASE WHEN typeof({0}) = 'text' THEN CAST(REPLACE({0}, ',', '.') AS NUMERIC) ELSE {0} END", col));
}
using (SQLiteCommand updateCmd = connection.CreateCommand())
{
updateCmd.CommandText = "UPDATE TModuleValue SET " + string.Join(", ", setClauses.ToArray());
updateCmd.ExecuteNonQuery();
}
}
catch
{
}
}
public static int DbQuaryExcuteToDataTable(string dbFileName, string Quary, ref DataTable rDT)
{
int result = 0;
@@ -1023,6 +1076,7 @@ namespace LFP_Manager.Utils
{
connection.Open();
BeginTran(connection);
RepairCommaDecimalsIfNeeded(connection);
// Insert data
using (SQLiteCommand command = connection.CreateCommand())
@@ -1255,6 +1309,7 @@ namespace LFP_Manager.Utils
{
connection.Open();
BeginTran(connection);
RepairCommaDecimalsIfNeeded(connection);
// Insert data
using (SQLiteCommand command = connection.CreateCommand())

View File

@@ -1,5 +1,6 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.IO;
@@ -399,10 +400,10 @@ namespace LFP_Manager.Utils
, 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
, String.Format(CultureInfo.InvariantCulture, "{0:#0.0}", Convert.ToDouble(tData.ValueData.TotalVoltage) / 10) // 6 voltageOfPack
, String.Format(CultureInfo.InvariantCulture, "{0:#0.0}", Convert.ToDouble(tData.ValueData.TotalCurrent) / 10) // 7 current
, String.Format(CultureInfo.InvariantCulture, "{0:#0.0}", Convert.ToDouble(tData.ValueData.TotalSOC) / 10) // 8 SOC
, String.Format(CultureInfo.InvariantCulture, "{0:#0.0}", Convert.ToDouble(tData.ValueData.TotalTemp) / 10) // 9 Max Temperature
);
sdata += "\r\n";
@@ -428,27 +429,27 @@ namespace LFP_Manager.Utils
, 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
, String.Format(CultureInfo.InvariantCulture, "{0:#0.0}", Convert.ToDouble(sData.ValueData.voltageOfPack) / 10) // 8 voltageOfPack
, String.Format(CultureInfo.InvariantCulture, "{0:#0.0}", Convert.ToDouble(sData.ValueData.current) / 10) // 9 current
, String.Format(CultureInfo.InvariantCulture, "{0:#0.0}", Convert.ToDouble(sData.ValueData.rSOC) / 10) // 10 SOC
, String.Format(CultureInfo.InvariantCulture, "{0:#0.0}", Convert.ToDouble(sData.ValueData.stateOfHealth) / 10) // 11 SOH
, String.Format(CultureInfo.InvariantCulture, "{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
sdata += String.Format(CultureInfo.InvariantCulture, "{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(CultureInfo.InvariantCulture, "{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
sdata += String.Format(CultureInfo.InvariantCulture, "{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(CultureInfo.InvariantCulture, "{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(CultureInfo.InvariantCulture, "{0:#0.0},", Convert.ToDouble(sData.ValueData.Ext1Temperature) / 10); // 34 Ext1 Temperature n
sdata += String.Format(CultureInfo.InvariantCulture, "{0:#0.0},", Convert.ToDouble(sData.ValueData.Ext2Temperature) / 10); // 35 Ext2 Temperature n
sdata += String.Format(
"{0},{1},{2},"

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -392,30 +392,46 @@ namespace LFP_Manager.Utils
{
int Max, Avg, Min, Sum;
int MaxNo, MinNo;
int validCount = 0;
Max = Avg = Min = Sum = 0;
Max = 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];
short tempVal = rSystemData.ValueData.CellTemperature[i];
if (tempVal == 0) continue; // 미연결 및 초기 0도 제외
if (Max < rSystemData.ValueData.CellTemperature[i])
if (validCount == 0)
{
Max = rSystemData.ValueData.CellTemperature[i];
Max = Min = tempVal;
MaxNo = MinNo = i;
}
Sum += tempVal;
validCount++;
if (Max < tempVal)
{
Max = tempVal;
MaxNo = i;
}
if (Min > rSystemData.ValueData.CellTemperature[i])
if (Min > tempVal)
{
Min = rSystemData.ValueData.CellTemperature[i];
Min = tempVal;
MinNo = i;
}
}
Avg = Sum / tempQty;
if (validCount == 0)
{
Avg = 0;
Min = 0;
Max = 0;
}
else
{
Avg = Sum / validCount;
}
rSystemData.AvgData.avgTemp = (short)Avg;
rSystemData.AvgData.maxTemp = (short)Max;