Compare commits

...

2 Commits

9 changed files with 308 additions and 220 deletions

View File

@ -164,77 +164,6 @@ namespace GenesisCordonelInterface.API
#region ================================== INIT ==================================
/*public Task<PublicModels.GciInitSlotResult> InitOneMeterFromExternAsync(
int slot,
ConfigSource cfg,
PasswordSource pwd,
PortConfig? req,
PortConfig? str,
CancellationToken token = default)
{
return GetWorker(slot).RunAsync(() => InitOneMeterFromExtern(slot, cfg, pwd, req, str), token);
}
public PublicModels.GciInitSlotResult InitOneMeterFromExtern(
int slot,
ConfigSource cfg,
PasswordSource pwd,
PortConfig? req,
PortConfig? str)
{
const string operation = nameof(InitOneMeterFromExtern);
try
{
LogInfo(operation,
$"Start. Slot={slot}, GciConfigSource={cfg}, PasswordSource={pwd}, " +
$"RequestPort={(req.HasValue ? req.Value.PortName.ToString() : "<empty>")}, " +
$"StreamingPort={(str.HasValue ? str.Value.PortName.ToString() : "<empty>")}");
var meter = GetMeter(slot);
bool created = false;
if (meter == null)
{
meter = new GenesisMeter();
created = true;
}
meter.useConfigSource = cfg;
meter.usePasswordSource = pwd;
//meter.SetupFromExternConfig(slot, req, str, true);
meter.SetupGenesisMeter(slot, req, str, true);
if (created)
_meterBatch.AddMeter(meter);
//SetSlotSelected(slot, true);
LogInfo(operation,
$"Success. Slot={slot}, Created={created}, MeterBatchCount={_meterBatch.ListOfMeters.Count}");
return new PublicModels.GciInitSlotResult
{
Success = true,
SlotId = slot,
Message = created ? "Slot created." : "Slot updated."
};
}
catch (Exception ex)
{
LogError(operation, ex);
return new PublicModels.GciInitSlotResult
{
Success = false,
SlotId = slot,
Message = ex.Message
};
}
}*/
public Task<PublicModels.GciInitSlotResult> InitSlotAsync(
int slot,
ConfigSource cfg,
@ -554,15 +483,65 @@ namespace GenesisCordonelInterface.API
}
}
public Task<PublicModels.GciCleanSlotsResult> CleanSlotsAsync(
CancellationToken token = default)
public Task<PublicModels.GciCleanSlotResult> CleanSlotAsync(
int slot,
CancellationToken token = default)
{
return Task.Run(() => CleanSlots(), token);
return Task.Run(() => CleanSlot(slot), token);
}
public PublicModels.GciCleanSlotsResult CleanSlots()
public PublicModels.GciCleanSlotResult CleanSlot(int slot)
{
const string operation = nameof(CleanSlots);
const string operation = nameof(CleanSlot);
try
{
LogInfo(operation, string.Format("Start. Slot={0}", slot));
var meter = GetMeter(slot);
if (meter != null)
{
meter.DisposeMeter();
_meterBatch.ListOfMeters.Remove(meter);
}
ApiWorker worker;
if (_workers.TryRemove(slot, out worker))
{
worker.Dispose();
}
return new PublicModels.GciCleanSlotResult
{
SlotId = slot,
Success = true,
Message = string.Format("Slot {0} cleaned.", slot)
};
}
catch (Exception ex)
{
LogError(operation, ex);
return new PublicModels.GciCleanSlotResult
{
SlotId = slot,
Success = false,
Message = ex.Message
};
}
}
public Task<PublicModels.GciCleanAllSlotsResult> CleanAllSlotsAsync(
CancellationToken token = default)
{
return Task.Run(() => CleanAllSlots(), token);
}
public PublicModels.GciCleanAllSlotsResult CleanAllSlots()
{
const string operation = nameof(CleanAllSlots);
try
{
@ -585,7 +564,7 @@ namespace GenesisCordonelInterface.API
}
}
return new PublicModels.GciCleanSlotsResult
return new PublicModels.GciCleanAllSlotsResult
{
Success = true,
Message = "Slots cleaned."
@ -595,7 +574,7 @@ namespace GenesisCordonelInterface.API
{
LogError(operation, ex);
return new PublicModels.GciCleanSlotsResult
return new PublicModels.GciCleanAllSlotsResult
{
Success = false,
Message = ex.Message
@ -905,8 +884,8 @@ namespace GenesisCordonelInterface.API
if (meter.IsLoggedOn)
meter.Logout();
//meter.DisposeMeter();
meter.SoftDispose();
meter.DisposeMeter();
//meter.SoftDispose();
LogInfo(operation, $"Success. Slot={slot}");

View File

@ -27,7 +27,7 @@ namespace GenesisCordonelInterface.API
public PortDetectionResult DetectStreamingPort(int slot)
{
var result = _innerMeterAPI.DetectStreamingPort(slot);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
@ -36,14 +36,14 @@ namespace GenesisCordonelInterface.API
CancellationToken token = default(CancellationToken))
{
var result = await _innerMeterAPI.DetectStreamingPortAsync(slot, token);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
public PortDetectionResult DetectRequestPort(int slot)
{
var result = _innerMeterAPI.DetectRequestPort(slot);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
@ -52,7 +52,7 @@ namespace GenesisCordonelInterface.API
CancellationToken token = default(CancellationToken))
{
var result = await _innerMeterAPI.DetectRequestPortAsync(slot, token);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
@ -60,23 +60,6 @@ namespace GenesisCordonelInterface.API
#region ================================== INIT ==================================
/*public async Task<GciInitSlotResult> InitSlotAsync(GciInitSlotRequest request, CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var result = await _innerMeterAPI.InitOneMeterFromExternAsync(
request.SlotId,
ModelsMapping.MapConfigSource(request.ConfigSource),
ModelsMapping.MapPasswordSource(request.PasswordSource),
ModelsMapping.MapPort(request.RequestPort),
ModelsMapping.MapPort(request.StreamingPort),
token);
RaiseMeterBatchStatusChanged();
return result;
}*/
public async Task<GciInitSlotResult> InitSlotAsync(
GciInitSlotRequest request,
CancellationToken token = default)
@ -92,7 +75,7 @@ namespace GenesisCordonelInterface.API
ModelsMapping.MapPort(request.StreamingPort),
token);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
@ -112,7 +95,7 @@ namespace GenesisCordonelInterface.API
ModelsMapping.MapPort(request.StreamingPort),
token);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
@ -137,12 +120,26 @@ namespace GenesisCordonelInterface.API
return result;
}
public async Task<GciCleanSlotsResult> CleanSlotsAsync(
public async Task<GciCleanSlotResult> CleanSlotAsync(
int slot,
CancellationToken token = default)
{
var result = await _innerMeterAPI.CleanSlotsAsync(token);
if (slot <= 0)
throw new ArgumentException("Invalid slot id.", nameof(slot));
RaiseMeterBatchStatusChanged();
var result = await _innerMeterAPI.CleanSlotAsync(slot, token);
//RaiseMeterBatchStatusChanged();
return result;
}
public async Task<GciCleanAllSlotsResult> CleanAllSlotsAsync(
CancellationToken token = default)
{
var result = await _innerMeterAPI.CleanAllSlotsAsync(token);
//RaiseMeterBatchStatusChanged();
return result;
}
@ -186,7 +183,7 @@ namespace GenesisCordonelInterface.API
{
GciConnectResult result = await _innerMeterAPI.ConnectOneSlotAsync(slot, token);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
@ -200,7 +197,7 @@ namespace GenesisCordonelInterface.API
var result = await _innerMeterAPI.DisconnectAsync(slot, token);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
@ -260,7 +257,7 @@ namespace GenesisCordonelInterface.API
refreshSystemState,
token);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
@ -278,21 +275,21 @@ namespace GenesisCordonelInterface.API
storeToDevice,
refreshSystemState);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
public async Task<GciSetPasswordResult> SetMeterPasswordAsync(int slot, string password)
{
var result = await _innerMeterAPI.SetMeterPasswordAsync(slot, password);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}
public GciSetPasswordResult SetMeterPassword(int slot, string password)
{
var result = _innerMeterAPI.SetMeterPassword(slot, password);
RaiseMeterBatchStatusChanged();
//RaiseMeterBatchStatusChanged();
return result;
}

View File

@ -302,7 +302,7 @@ namespace GenesisCordonelInterface.API
}
}
public class GciCleanSlotsResult
public class GciCleanAllSlotsResult
{
public bool Success { get; set; }
public string Message { get; set; }
@ -315,6 +315,21 @@ namespace GenesisCordonelInterface.API
Message);
}
}
public class GciCleanSlotResult
{
public int SlotId { get; set; }
public bool Success { get; set; }
public string Message { get; set; }
public override string ToString()
{
return string.Format(
"SlotId={0}, Success={1}, Message={2}",
SlotId,
Success,
Message);
}
}
public class GciGetPcbIdResult
{

View File

@ -413,26 +413,53 @@ namespace TBF.Rig.BridgeComponents.GciBridge
return result;
}
/// <summary>
/// Clears one initialized GCI slot and related GCI worker state.
///
/// Trace:
/// GciBridge.CleanSlotAsync()
/// -> InterfaceOutsideToGCI.CleanSlotAsync()
/// -> InterfaceGCIToLaatzen.CleanSlotAsync()
/// -> selected slot cleanup
/// -> worker cleanup
/// </summary>
/// <param name="slot">GCI slot id.</param>
/// <returns>Cleanup operation result.</returns>
public async Task<GciPublicModels.GciCleanSlotResult> CleanSlotAsync(int slot)
{
EnsureExternalInterface();
if (slot <= 0)
throw new ArgumentException("Invalid slot id.", nameof(slot));
GciPublicModels.GciCleanSlotResult result =
await gciExternalInterface.CleanSlotAsync(slot);
log.InfoFormat("{0}: CleanSlotAsync invoked. Slot={1}, Result={2}", Name, slot, result);
return result;
}
/// <summary>
/// Clears all initialized GCI slots and related GCI worker state.
///
/// Trace:
/// GciBridge.CleanSlotsAsync()
/// -> InterfaceOutsideToGCI.CleanSlotsAsync()
/// -> InterfaceGCIToLaatzen.CleanSlotsAsync()
/// GciBridge.CleanAllSlotsAsync()
/// -> InterfaceOutsideToGCI.CleanAllSlotsAsync()
/// -> InterfaceGCIToLaatzen.CleanAllSlotsAsync()
/// -> MeterBatch cleanup
/// -> selected slot cleanup
/// -> worker cleanup
/// </summary>
/// <returns>Cleanup operation result.</returns>
public async Task<GciPublicModels.GciCleanSlotsResult> CleanSlotsAsync()
public async Task<GciPublicModels.GciCleanAllSlotsResult> CleanAllSlotsAsync()
{
EnsureExternalInterface();
GciPublicModels.GciCleanSlotsResult result =
await gciExternalInterface.CleanSlotsAsync();
GciPublicModels.GciCleanAllSlotsResult result =
await gciExternalInterface.CleanAllSlotsAsync();
log.InfoFormat("{0}: CleanSlotsAsync invoked.", Name);
log.InfoFormat("{0}: CleanAllSlotsAsync invoked.", Name);
return result;
}

