Develop - GciBridge -> GCI -> PreadjustmentUI functions 2

This commit is contained in:
Marek Frniak 2026-05-21 08:16:02 +02:00
parent ad208f9633
commit bc72130d09
11 changed files with 851 additions and 221 deletions

View File

@ -243,6 +243,16 @@ namespace GenesisCordonelInterface.API
return string.IsNullOrWhiteSpace(port) ? "<empty>" : port;
}
public ConcurrentDictionary<RegisterDefinition, Byte[]> GetRegistersDicForSlot(int slot)
{
var meter = GetMeterThreadSafe(slot);
if (meter == null)
throw new Exception($"Slot {slot} not initialized.");
return meter.GetRegistersDic();
}
#endregion
#region ================================== INIT/UPDATE ==================================
@ -1748,6 +1758,163 @@ namespace GenesisCordonelInterface.API
#endregion
#region ================================== PreAdjustmentUI AMPLITUDE TEST process ==================================
/// <summary>
/// Execute standalone amplitude test process.
/// </summary>
public Task<bool> Preadjustment_AmplitudeTestAsync(
ProcessProgress pp,
CancellationToken token = default)
{
if (pp.Setting.TempOnly)
return Task.FromResult(true);
IProcess process;
if (pp.Setting.NumberOfPaths == 1)
{
process =
new SPAmplitudeTestProcess(
"Amplitude Test Single",
PreAdjustmentControl.StatusPanelItems.Amplitude,
PreAdjustmentControl.PredefinedMessages.WaitUntilAmplitudeTestFinished(pp.Setting.Culture),
PreAdjustmentControl.PredefinedMessages.AmplitudeFailed(pp.Setting.Culture),
4 * 60);
}
else
{
process =
new AmplitudeTestProcess(
"Amplitude Test",
PreAdjustmentControl.StatusPanelItems.Amplitude,
PreAdjustmentControl.PredefinedMessages.WaitUntilAmplitudeTestFinished(pp.Setting.Culture),
PreAdjustmentControl.PredefinedMessages.AmplitudeFailed(pp.Setting.Culture),
4 * 60);
}
return ExecuteProcessAsync(
process,
pp,
token);
}
#endregion
#region ================================== PreAdjustmentUI TEMPERATURE CALIBRATION process ==================================
public Task<bool> Preadjustment_TemperatureCalibrationAsync(
ProcessProgress pp,
CancellationToken token = default)
{
IProcess process;
if (pp.Setting.NumberOfPaths == 1)
{
process =
new SPTemperatureCalibrationProcess(
"Temperature Calibration Single",
PreAdjustmentControl.StatusPanelItems.TempCal,
PreAdjustmentControl.PredefinedMessages.WaitUntilTemperatureCalibrationFinished(pp.Setting.Culture),
PreAdjustmentControl.PredefinedMessages.TempCalFailed(pp.Setting.Culture),
2 * 60);
}
else
{
process =
new TemperatureCalibrationProcess(
"Temperature Calibration",
PreAdjustmentControl.StatusPanelItems.TempCal,
PreAdjustmentControl.PredefinedMessages.WaitUntilTemperatureCalibrationFinished(pp.Setting.Culture),
PreAdjustmentControl.PredefinedMessages.TempCalFailed(pp.Setting.Culture),
2 * 60);
}
return ExecuteProcessAsync(
process,
pp,
token);
}
#endregion
#region ================================== PreAdjustmentUI OFFSET TEST process ==================================
public Task<bool> Preadjustment_OffsetTestAsync(
ProcessProgress pp,
CancellationToken token = default)
{
if (pp.Setting.TempOnly)
return Task.FromResult(true);
IProcess process;
if (pp.Setting.NumberOfPaths == 1)
{
process =
new SPOffsetTestProcess(
"Offset Test Single",
PreAdjustmentControl.StatusPanelItems.Offset,
PreAdjustmentControl.PredefinedMessages.WaitUntilZeroflowOffsetTestFinished(pp.Setting.Culture),
PreAdjustmentControl.PredefinedMessages.ZeroflowOffsetTestFailed(pp.Setting.Culture),
18 * 60);
}
else
{
process =
new OffsetTestProcess(
"Offset Test",
PreAdjustmentControl.StatusPanelItems.Offset,
PreAdjustmentControl.PredefinedMessages.WaitUntilZeroflowOffsetTestFinished(pp.Setting.Culture),
PreAdjustmentControl.PredefinedMessages.ZeroflowOffsetTestFailed(pp.Setting.Culture),
18 * 60);
}
return ExecuteProcessAsync(
process,
pp,
token);
}
#endregion
#region ================================== PreAdjustmentUI COMPLETION process ==================================
public Task<bool> Preadjustment_CompletionAsync(
ProcessProgress pp,
CancellationToken token = default)
{
IProcess process;
if (pp.Setting.NumberOfPaths == 1)
{
process =
new SPCompletionProcess(
"Completion Single",
PreAdjustmentControl.StatusPanelItems.Completion,
PreAdjustmentControl.PredefinedMessages.WaitUntilCompletionFinished(pp.Setting.Culture),
PreAdjustmentControl.PredefinedMessages.CompletionFailed(pp.Setting.Culture),
1 * 60);
}
else
{
process =
new CompletionProcess(
"Completion",
PreAdjustmentControl.StatusPanelItems.Completion,
PreAdjustmentControl.PredefinedMessages.WaitUntilCompletionFinished(pp.Setting.Culture),
PreAdjustmentControl.PredefinedMessages.CompletionFailed(pp.Setting.Culture),
1 * 60);
}
return ExecuteProcessAsync(
process,
pp,
token);
}
#endregion
#region ================================== PreAdjustmentUI process threading ==================================
public async Task<bool> ExecuteProcessAsync(

View File

@ -466,11 +466,37 @@ namespace GenesisCordonelInterface.API
ProcessProgress pp,
CancellationToken token = default)
{
return _innerMeterAPI.Preadjustment_PreparationAsync(
pp,
token);
return _innerMeterAPI.Preadjustment_PreparationAsync(pp, token);
}
public Task<bool> Preadjustment_AmplitudeTestAsync(
ProcessProgress pp,
CancellationToken token = default)
{
return _innerMeterAPI.Preadjustment_AmplitudeTestAsync(pp, token);
}
public Task<bool> Preadjustment_TemperatureCalibrationAsync(
ProcessProgress pp,
CancellationToken token = default)
{
return _innerMeterAPI.Preadjustment_TemperatureCalibrationAsync(pp, token);
}
public Task<bool> Preadjustment_OffsetTestAsync(
ProcessProgress pp,
CancellationToken token = default)
{
return _innerMeterAPI.Preadjustment_OffsetTestAsync(pp, token);
}
public Task<bool> Preadjustment_CompletionAsync(
ProcessProgress pp,
CancellationToken token = default)
{
return _innerMeterAPI.Preadjustment_CompletionAsync(pp, token);
}
}
}

