2026-04-27 05:57:16 +00:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO.Ports;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
using GenesisCordonelInterface.API;
|
2026-05-04 09:29:13 +00:00
|
|
|
|
using static GenesisCordonelInterface.API.PublicModels;
|
2026-04-27 05:57:16 +00:00
|
|
|
|
|
|
|
|
|
|
namespace GenesisCordonelInterface.UI.Debug
|
|
|
|
|
|
{
|
|
|
|
|
|
public partial class MeterBatchConfigPanel : UserControl
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly InterfaceOutsideToGCI api;
|
|
|
|
|
|
|
|
|
|
|
|
private bool isRefreshing;
|
|
|
|
|
|
private List<string> comPorts = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
public MeterBatchConfigPanel(InterfaceOutsideToGCI api)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.api = api;
|
|
|
|
|
|
|
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
|
|
|
|
|
|
|
RefreshComPorts();
|
|
|
|
|
|
InitializeGridColumns();
|
|
|
|
|
|
|
|
|
|
|
|
api.MeterBatchStatusChanged += Api_MeterBatchStatusChanged;
|
|
|
|
|
|
|
|
|
|
|
|
UpdateGrid(api.GetMeterBatchDebugStatuses());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region INIT
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
private void InitializeGridColumns()
|
|
|
|
|
|
{
|
|
|
|
|
|
grid.Columns.Clear();
|
|
|
|
|
|
|
|
|
|
|
|
grid.Columns.Add("Slot", "Slot");
|
|
|
|
|
|
grid.Columns.Add(new DataGridViewCheckBoxColumn { Name = "Selected", HeaderText = "Selected" });
|
|
|
|
|
|
grid.Columns.Add("PcbId", "PcbId");
|
|
|
|
|
|
grid.Columns.Add(new DataGridViewCheckBoxColumn { Name = "IsLoggedOn", HeaderText = "IsLoggedOn" });
|
|
|
|
|
|
|
|
|
|
|
|
grid.Columns.Add(CreateComPortColumn("RequestPort", "RequestPort"));
|
|
|
|
|
|
grid.Columns.Add(CreateComPortColumn("StreamingPort", "StreamingPort"));
|
|
|
|
|
|
|
|
|
|
|
|
grid.Columns.Add(CreateButtonColumn("DetectRequest", "DetectRequest", "..."));
|
|
|
|
|
|
grid.Columns.Add(CreateButtonColumn("DetectStreaming", "DetectStreaming", "..."));
|
|
|
|
|
|
|
|
|
|
|
|
grid.Columns.Add("FwVersion", "FwVersion");
|
|
|
|
|
|
grid.Columns.Add("InterfaceVersion", "InterfaceVersion");
|
|
|
|
|
|
|
|
|
|
|
|
foreach (DataGridViewColumn col in grid.Columns)
|
|
|
|
|
|
{
|
|
|
|
|
|
col.ReadOnly =
|
|
|
|
|
|
col.Name != "Selected" &&
|
|
|
|
|
|
col.Name != "RequestPort" &&
|
|
|
|
|
|
col.Name != "StreamingPort" &&
|
|
|
|
|
|
col.Name != "DetectRequest" &&
|
|
|
|
|
|
col.Name != "DetectStreaming";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EnableDoubleBuffering(grid);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private DataGridViewComboBoxColumn CreateComPortColumn(string name, string headerText)
|
|
|
|
|
|
{
|
|
|
|
|
|
return new DataGridViewComboBoxColumn
|
|
|
|
|
|
{
|
|
|
|
|
|
Name = name,
|
|
|
|
|
|
HeaderText = headerText,
|
|
|
|
|
|
DataSource = new List<string>(comPorts),
|
|
|
|
|
|
FlatStyle = FlatStyle.Flat,
|
|
|
|
|
|
DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private DataGridViewButtonColumn CreateButtonColumn(string name, string headerText, string text)
|
|
|
|
|
|
{
|
|
|
|
|
|
return new DataGridViewButtonColumn
|
|
|
|
|
|
{
|
|
|
|
|
|
Name = name,
|
|
|
|
|
|
HeaderText = headerText,
|
|
|
|
|
|
Text = text,
|
|
|
|
|
|
UseColumnTextForButtonValue = true
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void RefreshComPorts()
|
|
|
|
|
|
{
|
|
|
|
|
|
comPorts = SerialPort.GetPortNames()
|
|
|
|
|
|
.OrderBy(NaturalComPortOrder)
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
|
|
if (!comPorts.Contains(""))
|
|
|
|
|
|
comPorts.Insert(0, "");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region REFRESH EVENT DRIVEN
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
private void Api_MeterBatchStatusChanged(
|
2026-05-04 09:29:13 +00:00
|
|
|
|
List<MeterBatchDebugStatus> data)
|
2026-04-27 05:57:16 +00:00
|
|
|
|
{
|
|
|
|
|
|
if (IsDisposed)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (InvokeRequired)
|
|
|
|
|
|
{
|
|
|
|
|
|
BeginInvoke(new Action(() => UpdateGrid(data)));
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UpdateGrid(data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-04 09:29:13 +00:00
|
|
|
|
private void UpdateGrid(List<MeterBatchDebugStatus> data)
|
2026-04-27 05:57:16 +00:00
|
|
|
|
{
|
|
|
|
|
|
isRefreshing = true;
|
|
|
|
|
|
|
2026-06-12 08:43:34 +00:00
|
|
|
|
if(data != null)
|
|
|
|
|
|
foreach (var meter in data)
|
|
|
|
|
|
{
|
|
|
|
|
|
EnsurePortValueExists(meter.RequestPort);
|
|
|
|
|
|
EnsurePortValueExists(meter.StreamingPort);
|
|
|
|
|
|
|
|
|
|
|
|
var row = FindOrCreateRow(meter.Slot);
|
|
|
|
|
|
|
|
|
|
|
|
Set(row, "Slot", meter.Slot);
|
|
|
|
|
|
Set(row, "Selected", meter.Selected);
|
|
|
|
|
|
Set(row, "PcbId", meter.PcbId);
|
|
|
|
|
|
Set(row, "IsLoggedOn", meter.IsLoggedOn);
|
|
|
|
|
|
Set(row, "RequestPort", meter.RequestPort);
|
|
|
|
|
|
Set(row, "StreamingPort", meter.StreamingPort);
|
|
|
|
|
|
Set(row, "FwVersion", meter.FwVersion);
|
|
|
|
|
|
Set(row, "InterfaceVersion", meter.InterfaceVersion);
|
|
|
|
|
|
}
|
2026-04-27 05:57:16 +00:00
|
|
|
|
|
|
|
|
|
|
isRefreshing = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region COM PORT HELPERS
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
private void UpdateComPortColumnItems(string columnName)
|
|
|
|
|
|
{
|
|
|
|
|
|
var col = grid.Columns[columnName] as DataGridViewComboBoxColumn;
|
|
|
|
|
|
if (col == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
col.DataSource = null;
|
|
|
|
|
|
col.DataSource = new List<string>(comPorts);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void EnsurePortValueExists(string port)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(port))
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (comPorts.Contains(port))
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
comPorts.Add(port);
|
|
|
|
|
|
comPorts = comPorts.OrderBy(NaturalComPortOrder).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
if (!comPorts.Contains(""))
|
|
|
|
|
|
comPorts.Insert(0, "");
|
|
|
|
|
|
|
|
|
|
|
|
UpdateComPortColumnItems("RequestPort");
|
|
|
|
|
|
UpdateComPortColumnItems("StreamingPort");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static int NaturalComPortOrder(string port)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(port))
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
string number = new string(port.Where(char.IsDigit).ToArray());
|
|
|
|
|
|
|
|
|
|
|
|
int parsed;
|
|
|
|
|
|
if (int.TryParse(number, out parsed))
|
|
|
|
|
|
return parsed;
|
|
|
|
|
|
|
|
|
|
|
|
return int.MaxValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region GRID HELPERS
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
private DataGridViewRow FindOrCreateRow(int slot)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (DataGridViewRow row in grid.Rows)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (row.Cells["Slot"].Value != null &&
|
|
|
|
|
|
Convert.ToInt32(row.Cells["Slot"].Value) == slot)
|
|
|
|
|
|
{
|
|
|
|
|
|
return row;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int idx = grid.Rows.Add();
|
|
|
|
|
|
var newRow = grid.Rows[idx];
|
|
|
|
|
|
newRow.Cells["Slot"].Value = slot;
|
|
|
|
|
|
return newRow;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void Set(DataGridViewRow row, string col, object value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!grid.Columns.Contains(col))
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (value == null)
|
|
|
|
|
|
value = "";
|
|
|
|
|
|
|
|
|
|
|
|
var cell = row.Cells[col];
|
|
|
|
|
|
|
|
|
|
|
|
if (!Equals(cell.Value, value))
|
|
|
|
|
|
cell.Value = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region USER EDIT
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
private void grid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (grid.IsCurrentCellDirty)
|
|
|
|
|
|
grid.CommitEdit(DataGridViewDataErrorContexts.Commit);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void grid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isRefreshing)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (e.RowIndex < 0)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
string columnName = grid.Columns[e.ColumnIndex].Name;
|
|
|
|
|
|
|
|
|
|
|
|
if (columnName != "Selected" &&
|
|
|
|
|
|
columnName != "RequestPort" &&
|
|
|
|
|
|
columnName != "StreamingPort")
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
int slot = Convert.ToInt32(grid.Rows[e.RowIndex].Cells["Slot"].Value);
|
|
|
|
|
|
|
|
|
|
|
|
if (columnName == "Selected")
|
|
|
|
|
|
{
|
|
|
|
|
|
bool selected = Convert.ToBoolean(grid.Rows[e.RowIndex].Cells["Selected"].Value);
|
|
|
|
|
|
api.SetSlotSelected(slot, selected);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string port = Convert.ToString(grid.Rows[e.RowIndex].Cells[columnName].Value);
|
|
|
|
|
|
|
|
|
|
|
|
if (columnName == "RequestPort")
|
|
|
|
|
|
{
|
2026-04-27 14:40:42 +00:00
|
|
|
|
//api.SetSlotRequestPort(slot, port);
|
2026-04-27 05:57:16 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (columnName == "StreamingPort")
|
|
|
|
|
|
{
|
2026-04-27 14:40:42 +00:00
|
|
|
|
//api.SetSlotStreamingPort(slot, port);
|
2026-04-27 05:57:16 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async void grid_CellContentClick(object sender, DataGridViewCellEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (e.RowIndex < 0)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
string columnName = grid.Columns[e.ColumnIndex].Name;
|
|
|
|
|
|
|
|
|
|
|
|
if (columnName != "DetectRequest" &&
|
|
|
|
|
|
columnName != "DetectStreaming")
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
int slot = Convert.ToInt32(grid.Rows[e.RowIndex].Cells["Slot"].Value);
|
|
|
|
|
|
|
|
|
|
|
|
if (columnName == "DetectRequest")
|
|
|
|
|
|
{
|
|
|
|
|
|
await DetectRequestPortAsync(slot);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (columnName == "DetectStreaming")
|
|
|
|
|
|
{
|
|
|
|
|
|
await DetectStreamingPortAsync(slot);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task DetectRequestPortAsync(int slot)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
grid.Enabled = false;
|
|
|
|
|
|
await api.DetectRequestPortAsync(slot);
|
|
|
|
|
|
api.RaiseMeterBatchStatusChanged();
|
|
|
|
|
|
}
|
|
|
|
|
|
finally
|
|
|
|
|
|
{
|
|
|
|
|
|
grid.Enabled = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task DetectStreamingPortAsync(int slot)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
grid.Enabled = false;
|
|
|
|
|
|
await api.DetectStreamingPortAsync(slot);
|
|
|
|
|
|
api.RaiseMeterBatchStatusChanged();
|
|
|
|
|
|
}
|
|
|
|
|
|
finally
|
|
|
|
|
|
{
|
|
|
|
|
|
grid.Enabled = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void grid_DataError(object sender, DataGridViewDataErrorEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
e.ThrowException = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region PERFORMANCE
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
private void EnableDoubleBuffering(DataGridView dgv)
|
|
|
|
|
|
{
|
|
|
|
|
|
typeof(DataGridView)
|
|
|
|
|
|
.GetProperty(
|
|
|
|
|
|
"DoubleBuffered",
|
|
|
|
|
|
System.Reflection.BindingFlags.Instance |
|
|
|
|
|
|
System.Reflection.BindingFlags.NonPublic)
|
|
|
|
|
|
?.SetValue(dgv, true, null);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
public void AddEmptySlotRow()
|
|
|
|
|
|
{
|
|
|
|
|
|
int nextSlot = 1;
|
|
|
|
|
|
|
|
|
|
|
|
var existing = grid.Rows
|
|
|
|
|
|
.Cast<DataGridViewRow>()
|
|
|
|
|
|
.Where(r => r.Cells["Slot"].Value != null)
|
|
|
|
|
|
.Select(r => Convert.ToInt32(r.Cells["Slot"].Value))
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
|
|
if (existing.Count > 0)
|
|
|
|
|
|
nextSlot = existing.Max() + 1;
|
|
|
|
|
|
|
|
|
|
|
|
int idx = grid.Rows.Add();
|
|
|
|
|
|
var row = grid.Rows[idx];
|
|
|
|
|
|
|
|
|
|
|
|
row.Cells["Slot"].Value = nextSlot;
|
|
|
|
|
|
row.Cells["Selected"].Value = true;
|
|
|
|
|
|
row.Cells["RequestPort"].Value = "";
|
|
|
|
|
|
row.Cells["StreamingPort"].Value = "";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-04 09:29:13 +00:00
|
|
|
|
public List<MeterBatchDebugStatus> GetGridData()
|
2026-04-27 05:57:16 +00:00
|
|
|
|
{
|
2026-05-04 09:29:13 +00:00
|
|
|
|
var list = new List<MeterBatchDebugStatus>();
|
2026-04-27 05:57:16 +00:00
|
|
|
|
|
|
|
|
|
|
foreach (DataGridViewRow row in grid.Rows)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (row.Cells["Slot"].Value == null)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
2026-05-04 09:29:13 +00:00
|
|
|
|
list.Add(new MeterBatchDebugStatus
|
2026-04-27 05:57:16 +00:00
|
|
|
|
{
|
|
|
|
|
|
Slot = Convert.ToInt32(row.Cells["Slot"].Value),
|
|
|
|
|
|
Selected = Convert.ToBoolean(row.Cells["Selected"].Value),
|
|
|
|
|
|
RequestPort = Convert.ToString(row.Cells["RequestPort"].Value),
|
|
|
|
|
|
StreamingPort = Convert.ToString(row.Cells["StreamingPort"].Value)
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|