View File

@ -370,6 +370,11 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug
_gridManager.AddEmptySlotRow();
}
public bool RemoveSlotRow(int slotId)
{
return _gridManager.RemoveSlot(slotId);
}
public List<GenesisCordonelInterface.API.PublicModels.MeterBatchDebugStatus> GetGridData()
{
return _gridManager.GetGridData();

View File

@ -365,6 +365,35 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Grid
return "";
}
public bool RemoveSlot(int slotId)
{
grid.SuspendLayout();
try
{
foreach (DataGridViewRow row in grid.Rows)
{
if (row.IsNewRow)
continue;
if (row.Cells["Slot"].Value == null)
continue;
if (Convert.ToInt32(row.Cells["Slot"].Value) == slotId)
{
grid.Rows.Remove(row);
return true;
}
}
return false;
}
finally
{
grid.ResumeLayout();
}
}
private string MapRequestPortTypeBack(string fullType)
{
return NormalizeRequestPortType(fullType);

View File

@ -78,7 +78,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
{
await ExecuteApiActionAsync(async () =>
{
await _gciApi.CleanSlotsAsync();
await _gciApi.CleanAllSlotsAsync();
_gridManager.ClearSlots();
});

View File

@ -9,7 +9,7 @@
private System.Windows.Forms.Button btnInitSlot;
private System.Windows.Forms.Button btnUpdateSlot;
private System.Windows.Forms.Button btnGetSlot;
private System.Windows.Forms.Button btnCleanSlots;
private System.Windows.Forms.Button btnCleanAllSlots;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.TextBox txtLog;
@ -35,14 +35,15 @@
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.btnInitSlot = new System.Windows.Forms.Button();
this.btnUpdateSlot = new System.Windows.Forms.Button();
this.btnGetSlot = new System.Windows.Forms.Button();
this.btnCleanSlots = new System.Windows.Forms.Button();
this.btnCleanAllSlots = new System.Windows.Forms.Button();
this.btnCleanSlot = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.txtLog = new System.Windows.Forms.TextBox();
this.btnLogin = new System.Windows.Forms.Button();
this.grpSlots.SuspendLayout();
this.SuspendLayout();
//
@ -63,7 +64,8 @@
this.grpSlots.Controls.Add(this.btnInitSlot);
this.grpSlots.Controls.Add(this.btnUpdateSlot);
this.grpSlots.Controls.Add(this.btnGetSlot);
this.grpSlots.Controls.Add(this.btnCleanSlots);
this.grpSlots.Controls.Add(this.btnCleanAllSlots);
this.grpSlots.Controls.Add(this.btnCleanSlot);
this.grpSlots.Location = new System.Drawing.Point(10, 10);
this.grpSlots.Name = "grpSlots";
this.grpSlots.Size = new System.Drawing.Size(689, 304);
@ -149,15 +151,6 @@
this.btnConnect.Text = "Connect(slot)";
this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
//
// 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)";
this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
//
// btnDisconnect
//
this.btnDisconnect.Location = new System.Drawing.Point(15, 191);
@ -167,6 +160,15 @@
this.btnDisconnect.Text = "Disconnect(slot)";
this.btnDisconnect.Click += new System.EventHandler(this.btnDisconnect_Click);
//
// 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)";
this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
//
// btnGetPcbId
//
this.btnGetPcbId.Location = new System.Drawing.Point(15, 125);
@ -203,14 +205,23 @@
this.btnGetSlot.Text = "GetSlot(slot)";
this.btnGetSlot.Click += new System.EventHandler(this.btnGetSlot_Click);
//
// btnCleanSlots
// btnCleanAllSlots
//
this.btnCleanSlots.Location = new System.Drawing.Point(15, 91);
this.btnCleanSlots.Name = "btnCleanSlots";
this.btnCleanSlots.Size = new System.Drawing.Size(150, 28);
this.btnCleanSlots.TabIndex = 2;
this.btnCleanSlots.Text = "CleanSlots()";
this.btnCleanSlots.Click += new System.EventHandler(this.btnCleanSlots_Click);
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.btnCleanAllSlots.Click += new System.EventHandler(this.btnCleanAllSlots_Click);
//
// btnCleanSlot
//
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.btnCleanSlot.Click += new System.EventHandler(this.btnCleanSlot_Click);
//
// btnCancel
//
@ -259,5 +270,6 @@
private System.Windows.Forms.ComboBox writeRegisterNameComboBox;
private System.Windows.Forms.ComboBox readRegisterNameComboBox;
private System.Windows.Forms.Button btnLogin;
private System.Windows.Forms.Button btnCleanSlot;
}
}