View File

@ -25,6 +25,15 @@ namespace GenesisCordonelInterface.Core.Threading
public static class RetryWorker
{
/// <summary>
/// Executes an asynchronous operation with retry and timeout protection.
///
/// Important:
/// The timeout here protects the caller from waiting forever, but it does not forcibly abort
/// the underlying hardware operation. Because hardware/COM calls may continue running after
/// the timeout signal, this method waits for the original action to finish before starting
/// the next retry. This prevents overlapping COM requests on the same device.
/// </summary>
public static async Task<RetryResult<T>> RunWithRetryAsync<T>(
Func<Task<T>> action,
Func<T, bool> isSuccess,
@ -41,21 +50,53 @@ namespace GenesisCordonelInterface.Core.Threading
for (int attempt = 1; attempt <= maxAttempts; attempt++)
{
var actionTask = action();
var timeoutTask = Task.Delay(timeoutMs);
Task<T> actionTask = null;
var completedTask = await Task.WhenAny(actionTask, timeoutTask);
if (completedTask == timeoutTask)
try
{
timedOut = true;
log?.Invoke($"{operationName} timeout attempt {attempt}/{maxAttempts}");
}
else
{
lastResult = await actionTask;
log?.Invoke($"{operationName} started. Attempt {attempt}/{maxAttempts}");
if (isSuccess(lastResult))
// Start real operation, for example Connect/GetPcbId/Login.
actionTask = action();
// Start independent timeout timer.
var timeoutTask = Task.Delay(timeoutMs);
// Wait until either operation completes or timeout expires.
var completedTask = await Task.WhenAny(actionTask, timeoutTask)
.ConfigureAwait(false);
if (completedTask == timeoutTask)
{
timedOut = true;
log?.Invoke(
$"{operationName} timed out. Attempt {attempt}/{maxAttempts}. " +
"Waiting for the running operation to finish before retry.");
// Critical part:
// Do NOT immediately start another retry.
// The hardware operation may still be active in ApiWorker.
// Starting another attempt immediately could corrupt communication.
try
{
lastResult = await actionTask.ConfigureAwait(false);
}
catch (Exception ex)
{
log?.Invoke(
$"{operationName} finished after timeout with exception: " +
$"{ex.GetType().Name}: {ex.Message}");
}
}
else
{
// Operation completed before timeout.
lastResult = await actionTask.ConfigureAwait(false);
}
// Decide whether the returned result means success.
if (lastResult != null && isSuccess(lastResult))
{
return new RetryResult<T>
{
@ -63,15 +104,29 @@ namespace GenesisCordonelInterface.Core.Threading
Success = true,
Attempts = attempt,
Duration = DateTime.Now - started,
TimedOut = false
TimedOut = timedOut
};
}
logResult?.Invoke($"{operationName} failed attempt {attempt}/{maxAttempts}", lastResult);
logResult?.Invoke(
$"{operationName} failed. Attempt {attempt}/{maxAttempts}",
lastResult);
}
catch (Exception ex)
{
// Covers exceptions thrown before timeout handling or by action startup.
log?.Invoke(
$"{operationName} exception on attempt {attempt}/{maxAttempts}: " +
$"{ex.GetType().Name}: {ex.Message}");
}
// Delay before next retry, except after the final attempt.
if (attempt < maxAttempts)
await Task.Delay(delayMs);
{
log?.Invoke($"{operationName} waiting {delayMs} ms before retry.");
await Task.Delay(delayMs).ConfigureAwait(false);
}
}
return new RetryResult<T>

View File

@ -1505,6 +1505,182 @@ namespace TBF.Rig.BridgeComponents.GciBridge
#endregion
#region ================================== PreAdjustment AMPLITUDE TEST bridge ==================================
public async Task<bool> Preadjustment_AmplitudeTestAsync(
ProcessProgress pp,
CancellationToken token = default)
{
const string operation = nameof(Preadjustment_AmplitudeTestAsync);
try
{
EnsureExternalInterface();
if (pp == null)
throw new ArgumentNullException(nameof(pp));
log.InfoFormat("{0}: {1} Start.", Name, operation);
bool result =
await gciExternalInterface
.Preadjustment_AmplitudeTestAsync(
pp,
token)
.ConfigureAwait(false);
log.InfoFormat(
"{0}: {1} Finish. Success={2}",
Name,
operation,
result);
return result;
}
catch (Exception ex)
{
log.Error(
string.Format("{0}: {1} failed.", Name, operation),
ex);
return false;
}
}
#endregion
#region ================================== PreAdjustment TEMPERATURE CALIBRATION bridge ==================================
public async Task<bool> Preadjustment_TemperatureCalibrationAsync(
ProcessProgress pp,
CancellationToken token = default)
{
const string operation = nameof(Preadjustment_TemperatureCalibrationAsync);
try
{
EnsureExternalInterface();
if (pp == null)
throw new ArgumentNullException(nameof(pp));
log.InfoFormat("{0}: {1} Start.", Name, operation);
bool result =
await gciExternalInterface
.Preadjustment_TemperatureCalibrationAsync(
pp,
token)
.ConfigureAwait(false);
log.InfoFormat(
"{0}: {1} Finish. Success={2}",
Name,
operation,
result);
return result;
}
catch (Exception ex)
{
log.Error(
string.Format("{0}: {1} failed.", Name, operation),
ex);
return false;
}
}
#endregion
#region ================================== PreAdjustment OFFSET TEST bridge ==================================
public async Task<bool> Preadjustment_OffsetTestAsync(
ProcessProgress pp,
CancellationToken token = default)
{
const string operation = nameof(Preadjustment_OffsetTestAsync);
try
{
EnsureExternalInterface();
if (pp == null)
throw new ArgumentNullException(nameof(pp));
log.InfoFormat("{0}: {1} Start.", Name, operation);
bool result =
await gciExternalInterface
.Preadjustment_OffsetTestAsync(
pp,
token)
.ConfigureAwait(false);
log.InfoFormat(
"{0}: {1} Finish. Success={2}",
Name,
operation,
result);
return result;
}
catch (Exception ex)
{
log.Error(
string.Format("{0}: {1} failed.", Name, operation),
ex);
return false;
}
}
#endregion
#region ================================== PreAdjustment COMPLETION bridge ==================================
public async Task<bool> Preadjustment_CompletionAsync(
ProcessProgress pp,
CancellationToken token = default)
{
const string operation = nameof(Preadjustment_CompletionAsync);
try
{
EnsureExternalInterface();
if (pp == null)
throw new ArgumentNullException(nameof(pp));
log.InfoFormat("{0}: {1} Start.", Name, operation);
bool result =
await gciExternalInterface
.Preadjustment_CompletionAsync(
pp,
token)
.ConfigureAwait(false);
log.InfoFormat(
"{0}: {1} Finish. Success={2}",
Name,
operation,
result);
return result;
}
catch (Exception ex)
{
log.Error(
string.Format("{0}: {1} failed.", Name, operation),
ex);
return false;
}
}
#endregion
#region ======================================= Helpers =======================================
private UDSRPublicModels.DataQuery CreatePasswordQuery(string pcbId)
{

View File

@ -15,6 +15,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug
private MainForm _mainform;
private MainView _mainView;
public Grid.MeterGridManager _gridManager;
public event Action SelectedSlotsChanged;
private bool isRefreshing;
private List<string> comPorts = new List<string>();
@ -267,8 +268,16 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug
if (columnName == "Selected")
{
bool selected = Convert.ToBoolean(grid.Rows[e.RowIndex].Cells["Selected"].Value);
bool selected =
Convert.ToBoolean(
grid.Rows[e.RowIndex]
.Cells["Selected"]
.Value);
_api.SetSlotSelected(slot, selected);
SelectedSlotsChanged?.Invoke();
return;
}

View File

@ -1,4 +1,5 @@
using System;
using Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

View File

@ -7,9 +7,8 @@
private System.Windows.Forms.GroupBox grpSlots;
private System.Windows.Forms.Button preparationActionButton;
private System.Windows.Forms.Button btnUpdateSlot;
private System.Windows.Forms.Button detectActionButton;
private System.Windows.Forms.Button btnCleanAllSlots;
private System.Windows.Forms.Button temperatureCalibrationActionButton;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.TextBox txtLog;
@ -25,47 +24,41 @@
private void InitializeComponent()
{
this.grpSlots = new System.Windows.Forms.GroupBox();
this.writeRegisterNameComboBox = new System.Windows.Forms.ComboBox();
this.readRegisterNameComboBox = new System.Windows.Forms.ComboBox();
this.label4 = new System.Windows.Forms.Label();
this.writeRegisterValueTextBox = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.writeRegisterButton = new System.Windows.Forms.Button();
this.readRegisterButton = new System.Windows.Forms.Button();
this.btnConnect = new System.Windows.Forms.Button();
this.btnDisconnect = new System.Windows.Forms.Button();
this.btnLogin = new System.Windows.Forms.Button();
this.btnGetPcbId = new System.Windows.Forms.Button();
this.completionActionButton = new System.Windows.Forms.Button();
this.offsetTestActionButton = new System.Windows.Forms.Button();
this.preparationActionButton = new System.Windows.Forms.Button();
this.btnUpdateSlot = new System.Windows.Forms.Button();
this.detectActionButton = new System.Windows.Forms.Button();
this.btnCleanAllSlots = new System.Windows.Forms.Button();
this.btnCleanSlot = new System.Windows.Forms.Button();
this.temperatureCalibrationActionButton = new System.Windows.Forms.Button();
this.amplitudeTestActionButton = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.txtLog = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.grpSlots.SuspendLayout();
this.SuspendLayout();
//
// grpSlots
//
this.grpSlots.Controls.Add(this.writeRegisterNameComboBox);
this.grpSlots.Controls.Add(this.readRegisterNameComboBox);
this.grpSlots.Controls.Add(this.label7);
this.grpSlots.Controls.Add(this.label6);
this.grpSlots.Controls.Add(this.label5);
this.grpSlots.Controls.Add(this.label4);
this.grpSlots.Controls.Add(this.writeRegisterValueTextBox);
this.grpSlots.Controls.Add(this.label3);
this.grpSlots.Controls.Add(this.label2);
this.grpSlots.Controls.Add(this.writeRegisterButton);
this.grpSlots.Controls.Add(this.readRegisterButton);
this.grpSlots.Controls.Add(this.btnConnect);
this.grpSlots.Controls.Add(this.btnDisconnect);
this.grpSlots.Controls.Add(this.btnLogin);
this.grpSlots.Controls.Add(this.btnGetPcbId);
this.grpSlots.Controls.Add(this.label1);
this.grpSlots.Controls.Add(this.button1);
this.grpSlots.Controls.Add(this.completionActionButton);
this.grpSlots.Controls.Add(this.offsetTestActionButton);
this.grpSlots.Controls.Add(this.preparationActionButton);
this.grpSlots.Controls.Add(this.btnUpdateSlot);
this.grpSlots.Controls.Add(this.detectActionButton);
this.grpSlots.Controls.Add(this.btnCleanAllSlots);
this.grpSlots.Controls.Add(this.btnCleanSlot);
this.grpSlots.Controls.Add(this.temperatureCalibrationActionButton);
this.grpSlots.Controls.Add(this.amplitudeTestActionButton);
this.grpSlots.Location = new System.Drawing.Point(10, 10);
this.grpSlots.Name = "grpSlots";
this.grpSlots.Size = new System.Drawing.Size(689, 304);
@ -74,146 +67,56 @@
this.grpSlots.Text = "Slots by selection in the table";
this.grpSlots.Enter += new System.EventHandler(this.grpSlots_Enter);
//
// writeRegisterNameComboBox
// completionActionButton
//
this.writeRegisterNameComboBox.FormattingEnabled = true;
this.writeRegisterNameComboBox.Location = new System.Drawing.Point(300, 264);
this.writeRegisterNameComboBox.Name = "writeRegisterNameComboBox";
this.writeRegisterNameComboBox.Size = new System.Drawing.Size(213, 21);
this.writeRegisterNameComboBox.TabIndex = 15;
this.completionActionButton.Location = new System.Drawing.Point(390, 249);
this.completionActionButton.Name = "completionActionButton";
this.completionActionButton.Size = new System.Drawing.Size(150, 28);
this.completionActionButton.TabIndex = 3;
this.completionActionButton.Text = "Completition";
//
// readRegisterNameComboBox
// offsetTestActionButton
//
this.readRegisterNameComboBox.FormattingEnabled = true;
this.readRegisterNameComboBox.Location = new System.Drawing.Point(300, 230);
this.readRegisterNameComboBox.Name = "readRegisterNameComboBox";
this.readRegisterNameComboBox.Size = new System.Drawing.Size(213, 21);
this.readRegisterNameComboBox.TabIndex = 14;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(224, 233);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(78, 13);
this.label4.TabIndex = 13;
this.label4.Text = "Register name:";
//
// writeRegisterValueTextBox
//
this.writeRegisterValueTextBox.Location = new System.Drawing.Point(555, 264);
this.writeRegisterValueTextBox.Name = "writeRegisterValueTextBox";
this.writeRegisterValueTextBox.Size = new System.Drawing.Size(117, 20);
this.writeRegisterValueTextBox.TabIndex = 12;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(517, 267);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(36, 13);
this.label3.TabIndex = 10;
this.label3.Text = "value:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(224, 267);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(78, 13);
this.label2.TabIndex = 9;
this.label2.Text = "Register name:";
//
// writeRegisterButton
//
this.writeRegisterButton.Location = new System.Drawing.Point(15, 259);
this.writeRegisterButton.Name = "writeRegisterButton";
this.writeRegisterButton.Size = new System.Drawing.Size(203, 28);
this.writeRegisterButton.TabIndex = 7;
this.writeRegisterButton.Text = "WriteRegister(slot, registerName, value)";
this.writeRegisterButton.Click += new System.EventHandler(this.writeRegisterButton_Click);
//
// readRegisterButton
//
this.readRegisterButton.Location = new System.Drawing.Point(15, 225);
this.readRegisterButton.Name = "readRegisterButton";
this.readRegisterButton.Size = new System.Drawing.Size(203, 28);
this.readRegisterButton.TabIndex = 6;
this.readRegisterButton.Text = "ReadRegister(slot, registerName)";
//
// btnConnect
//
this.btnConnect.Location = new System.Drawing.Point(15, 158);
this.btnConnect.Name = "btnConnect";
this.btnConnect.Size = new System.Drawing.Size(150, 28);
this.btnConnect.TabIndex = 3;
this.btnConnect.Text = "Connect(slot)";
//
// btnDisconnect
//
this.btnDisconnect.Location = new System.Drawing.Point(15, 191);
this.btnDisconnect.Name = "btnDisconnect";
this.btnDisconnect.Size = new System.Drawing.Size(150, 28);
this.btnDisconnect.TabIndex = 4;
this.btnDisconnect.Text = "Disconnect(slot)";
//
// btnLogin
//
this.btnLogin.Location = new System.Drawing.Point(171, 158);
this.btnLogin.Name = "btnLogin";
this.btnLogin.Size = new System.Drawing.Size(150, 28);
this.btnLogin.TabIndex = 17;
this.btnLogin.Text = "Login(slot)";
//
// btnGetPcbId
//
this.btnGetPcbId.Location = new System.Drawing.Point(15, 125);
this.btnGetPcbId.Name = "btnGetPcbId";
this.btnGetPcbId.Size = new System.Drawing.Size(150, 28);
this.btnGetPcbId.TabIndex = 5;
this.btnGetPcbId.Text = "GetPcb(slot)";
this.offsetTestActionButton.Location = new System.Drawing.Point(334, 215);
this.offsetTestActionButton.Name = "offsetTestActionButton";
this.offsetTestActionButton.Size = new System.Drawing.Size(150, 28);
this.offsetTestActionButton.TabIndex = 5;
this.offsetTestActionButton.Text = "Offset test";
//
// preparationActionButton
//
this.preparationActionButton.Location = new System.Drawing.Point(15, 25);
this.preparationActionButton.Location = new System.Drawing.Point(203, 113);
this.preparationActionButton.Name = "preparationActionButton";
this.preparationActionButton.Size = new System.Drawing.Size(150, 28);
this.preparationActionButton.TabIndex = 0;
this.preparationActionButton.Text = "Preparation";
this.preparationActionButton.Click += new System.EventHandler(this.preparationActionButton_Click);
//
// btnUpdateSlot
//
this.btnUpdateSlot.Location = new System.Drawing.Point(171, 25);
this.btnUpdateSlot.Name = "btnUpdateSlot";
this.btnUpdateSlot.Size = new System.Drawing.Size(150, 28);
this.btnUpdateSlot.TabIndex = 16;
this.btnUpdateSlot.Text = "UpdateSlot(slot)";
//
// detectActionButton
//
this.detectActionButton.Location = new System.Drawing.Point(15, 58);
this.detectActionButton.Location = new System.Drawing.Point(171, 79);
this.detectActionButton.Name = "detectActionButton";
this.detectActionButton.Size = new System.Drawing.Size(150, 28);
this.detectActionButton.TabIndex = 1;
this.detectActionButton.Text = "Detect";
this.detectActionButton.Click += new System.EventHandler(this.detectActionButton_Click);
//
// btnCleanAllSlots
// temperatureCalibrationActionButton
//
this.btnCleanAllSlots.Location = new System.Drawing.Point(171, 92);
this.btnCleanAllSlots.Name = "btnCleanAllSlots";
this.btnCleanAllSlots.Size = new System.Drawing.Size(150, 28);
this.btnCleanAllSlots.TabIndex = 2;
this.btnCleanAllSlots.Text = "CleanAllSlots()";
this.temperatureCalibrationActionButton.Location = new System.Drawing.Point(285, 181);
this.temperatureCalibrationActionButton.Name = "temperatureCalibrationActionButton";
this.temperatureCalibrationActionButton.Size = new System.Drawing.Size(150, 28);
this.temperatureCalibrationActionButton.TabIndex = 2;
this.temperatureCalibrationActionButton.Text = "Temperature calibration";
this.temperatureCalibrationActionButton.Click += new System.EventHandler(this.amplitudeTestActionButton_Click);
//
// btnCleanSlot
// amplitudeTestActionButton
//
this.btnCleanSlot.Location = new System.Drawing.Point(15, 92);
this.btnCleanSlot.Name = "btnCleanSlot";
this.btnCleanSlot.Size = new System.Drawing.Size(150, 28);
this.btnCleanSlot.TabIndex = 18;
this.btnCleanSlot.Text = "CleanSlot(slot)";
this.amplitudeTestActionButton.Location = new System.Drawing.Point(246, 147);
this.amplitudeTestActionButton.Name = "amplitudeTestActionButton";
this.amplitudeTestActionButton.Size = new System.Drawing.Size(150, 28);
this.amplitudeTestActionButton.TabIndex = 18;
this.amplitudeTestActionButton.Text = "Amplitude test";
//
// btnCancel
//
@ -239,6 +142,84 @@
this.txtLog.TabIndex = 5;
this.txtLog.WordWrap = false;
//
// button1
//
this.button1.Location = new System.Drawing.Point(17, 28);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(150, 28);
this.button1.TabIndex = 108;
this.button1.Text = "Preadjustment init";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(176, 121);
this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(22, 13);
this.label1.TabIndex = 109;
this.label1.Text = "--->";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(219, 155);
this.label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(22, 13);
this.label2.TabIndex = 110;
this.label2.Text = "--->";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(258, 189);
this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(22, 13);
this.label3.TabIndex = 111;
this.label3.Text = "--->";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(307, 223);
this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(22, 13);
this.label4.TabIndex = 112;
this.label4.Text = "--->";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(363, 257);
this.label5.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(22, 13);
this.label5.TabIndex = 113;
this.label5.Text = "--->";
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(14, 87);
this.label6.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(117, 13);
this.label6.TabIndex = 114;
this.label6.Text = "Preadjustment process:";
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(144, 87);
this.label7.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(22, 13);
this.label7.TabIndex = 115;
this.label7.Text = "--->";
//
// PreadjustmentActionsView
//
this.BackColor = System.Drawing.SystemColors.Control;
@ -254,18 +235,16 @@
}
private System.Windows.Forms.Button btnConnect;
private System.Windows.Forms.Button btnDisconnect;
private System.Windows.Forms.Button btnGetPcbId;
private System.Windows.Forms.Button readRegisterButton;
private System.Windows.Forms.TextBox writeRegisterValueTextBox;
private System.Windows.Forms.Button completionActionButton;
private System.Windows.Forms.Button offsetTestActionButton;
private System.Windows.Forms.Button amplitudeTestActionButton;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button writeRegisterButton;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.ComboBox writeRegisterNameComboBox;
private System.Windows.Forms.ComboBox readRegisterNameComboBox;
private System.Windows.Forms.Button btnLogin;
private System.Windows.Forms.Button btnCleanSlot;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label label6;
}
}

View File

@ -120,19 +120,15 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
Cursor = busy ? Cursors.WaitCursor : Cursors.Default;
preparationActionButton.Enabled = !busy;
btnUpdateSlot.Enabled = !busy;
detectActionButton.Enabled = !busy;
btnCleanAllSlots.Enabled = !busy;
btnGetPcbId.Enabled = !busy;
btnConnect.Enabled = !busy;
btnDisconnect.Enabled = !busy;
readRegisterButton.Enabled = !busy;
writeRegisterButton.Enabled = !busy;
readRegisterNameComboBox.Enabled = !busy;
writeRegisterNameComboBox.Enabled = !busy;
writeRegisterValueTextBox.Enabled = !busy;
btnLogin.Enabled = !busy;
btnCleanSlot.Enabled = !busy;
temperatureCalibrationActionButton.Enabled = !busy;
offsetTestActionButton.Enabled = !busy;
completionActionButton.Enabled = !busy;
amplitudeTestActionButton.Enabled = !busy;
amplitudeTestActionButton.Enabled = !busy;
temperatureCalibrationActionButton.Enabled = !busy;
offsetTestActionButton.Enabled = !busy;
completionActionButton.Enabled = !busy;
btnCancel.Enabled = busy;
}
@ -154,13 +150,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
private void LoadRegisterComboBoxes()
{
var registers = _bridge.GetAllRegisterNames();
readRegisterNameComboBox.Items.Clear();
writeRegisterNameComboBox.Items.Clear();
readRegisterNameComboBox.Items.AddRange(registers.ToArray());
writeRegisterNameComboBox.Items.AddRange(registers.ToArray());
}
private void grpSlots_Enter(object sender, EventArgs e)
@ -281,6 +271,70 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
return settings;
}
private void amplitudeTestActionButton_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
{
var pp = CreatePreparationProgress();
bool success = await _bridge.Preadjustment_AmplitudeTestAsync(pp, token);
Log(success
? "Amplitude Test completed."
: "Amplitude Test failed.");
RefreshGrid();
});
}
private void temperatureCalibrationActionButton_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
{
var pp = CreatePreparationProgress();
bool success = await _bridge.Preadjustment_TemperatureCalibrationAsync(pp, token);
Log(success
? "Temperature Calibration completed."
: "Temperature Calibration failed.");
RefreshGrid();
});
}
private void offsetTestActionButton_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
{
var pp = CreatePreparationProgress();
bool success = await _bridge.Preadjustment_OffsetTestAsync(pp, token);
Log(success
? "Offset Test completed."
: "Offset Test failed.");
RefreshGrid();
});
}
private void completionActionButton_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
{
var pp = CreatePreparationProgress();
bool success = await _bridge.Preadjustment_CompletionAsync(pp, token);
Log(success
? "Completion completed."
: "Completion failed.");
RefreshGrid();
});
}
private void writeRegisterButton_Click(object sender, EventArgs e)
{
/*ExecuteAsync(async token =>

View File

@ -42,6 +42,7 @@
this.btnGetSlot = new System.Windows.Forms.Button();
this.btnCleanAllSlots = new System.Windows.Forms.Button();
this.btnCleanSlot = new System.Windows.Forms.Button();
this.writeRegisterValueTypeLabel = new System.Windows.Forms.Label();
this.btnCancel = new System.Windows.Forms.Button();
this.txtLog = new System.Windows.Forms.TextBox();
this.grpSlots.SuspendLayout();
@ -49,6 +50,9 @@
//
// grpSlots
//
this.grpSlots.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.grpSlots.Controls.Add(this.writeRegisterNameComboBox);
this.grpSlots.Controls.Add(this.readRegisterNameComboBox);
this.grpSlots.Controls.Add(this.label4);
@ -66,9 +70,10 @@
this.grpSlots.Controls.Add(this.btnGetSlot);
this.grpSlots.Controls.Add(this.btnCleanAllSlots);
this.grpSlots.Controls.Add(this.btnCleanSlot);
this.grpSlots.Controls.Add(this.writeRegisterValueTypeLabel);
this.grpSlots.Location = new System.Drawing.Point(10, 10);
this.grpSlots.Name = "grpSlots";
this.grpSlots.Size = new System.Drawing.Size(689, 304);
this.grpSlots.Size = new System.Drawing.Size(726, 304);
this.grpSlots.TabIndex = 2;
this.grpSlots.TabStop = false;
this.grpSlots.Text = "Slots by selection in the table";
@ -103,7 +108,7 @@
//
this.writeRegisterValueTextBox.Location = new System.Drawing.Point(555, 264);
this.writeRegisterValueTextBox.Name = "writeRegisterValueTextBox";
this.writeRegisterValueTextBox.Size = new System.Drawing.Size(117, 20);
this.writeRegisterValueTextBox.Size = new System.Drawing.Size(85, 20);
this.writeRegisterValueTextBox.TabIndex = 12;
//
// label3
@ -223,6 +228,15 @@
this.btnCleanSlot.Text = "CleanSlot(slot)";
this.btnCleanSlot.Click += new System.EventHandler(this.btnCleanSlot_Click);
//
// writeRegisterValueTypeLabel
//
this.writeRegisterValueTypeLabel.AutoSize = true;
this.writeRegisterValueTypeLabel.Location = new System.Drawing.Point(646, 267);
this.writeRegisterValueTypeLabel.Name = "writeRegisterValueTypeLabel";
this.writeRegisterValueTypeLabel.Size = new System.Drawing.Size(36, 13);
this.writeRegisterValueTypeLabel.TabIndex = 19;
this.writeRegisterValueTypeLabel.Text = "type: -";
//
// btnCancel
//
this.btnCancel.Enabled = false;
@ -243,18 +257,18 @@
this.txtLog.Name = "txtLog";
this.txtLog.ReadOnly = true;
this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtLog.Size = new System.Drawing.Size(689, 232);
this.txtLog.Size = new System.Drawing.Size(726, 232);
this.txtLog.TabIndex = 5;
this.txtLog.WordWrap = false;
//
// GenesisCordonelInterfaceView
// SlotsComPortsRegistersActionsView
//
this.BackColor = System.Drawing.SystemColors.Control;
this.Controls.Add(this.grpSlots);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.txtLog);
this.Name = "GenesisCordonelInterfaceView";
this.Size = new System.Drawing.Size(719, 603);
this.Name = "SlotsComPortsRegistersActionsView";
this.Size = new System.Drawing.Size(756, 603);
this.grpSlots.ResumeLayout(false);
this.grpSlots.PerformLayout();
this.ResumeLayout(false);
@ -275,5 +289,6 @@
private System.Windows.Forms.ComboBox readRegisterNameComboBox;
private System.Windows.Forms.Button btnLogin;
private System.Windows.Forms.Button btnCleanSlot;
private System.Windows.Forms.Label writeRegisterValueTypeLabel;
}
}

View File

@ -17,6 +17,8 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
private CancellationTokenSource _cts;
private readonly Action _addSlotAction;
private readonly Action _saveAction;
private readonly Dictionary<string, Type> _registerTypes =
new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
public SlotsComPortsRegistersActionsView(
MainView mainview,
@ -33,6 +35,13 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
InitializeComponent();
LoadRegisterComboBoxes();
_mainView._batchPanel.SelectedSlotsChanged -= LoadRegisterComboBoxes;
_mainView._batchPanel.SelectedSlotsChanged += LoadRegisterComboBoxes;
writeRegisterNameComboBox.SelectedIndexChanged -= writeRegisterNameComboBox_SelectedIndexChanged;
writeRegisterNameComboBox.SelectedIndexChanged += writeRegisterNameComboBox_SelectedIndexChanged;
writeRegisterNameComboBox.TextChanged -= writeRegisterNameComboBox_SelectedIndexChanged;
writeRegisterNameComboBox.TextChanged += writeRegisterNameComboBox_SelectedIndexChanged;
}
private void AddSlot()
@ -48,14 +57,14 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
private List<GciPublicModels.MeterBatchDebugStatus> GetSelectedSlots()
{
if (_mainView == null || _mainView._batchPanel == null)
throw new Exception("Meter batch grid is not available.");
{
Log("Meter batch grid is not available.");
var slots = _mainView._batchPanel.GetSelectedGridData();
return new List<GciPublicModels.MeterBatchDebugStatus>();
}
if (slots.Count == 0)
throw new Exception("No selected slots in grid.");
return slots;
return _mainView._batchPanel.GetSelectedGridData()
?? new List<GciPublicModels.MeterBatchDebugStatus>();
}
private void RefreshGrid(int? removedSlot = null)
@ -414,16 +423,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
if (string.IsNullOrWhiteSpace(valueText))
throw new Exception("Write register value is empty.");
object value;
if (registerName == "GENESISFLOW_LedMode")
{
value = byte.Parse(valueText);
}
else
{
value = valueText;
}
object value = ConvertTextToRegisterValue(registerName, valueText);
var tasks = GetSelectedSlots()
.Select(async slot =>
@ -530,18 +530,162 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
private void LoadRegisterComboBoxes()
{
var registers = _bridge.GetAllRegisterNames();
_registerTypes.Clear();
readRegisterNameComboBox.Items.Clear();
writeRegisterNameComboBox.Items.Clear();
readRegisterNameComboBox.Items.AddRange(registers.ToArray());
writeRegisterNameComboBox.Items.AddRange(registers.ToArray());
var selectedSlots = GetSelectedSlots();
if (selectedSlots.Count == 0)
{
Log("No selected slot.");
return;
}
int slot = selectedSlots
.OrderBy(x => x.Slot)
.First()
.Slot;
var registers = _mainView._laatzenApi.GetRegistersDicForSlot(slot);
var uniqueRegisters = registers
.GroupBy(x => x.Key.GetIdent())
.Select(g => g.First())
.OrderBy(x => x.Key.GetIdent())
.ToList();
foreach (var item in uniqueRegisters)
{
string registerName = item.Key.GetIdent();
Type dataType = item.Key.DataType;
_registerTypes[registerName] = dataType;
readRegisterNameComboBox.Items.Add(registerName);
writeRegisterNameComboBox.Items.Add(registerName);
}
Log($"Loaded {uniqueRegisters.Count} unique registers from slot {slot}");
}
private void grpSlots_Enter(object sender, EventArgs e)
{
}
private void writeRegisterNameComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
string registerName = Convert.ToString(writeRegisterNameComboBox.Text).Trim();
if (_registerTypes.TryGetValue(registerName, out var type))
{
writeRegisterValueTypeLabel.Text = $"type: {type.Name}";
}
else
{
writeRegisterValueTypeLabel.Text = "type: -";
}
}
private object ConvertTextToRegisterValue(
string registerName,
string valueText)
{
if (!_registerTypes.TryGetValue(
registerName,
out var targetType))
{
throw new Exception(
$"Unknown register type for register '{registerName}'.");
}
return ConvertTextToType(
valueText,
targetType,
registerName);
}
private object ConvertTextToType(
string valueText,
Type targetType,
string registerName)
{
if (targetType == typeof(string))
return valueText;
if (targetType.IsEnum)
{
return Enum.Parse(
targetType,
valueText,
true);
}
if (targetType == typeof(byte[]))
{
return ParseByteArray(valueText);
}
if (targetType.Name == "Enum8")
{
return byte.Parse(valueText);
}
try
{
return Convert.ChangeType(
valueText,
targetType,
System.Globalization.CultureInfo.InvariantCulture);
}
catch (Exception ex)
{
throw new Exception(
$"Value '{valueText}' cannot be converted to '{targetType.Name}' for register '{registerName}'.",
ex);
}
}
private byte[] ParseByteArray(string valueText)
{
valueText = valueText.Trim();
if (valueText.Contains("-") ||
valueText.Contains(" "))
{
return valueText
.Split(
new[] { '-', ' ', ',', ';' },
StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Replace("0x", ""))
.Select(x => Convert.ToByte(x, 16))
.ToArray();
}
valueText =
valueText.Replace("0x", "");
if (valueText.Length % 2 != 0)
{
throw new Exception(
"Hex string length must be even.");
}
byte[] result =
new byte[valueText.Length / 2];
for (int i = 0; i < result.Length; i++)
{
string hex =
valueText.Substring(i * 2, 2);
result[i] =
Convert.ToByte(hex, 16);
}
return result;
}
}
}

View File

@ -4450,6 +4450,10 @@
<Project>{d0c8d887-ed52-40ab-a069-90bce0e801e2}</Project>
<Name>CordonelPreadjustmentUi</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Hardware\WaterMeter\Genesis\Registers\Registers.csproj">
<Project>{f4aaf7e6-7333-4284-b735-e32deb076c64}</Project>
<Name>Registers</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Logic\ProductionOrderCore\ProductionOrderCore.csproj">
<Project>{6d2777bb-7a88-466d-a49b-3266f9bf0160}</Project>
<Name>ProductionOrderCore</Name>