View File

@ -57,8 +57,14 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
return slots;
}
private void RefreshGrid()
private void RefreshGrid(int? removedSlot = null)
{
if (removedSlot.HasValue)
{
_mainView?._gciApi.SetSlotSelected(removedSlot.Value, false);
_mainView?._batchPanel?.RemoveSlotRow(removedSlot.Value);
}
if (_bridge?.gciExternalInterface != null)
_bridge.gciExternalInterface.RaiseMeterBatchStatusChanged();
}
@ -152,13 +158,28 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
});
}
private void btnCleanSlots_Click(object sender, EventArgs e)
private void btnCleanSlot_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
{
var result = await _bridge.CleanSlotsAsync();
foreach (var slot in GetSelectedSlots())
{
var result = await _bridge.CleanSlotAsync(slot.Slot);
LogResult("CleanSlotsAsync", result);
LogResult($"CleanSlotAsync slot {slot.Slot}", result);
RefreshGrid(slot.Slot);
}
});
}
private void btnCleanAllSlots_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
{
var result = await _bridge.CleanAllSlotsAsync();
LogResult("CleanAllSlotsAsync", result);
RefreshGrid();
});
@ -224,81 +245,6 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
});
}
private void btnCancel_Click(object sender, EventArgs e)
{
_cts?.Cancel();
Log("Cancel requested.");
}
private async void ExecuteAsync(Func<CancellationToken, Task> action)
{
try
{
SetBusy(true);
_cts = new CancellationTokenSource();
await action(_cts.Token);
}
catch (OperationCanceledException)
{
Log("Operation canceled.");
}
catch (Exception ex)
{
Log("ERROR: " + ex);
MessageBox.Show(
ex.Message,
"GciBridge API call failed",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
finally
{
_cts?.Dispose();
_cts = null;
SetBusy(false);
}
}
private void SetBusy(bool busy)
{
Cursor = busy ? Cursors.WaitCursor : Cursors.Default;
btnInitSlot.Enabled = !busy;
btnUpdateSlot.Enabled = !busy;
btnGetSlot.Enabled = !busy;
btnCleanSlots.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;
btnCancel.Enabled = busy;
}
private void LogResult(string methodName, object result)
{
Log(methodName + " result:");
Log(result == null ? "<null>" : result.ToString());
}
private void Log(string message)
{
txtLog.AppendText(
DateTime.Now.ToString("HH:mm:ss.fff") +
" " +
message +
Environment.NewLine);
}
private void readRegisterButton_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
@ -363,6 +309,84 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
});
}
private void btnCancel_Click(object sender, EventArgs e)
{
_cts?.Cancel();
Log("Cancel requested.");
}
private async void ExecuteAsync(Func<CancellationToken, Task> action)
{
try
{
SetBusy(true);
_cts = new CancellationTokenSource();
await action(_cts.Token);
}
catch (OperationCanceledException)
{
Log("Operation canceled.");
}
catch (Exception ex)
{
Log("ERROR: " + ex);
MessageBox.Show(
ex.Message,
"GciBridge API call failed",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
finally
{
_cts?.Dispose();
_cts = null;
SetBusy(false);
}
}
private void SetBusy(bool busy)
{
Cursor = busy ? Cursors.WaitCursor : Cursors.Default;
btnInitSlot.Enabled = !busy;
btnUpdateSlot.Enabled = !busy;
btnGetSlot.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;
btnCancel.Enabled = busy;
}
private void LogResult(string methodName, object result)
{
Log(methodName + " result:");
Log(result == null ? "<null>" : result.ToString());
}
private void Log(string message)
{
txtLog.AppendText(
DateTime.Now.ToString("HH:mm:ss.fff") +
" " +
message +
Environment.NewLine);
}
private void LoadRegisterComboBoxes()
{
var registers = _bridge.GetAllRegisterNames();