kick 2 - prva dobra s dialogom testov
This commit is contained in:
@@ -0,0 +1,355 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
using GenesisCordonelInterface.Core.Threading;
|
||||
using GciPublicModels = GenesisCordonelInterface.API.PublicModels;
|
||||
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
{
|
||||
public partial class GciBridge
|
||||
{
|
||||
public bool IsSimulation { get { return DebugLevel == DebugMode.Simulate; } }
|
||||
public GciSimulationSettings Simulation { get; } = new GciSimulationSettings();
|
||||
private readonly AsyncLocal<GciSimulationProfile> simulationOverride = new AsyncLocal<GciSimulationProfile>();
|
||||
|
||||
// Scoped to this execution context, including awaited calls; does not change defaults.
|
||||
public IDisposable BeginSimulation(GciSimulationProfile profile)
|
||||
{
|
||||
if (!IsSimulation) throw new InvalidOperationException("GCI Bridge must be in Simulate mode.");
|
||||
if (profile == null) throw new ArgumentNullException("profile");
|
||||
var previous = simulationOverride.Value;
|
||||
simulationOverride.Value = profile.Snapshot();
|
||||
return new SimulationScope(() => simulationOverride.Value = previous);
|
||||
}
|
||||
|
||||
private sealed class SimulationScope : IDisposable
|
||||
{
|
||||
private Action restore;
|
||||
public SimulationScope(Action restore) { this.restore = restore; }
|
||||
public void Dispose() { var action = restore; restore = null; if (action != null) action(); }
|
||||
}
|
||||
private readonly object simulationLock = new object();
|
||||
private readonly Dictionary<int, GciPublicModels.GciSlotInfo> simulationSlots = new Dictionary<int, GciPublicModels.GciSlotInfo>();
|
||||
private readonly Dictionary<int, GciPublicModels.WorkerDebugStatus> simulationWorkers = new Dictionary<int, GciPublicModels.WorkerDebugStatus>();
|
||||
private readonly ConcurrentDictionary<int, SemaphoreSlim> simulationGates = new ConcurrentDictionary<int, SemaphoreSlim>();
|
||||
private readonly HashSet<int> simulationSelection = new HashSet<int>();
|
||||
private static readonly NLog.Logger simulationLogger = NLog.LogManager.GetLogger("GenesisCordonelInterface.GciBridge.Simulation");
|
||||
public event Action<int, string> SimulationLog;
|
||||
|
||||
private void LogSimulation(int slot, string operation, string message)
|
||||
{
|
||||
var entry = new NLog.LogEventInfo(NLog.LogLevel.Info, simulationLogger.Name, string.Format("[SIMULATION] Bridge={0}, Slot={1}, Operation={2}, {3}", Name, slot, operation, message));
|
||||
entry.Properties["Slot"] = slot;
|
||||
entry.Properties["Operation"] = operation;
|
||||
entry.Properties["Bridge"] = Name;
|
||||
simulationLogger.Log(entry);
|
||||
var handlers = SimulationLog;
|
||||
if (handlers == null) return;
|
||||
int[] targets;
|
||||
lock (simulationLock) targets = slot > 0 ? new[] { slot } : simulationSelection.ToArray();
|
||||
foreach (int target in targets)
|
||||
{
|
||||
foreach (Action<int, string> handler in handlers.GetInvocationList())
|
||||
{
|
||||
try { handler(target, entry.Message); }
|
||||
catch (Exception ex) { log.Warn("Simulation diagnostic subscriber failed.", ex); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<T> SimulateAsync<T>(string operation, int slot, CancellationToken token, Func<GciSimulationProfile, T> create, string register = null)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
var profile = Simulation.Get(operation, register);
|
||||
var dynamicProfile = simulationOverride.Value;
|
||||
if (dynamicProfile != null)
|
||||
{
|
||||
profile.DurationMs = dynamicProfile.DurationMs;
|
||||
profile.Success = dynamicProfile.Success;
|
||||
profile.ErrorMessage = dynamicProfile.ErrorMessage;
|
||||
}
|
||||
var gate = simulationGates.GetOrAdd(slot, _ => new SemaphoreSlim(1, 1));
|
||||
lock (simulationLock)
|
||||
{
|
||||
if (!simulationWorkers.ContainsKey(slot)) simulationWorkers[slot] = new GciPublicModels.WorkerDebugStatus { Slot = slot, Name = slot == 0 ? "Simulated batch" : "Simulated slot " + slot };
|
||||
simulationWorkers[slot].QueueLength++;
|
||||
}
|
||||
bool acquired = false;
|
||||
try
|
||||
{
|
||||
await gate.WaitAsync(token).ConfigureAwait(false);
|
||||
acquired = true;
|
||||
lock (simulationLock)
|
||||
{
|
||||
var worker = simulationWorkers[slot];
|
||||
worker.QueueLength--;
|
||||
worker.IsBusy = true;
|
||||
worker.CurrentOperation = operation;
|
||||
worker.LastError = null;
|
||||
worker.LastActivity = DateTime.Now;
|
||||
}
|
||||
LogSimulation(slot, operation, "START, DurationMs=" + profile.DurationMs);
|
||||
await Task.Delay(profile.DurationMs, token).ConfigureAwait(false);
|
||||
token.ThrowIfCancellationRequested();
|
||||
T result;
|
||||
lock (simulationLock)
|
||||
{
|
||||
result = create(profile);
|
||||
simulationWorkers[slot].LastError = profile.Success ? null : profile.ErrorMessage;
|
||||
}
|
||||
LogSimulation(slot, operation, "FINISH, Success=" + profile.Success + ", ErrorMessage=" + profile.ErrorMessage);
|
||||
return result;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
LogSimulation(slot, operation, "CANCELLED");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (simulationLock)
|
||||
{
|
||||
var worker = simulationWorkers[slot];
|
||||
if (!acquired) worker.QueueLength--;
|
||||
else
|
||||
{
|
||||
worker.IsBusy = false;
|
||||
worker.CurrentOperation = null;
|
||||
worker.LastActivity = DateTime.Now;
|
||||
}
|
||||
}
|
||||
if (acquired) gate.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateSimulationSlot(int slot)
|
||||
{
|
||||
if (slot <= 0) throw new ArgumentOutOfRangeException("slot");
|
||||
}
|
||||
|
||||
private string SimulationPcb(int slot, GciSimulationProfile profile)
|
||||
{
|
||||
return profile.PcbId ?? (900000000L + slot).ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
// Successful canned operations may create a logical slot; no COM device is created.
|
||||
private GciPublicModels.GciSlotInfo SimSlot(int slot, GciSimulationProfile profile)
|
||||
{
|
||||
GciPublicModels.GciSlotInfo state;
|
||||
if (!simulationSlots.TryGetValue(slot, out state))
|
||||
{
|
||||
state = new GciPublicModels.GciSlotInfo { SlotId = slot, Exists = true, Success = true, PcbId = SimulationPcb(slot, profile) };
|
||||
simulationSlots.Add(slot, state);
|
||||
simulationSelection.Add(slot);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
private static GciPublicModels.GciPortConfig CopyPort(GciPublicModels.GciPortConfig port)
|
||||
{
|
||||
return port == null ? null : new GciPublicModels.GciPortConfig { PortName = port.PortName, Type = port.Type };
|
||||
}
|
||||
|
||||
private static GciPublicModels.GciSlotInfo CopySlot(GciPublicModels.GciSlotInfo s)
|
||||
{
|
||||
return new GciPublicModels.GciSlotInfo { SlotId = s.SlotId, Exists = s.Exists, Success = s.Success, IsConnected = s.IsConnected, IsLoggedOn = s.IsLoggedOn, Message = s.Message, PcbId = s.PcbId, Password = s.Password, ConfigSource = s.ConfigSource, PasswordSource = s.PasswordSource, RequestPort = CopyPort(s.RequestPort), StreamingPort = CopyPort(s.StreamingPort) };
|
||||
}
|
||||
|
||||
private Task<GciPublicModels.GciInitSlotResult> SimInit(string operation, GciPublicModels.GciInitSlotRequest request, CancellationToken token)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException("request");
|
||||
ValidateSimulationSlot(request.SlotId);
|
||||
return SimulateAsync(operation, request.SlotId, token, p =>
|
||||
{
|
||||
bool existed = simulationSlots.ContainsKey(request.SlotId);
|
||||
if (p.Success)
|
||||
{
|
||||
var s = SimSlot(request.SlotId, p);
|
||||
s.RequestPort = CopyPort(request.RequestPort);
|
||||
s.StreamingPort = CopyPort(request.StreamingPort);
|
||||
s.Password = request.Password;
|
||||
s.ConfigSource = request.ConfigSource;
|
||||
s.PasswordSource = request.PasswordSource;
|
||||
}
|
||||
return new GciPublicModels.GciInitSlotResult { SlotId = request.SlotId, Success = p.Success, Message = p.ErrorMessage, PcbId = p.Success ? SimulationPcb(request.SlotId, p) : null, Created = p.Success && !existed, Updated = p.Success && existed, AlreadyExists = existed };
|
||||
});
|
||||
}
|
||||
|
||||
private Task<GciPublicModels.PreAdjustmentProcessResult> SimPhase(string operation, int slot, CancellationToken token)
|
||||
{
|
||||
return SimulateAsync(operation, slot, token, p => new GciPublicModels.PreAdjustmentProcessResult { Success = p.Success, Slot = slot, ProcessName = operation, ErrorMessage = p.ErrorMessage });
|
||||
}
|
||||
|
||||
private int[] GetSimulatedPreadjustmentSlots()
|
||||
{
|
||||
lock (simulationLock)
|
||||
{
|
||||
// Slot 0 represented the old aggregate simulation. Preadjustment now reports
|
||||
// only real logical slot workers.
|
||||
GciPublicModels.WorkerDebugStatus batchWorker;
|
||||
if (simulationWorkers.TryGetValue(0, out batchWorker) && !batchWorker.IsBusy) simulationWorkers.Remove(0);
|
||||
return simulationSelection.OrderBy(slot => slot).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<GciPublicModels.PreAdjustmentProcessResult> SimBatchPhase(string operation, CancellationToken token)
|
||||
{
|
||||
int[] slots = GetSimulatedPreadjustmentSlots();
|
||||
if (slots.Length == 0)
|
||||
return new GciPublicModels.PreAdjustmentProcessResult { Success = false, Slot = -1, ProcessName = operation, ErrorMessage = "No simulated preadjustment slots are selected." };
|
||||
|
||||
// Start every slot operation before awaiting the aggregate. SimulateAsync supplies
|
||||
// an independent worker and serialization gate for each slot.
|
||||
Task<GciPublicModels.PreAdjustmentProcessResult>[] tasks = slots.Select(slot => SimPhase(operation, slot, token)).ToArray();
|
||||
GciPublicModels.PreAdjustmentProcessResult[] results = await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
GciPublicModels.PreAdjustmentProcessResult[] failed = results.Where(result => !result.Success).ToArray();
|
||||
return new GciPublicModels.PreAdjustmentProcessResult
|
||||
{
|
||||
Success = failed.Length == 0,
|
||||
Slot = -1,
|
||||
ProcessName = operation,
|
||||
ErrorMessage = failed.Length == 0 ? null : string.Join("; ", failed.Select(result => "Slot " + result.Slot + ": " + result.ErrorMessage))
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<GciPublicModels.PreAdjustmentProcessResult> SimInitializeBatch(string operation, IEnumerable<int> selectedSlots, CancellationToken token)
|
||||
{
|
||||
int[] slots = selectedSlots.Distinct().OrderBy(slot => slot).ToArray();
|
||||
if (slots.Length == 0)
|
||||
return new GciPublicModels.PreAdjustmentProcessResult { Success = false, Slot = -1, ProcessName = operation, ErrorMessage = "No simulated preadjustment slots were supplied." };
|
||||
|
||||
lock (simulationLock)
|
||||
{
|
||||
GciPublicModels.WorkerDebugStatus batchWorker;
|
||||
if (simulationWorkers.TryGetValue(0, out batchWorker) && !batchWorker.IsBusy) simulationWorkers.Remove(0);
|
||||
simulationSelection.Clear();
|
||||
foreach (int slot in slots)
|
||||
{
|
||||
// Keep failed simulated slots visible in diagnostics until GenesisCommunication
|
||||
// records and excludes them.
|
||||
SimSlot(slot, Simulation.Get(operation, null));
|
||||
simulationSelection.Add(slot);
|
||||
}
|
||||
}
|
||||
|
||||
Task<GciPublicModels.PreAdjustmentProcessResult>[] tasks = slots.Select(slot => SimPhase(operation, slot, token)).ToArray();
|
||||
GciPublicModels.PreAdjustmentProcessResult[] results = await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
GciPublicModels.PreAdjustmentProcessResult[] failed = results.Where(result => !result.Success).ToArray();
|
||||
return new GciPublicModels.PreAdjustmentProcessResult
|
||||
{
|
||||
Success = failed.Length == 0,
|
||||
Slot = -1,
|
||||
ProcessName = operation,
|
||||
ErrorMessage = failed.Length == 0 ? null : string.Join("; ", failed.Select(result => "Slot " + result.Slot + ": " + result.ErrorMessage))
|
||||
};
|
||||
}
|
||||
|
||||
// Aggregate simulation for UI-only workflows (Q3, preparation check, hold).
|
||||
// This deliberately does not claim to execute their individual register steps.
|
||||
public Task<GciPublicModels.PreAdjustmentProcessResult> SimulateMeterActivityAsync(string activity, int slot, CancellationToken token = default(CancellationToken))
|
||||
{
|
||||
if (!IsSimulation) throw new InvalidOperationException("GCI Bridge must be in Simulate mode.");
|
||||
ValidateSimulationSlot(slot);
|
||||
return SimulateAsync("MeterActivity", slot, token, p =>
|
||||
{
|
||||
if (p.Success) SimSlot(slot, p);
|
||||
return new GciPublicModels.PreAdjustmentProcessResult { Success = p.Success, Slot = slot, ProcessName = activity, ErrorMessage = p.ErrorMessage };
|
||||
});
|
||||
}
|
||||
|
||||
private Task<Interfaces.PublicModels.GciFullLoginResult> SimFullLogin(int slot, CancellationToken token)
|
||||
{
|
||||
// One independently configurable canned workflow; does not also delay every child.
|
||||
return SimulateAsync("ConnectFullPassLoginWithRetryAsync", slot, token, p =>
|
||||
{
|
||||
string pcb = p.Success ? SimulationPcb(slot, p) : null;
|
||||
if (p.Success)
|
||||
{
|
||||
var s = SimSlot(slot, p);
|
||||
s.IsConnected = true;
|
||||
s.IsLoggedOn = true;
|
||||
s.Password = p.Password;
|
||||
}
|
||||
return new Interfaces.PublicModels.GciFullLoginResult
|
||||
{
|
||||
SlotId = slot, Success = p.Success, Message = p.ErrorMessage,
|
||||
ConnectResult = SimRetry(new GciPublicModels.GciConnectResult { SlotId = slot, Success = p.Success, IsConnected = p.Success, PcbId = pcb, Message = p.ErrorMessage }, p),
|
||||
PcbResult = p.Success ? SimRetry(new GciPublicModels.GciGetPcbIdResult { SlotId = slot, Success = true, PcbId = pcb }, p) : null,
|
||||
PasswordResult = p.Success ? SimRetry(new Interfaces.PublicModels.UdsPasswordResult { Success = true, PcbId = pcb, Password = p.Password }, p) : null,
|
||||
SetPasswordResult = p.Success ? SimRetry(new GciPublicModels.GciSetPasswordResult { SlotId = slot, Success = true, Password = p.Password }, p) : null,
|
||||
LoginResult = p.Success ? SimRetry(new GciPublicModels.GciLoginResult { SlotId = slot, Success = true, IsLoggedOn = true, PcbId = pcb }, p) : null
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private static RetryResult<T> SimRetry<T>(T result, GciSimulationProfile p)
|
||||
{
|
||||
return new RetryResult<T> { Result = result, Success = p.Success, Attempts = 1, Duration = TimeSpan.Zero, TimedOut = false };
|
||||
}
|
||||
|
||||
private async Task<GciPublicModels.PreadjustmentDetectResult> SimDetect(IEnumerable<GciPublicModels.MeterBatchDebugStatus> slots, CancellationToken token)
|
||||
{
|
||||
if (slots == null) throw new ArgumentNullException("slots");
|
||||
int[] selected = slots.Where(status => status.Selected).Select(status => status.Slot).Distinct().OrderBy(slot => slot).ToArray();
|
||||
foreach (int slot in selected) ValidateSimulationSlot(slot);
|
||||
if (selected.Length == 0) return new GciPublicModels.PreadjustmentDetectResult { Success = false, ErrorMessage = "No simulated slots are selected.", DetectedMeterCount = 0 };
|
||||
|
||||
lock (simulationLock)
|
||||
{
|
||||
GciPublicModels.WorkerDebugStatus batchWorker;
|
||||
if (simulationWorkers.TryGetValue(0, out batchWorker) && !batchWorker.IsBusy) simulationWorkers.Remove(0);
|
||||
simulationSelection.Clear();
|
||||
foreach (int slot in selected)
|
||||
{
|
||||
SimSlot(slot, Simulation.Get("PreAdjustment_Detect", null));
|
||||
simulationSelection.Add(slot);
|
||||
}
|
||||
}
|
||||
|
||||
Task<GciPublicModels.PreAdjustmentProcessResult>[] tasks = selected.Select(slot => SimPhase("PreAdjustment_Detect", slot, token)).ToArray();
|
||||
GciPublicModels.PreAdjustmentProcessResult[] results = await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
GciPublicModels.PreAdjustmentProcessResult[] failed = results.Where(result => !result.Success).ToArray();
|
||||
return new GciPublicModels.PreadjustmentDetectResult
|
||||
{
|
||||
Success = failed.Length == 0,
|
||||
ErrorMessage = failed.Length == 0 ? null : string.Join("; ", failed.Select(result => "Slot " + result.Slot + ": " + result.ErrorMessage)),
|
||||
DetectedMeterCount = results.Count(result => result.Success)
|
||||
};
|
||||
}
|
||||
|
||||
// Exclusion changes both the overview selection and the process control.
|
||||
public void ExcludePreadjustmentSlot(int slot)
|
||||
{
|
||||
if (IsSimulation) { lock (simulationLock) simulationSelection.Remove(slot); return; }
|
||||
EnsureExternalInterface();
|
||||
gciExternalInterface.SetSlotSelected(slot, false);
|
||||
var controls = gciExternalInterface._innerMeterAPI._meterControls;
|
||||
if (controls == null) return;
|
||||
foreach (var control in controls.Where(c => c.Slot == slot))
|
||||
{
|
||||
control.SetChecked(false);
|
||||
control.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
public List<GciPublicModels.MeterBatchDebugStatus> GetMeterBatchDebugStatuses()
|
||||
{
|
||||
if (!IsSimulation) { EnsureExternalInterface(); return gciExternalInterface.GetMeterBatchDebugStatuses(); }
|
||||
lock (simulationLock)
|
||||
return simulationSlots.Values.OrderBy(s => s.SlotId).Select(s => new GciPublicModels.MeterBatchDebugStatus { Slot = s.SlotId, Selected = simulationSelection.Contains(s.SlotId), PcbId = s.PcbId, IsConnected = s.IsConnected, IsLoggedOn = s.IsLoggedOn, FwVersion = "SIM", RequestPort = s.RequestPort == null ? "" : s.RequestPort.PortName, RequestPortType = s.RequestPort == null ? "" : s.RequestPort.Type, StreamingPort = s.StreamingPort == null ? "" : s.StreamingPort.PortName }).ToList();
|
||||
}
|
||||
|
||||
public List<GciPublicModels.WorkerDebugStatus> GetWorkerDebugStatuses()
|
||||
{
|
||||
if (!IsSimulation) { EnsureExternalInterface(); return gciExternalInterface.GetWorkerDebugStatuses(); }
|
||||
lock (simulationLock)
|
||||
return simulationWorkers.Values.OrderBy(s => s.Slot).Select(s => new GciPublicModels.WorkerDebugStatus { Slot = s.Slot, Name = s.Name, QueueLength = s.QueueLength, IsBusy = s.IsBusy, CurrentOperation = s.CurrentOperation, LastActivity = s.LastActivity, LastError = s.LastError }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ using NHibernate.Mapping;
|
||||
/// Copyright (c) 2015-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -41,7 +42,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
/// TBF bridge component for integration with the sibling GCI project.
|
||||
/// The component can be linked to UniDataStorage reader and writer components.
|
||||
/// </summary>
|
||||
public class GciBridge : ComponentBase
|
||||
public partial class GciBridge : ComponentBase
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(GciBridge));
|
||||
|
||||
@@ -134,6 +135,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
if (IsSimulation) { log.InfoFormat("{0}: Simulation mode initialized; hardware initialization skipped.", Name); return; }
|
||||
if (gciBridgeCfg.EnableExternalAccess)
|
||||
{
|
||||
TryInitializeExternalInterface();
|
||||
@@ -218,6 +220,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
|
||||
public void ShowGciGui()
|
||||
{
|
||||
if (IsSimulation) { MessageBox.Show("Use GenesisCommunication diagnostics for simulated slots. The hardware GCI GUI is unavailable in Simulate mode.", "GCI simulation"); return; }
|
||||
if (!gciBridgeCfg.EnableGuiAccess) return;
|
||||
|
||||
if (gciGuiHostForm == null || gciGuiHostForm.IsDisposed)
|
||||
@@ -245,6 +248,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
|
||||
public void ShowGui()
|
||||
{
|
||||
if (IsSimulation) { MessageBox.Show("Use GenesisCommunication diagnostics for simulated slots. The hardware GCI GUI is unavailable in Simulate mode.", "GCI simulation"); return; }
|
||||
if (!gciBridgeCfg.EnableGuiAccess) return;
|
||||
|
||||
if (gciBridgeGuiForm == null || gciBridgeGuiForm.IsDisposed)
|
||||
@@ -310,6 +314,10 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
GciPublicModels.GciInitSlotRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return await SimInit(nameof(InitSlotAsync), request, token).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (request == null)
|
||||
@@ -391,6 +399,10 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
GciPublicModels.GciInitSlotRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return await SimInit(nameof(UpdateSlotAsync), request, token).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (request == null)
|
||||
@@ -469,6 +481,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slotId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slotId);
|
||||
|
||||
return await SimulateAsync(nameof(GetSlotAsync), slotId, token, p => { if (!p.Success) return new GciPublicModels.GciSlotInfo { SlotId = slotId, Success = false, Message = p.ErrorMessage }; var copy = CopySlot(SimSlot(slotId, p)); copy.Message = p.ErrorMessage; return copy; }).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (slotId <= 0)
|
||||
@@ -545,6 +563,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slot,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slot);
|
||||
|
||||
return await SimulateAsync(nameof(CleanSlotAsync), slot, token, p => { if (p.Success) { simulationSlots.Remove(slot); simulationSelection.Remove(slot); } return new GciPublicModels.GciCleanSlotResult { SlotId = slot, Success = p.Success, Message = p.ErrorMessage }; }).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (slot <= 0)
|
||||
@@ -621,6 +645,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
public async Task<GciPublicModels.GciCleanAllSlotsResult> CleanAllSlotsAsync(
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
|
||||
|
||||
return await SimulateAsync(nameof(CleanAllSlotsAsync), 0, token, p => { if (p.Success) { simulationSlots.Clear(); simulationSelection.Clear(); } return new GciPublicModels.GciCleanAllSlotsResult { Success = p.Success, Message = p.ErrorMessage }; }).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
GciPublicModels.GciCleanAllSlotsResult result =
|
||||
@@ -693,6 +723,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slotId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slotId);
|
||||
|
||||
return await SimulateAsync(nameof(GetPcbIdAsync), slotId, token, p => { if (p.Success) SimSlot(slotId, p).PcbId = SimulationPcb(slotId, p); return new GciPublicModels.GciGetPcbIdResult { SlotId = slotId, Success = p.Success, PcbId = p.Success ? SimulationPcb(slotId, p) : null, Message = p.ErrorMessage }; }).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (slotId <= 0)
|
||||
@@ -810,6 +846,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slot,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slot);
|
||||
|
||||
return await SimulateAsync(nameof(ConnectAsync), slot, token, p => { if (p.Success) SimSlot(slot, p).IsConnected = true; return new GciPublicModels.GciConnectResult { SlotId = slot, Success = p.Success, IsConnected = p.Success, PcbId = p.Success ? SimulationPcb(slot, p) : null, Message = p.ErrorMessage }; }).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (slot <= 0)
|
||||
@@ -842,6 +884,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slotId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slotId);
|
||||
|
||||
return await SimulateAsync(nameof(LoginAsync), slotId, token, p => { if (p.Success) { SimSlot(slotId, p).IsConnected = true; SimSlot(slotId, p).IsLoggedOn = true; } return new GciPublicModels.GciLoginResult { SlotId = slotId, Success = p.Success, IsLoggedOn = p.Success, PcbId = p.Success ? SimulationPcb(slotId, p) : null, Message = p.ErrorMessage }; }).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (slotId <= 0)
|
||||
@@ -913,6 +961,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slotId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slotId);
|
||||
|
||||
return await SimulateAsync(nameof(DisconnectAsync), slotId, token, p => { if (p.Success && simulationSlots.ContainsKey(slotId)) { simulationSlots[slotId].IsConnected = false; simulationSlots[slotId].IsLoggedOn = false; } return new GciPublicModels.GciDisconnectResult { SlotId = slotId, Success = p.Success, Message = p.ErrorMessage }; }).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (slotId <= 0)
|
||||
@@ -992,6 +1046,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
string password,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slotId);
|
||||
if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Password is empty.");
|
||||
return await SimulateAsync(nameof(SetPasswordAsync), slotId, token, p => { if (p.Success) SimSlot(slotId, p).Password = password; return new GciPublicModels.GciSetPasswordResult { SlotId = slotId, Success = p.Success, Password = p.Success ? password : null, Message = p.ErrorMessage }; }).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (slotId <= 0)
|
||||
@@ -1068,6 +1128,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
string registerName,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slotId);
|
||||
if (string.IsNullOrWhiteSpace(registerName)) throw new ArgumentException("Register name is empty.");
|
||||
return await SimulateAsync(nameof(ReadRegisterAsync), slotId, token, p => new GciPublicModels.RegisterReadResult { Success = p.Success, RegisterName = registerName, RawHex = p.Success ? p.RawHex : null, ErrorMessage = p.ErrorMessage }, registerName).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (slotId <= 0)
|
||||
@@ -1158,6 +1224,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
bool refreshSystemState = false,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slotId);
|
||||
if (string.IsNullOrWhiteSpace(registerName)) throw new ArgumentException("Register name is empty.");
|
||||
return await SimulateAsync(nameof(WriteRegisterAsync), slotId, token, p => new GciPublicModels.RegisterWriteResult { Success = p.Success, RegisterName = registerName, WrittenValue = value, StoreToDevice = storeToDevice, RefreshSystemState = refreshSystemState, ErrorMessage = p.ErrorMessage }, registerName).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (slotId <= 0)
|
||||
@@ -1261,6 +1333,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
string pcbId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
|
||||
if (string.IsNullOrWhiteSpace(pcbId)) throw new ArgumentException("PCB ID is empty.");
|
||||
return await SimulateAsync(nameof(GetPasswordAsync), 0, token, p => { return new UdsPasswordResult { Success = p.Success, PcbId = pcbId, Password = p.Success ? p.Password : null, Message = p.ErrorMessage }; }).ConfigureAwait(false);
|
||||
}
|
||||
EnsureReader();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(pcbId))
|
||||
@@ -1339,6 +1417,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int meterSize,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
|
||||
if (meterSize < 0) throw new ArgumentOutOfRangeException("meterSize");
|
||||
return await SimulateAsync(nameof(GetPreAdjustmentCalibrationParamsAsync), 0, token, p => { return new UdsPreAdjustmentCalibrationParamsResult { Success = p.Success, MeterSize = meterSize, CalibrationParams = p.Success ? new Dictionary<string, UInt32>(p.CalibrationParams) : null, Message = p.ErrorMessage }; }).ConfigureAwait(false);
|
||||
}
|
||||
EnsureReader();
|
||||
|
||||
if (meterSize < 0)
|
||||
@@ -1526,6 +1610,11 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
/// <returns>Complete workflow result including all retry statistics and operation results.</returns>
|
||||
public async Task<GciFullLoginResult> ConnectFullPassLoginWithRetryAsync(int slotId, CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slotId);
|
||||
return await SimFullLogin(slotId, token).ConfigureAwait(false);
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
EnsureReader();
|
||||
|
||||
@@ -1581,6 +1670,14 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
public PreAdjustmentInitializationResult Preadjustment_Initialization(
|
||||
ProcessProgress pp, List<MeterStateControl> mc)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
if (pp == null || mc == null) throw new ArgumentNullException(pp == null ? "pp" : "mc");
|
||||
var slots = mc.Where(m => m.IsEnabled).Select(m => m.Slot).Distinct().ToArray();
|
||||
foreach (int slot in slots) ValidateSimulationSlot(slot);
|
||||
GciPublicModels.PreAdjustmentProcessResult simulated = SimInitializeBatch(nameof(Preadjustment_Initialization), slots, CancellationToken.None).GetAwaiter().GetResult();
|
||||
return new PreAdjustmentInitializationResult { Success = simulated.Success, ErrorMessage = simulated.ErrorMessage, Slots = simulated.Success ? string.Join(",", slots) : "" };
|
||||
}
|
||||
const string operation = nameof(Preadjustment_Initialization);
|
||||
|
||||
try
|
||||
@@ -1627,6 +1724,10 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
IEnumerable<GciPublicModels.MeterBatchDebugStatus> selectedSlots,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return await SimDetect(selectedSlots, token).ConfigureAwait(false);
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_DetectAsync);
|
||||
|
||||
try
|
||||
@@ -1666,6 +1767,10 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
IEnumerable<GciPublicModels.MeterBatchDebugStatus> selectedSlots,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return SimDetect(selectedSlots, token).GetAwaiter().GetResult();
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_DetectDirect);
|
||||
|
||||
try
|
||||
@@ -1700,6 +1805,11 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slot,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slot);
|
||||
return await SimPhase("PreAdjustment_Preparation", slot, token).ConfigureAwait(false);
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_PreparationAsync);
|
||||
|
||||
try
|
||||
@@ -1745,6 +1855,10 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
|
||||
public PreAdjustmentProcessResult PreAdjustment_PreparationDirect()
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return SimBatchPhase("PreAdjustment_Preparation", CancellationToken.None).GetAwaiter().GetResult();
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_PreparationDirect);
|
||||
|
||||
try
|
||||
@@ -1780,6 +1894,11 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slot,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slot);
|
||||
return await SimPhase("PreAdjustment_AmplitudeTest", slot, token).ConfigureAwait(false);
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_AmplitudeTestAsync);
|
||||
|
||||
try
|
||||
@@ -1825,6 +1944,10 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
|
||||
public PreAdjustmentProcessResult PreAdjustment_AmplitudeTestDirect()
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return SimBatchPhase("PreAdjustment_AmplitudeTest", CancellationToken.None).GetAwaiter().GetResult();
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_AmplitudeTestDirect);
|
||||
|
||||
try
|
||||
@@ -1860,6 +1983,11 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slot,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slot);
|
||||
return await SimPhase("PreAdjustment_TemperatureCalibration", slot, token).ConfigureAwait(false);
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_TemperatureCalibrationAsync);
|
||||
|
||||
try
|
||||
@@ -1906,6 +2034,10 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
public bool PreAdjustment_PushTemperature(
|
||||
double temperature)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return SimBatchPhase(nameof(PreAdjustment_PushTemperature), CancellationToken.None).GetAwaiter().GetResult().Success;
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_PushTemperature);
|
||||
|
||||
try
|
||||
@@ -1932,6 +2064,10 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
|
||||
public PreAdjustmentProcessResult PreAdjustment_TemperatureCalibrationDirect()
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return SimBatchPhase("PreAdjustment_TemperatureCalibration", CancellationToken.None).GetAwaiter().GetResult();
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_TemperatureCalibrationDirect);
|
||||
|
||||
try
|
||||
@@ -1967,6 +2103,11 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slot,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slot);
|
||||
return await SimPhase("PreAdjustment_OffsetTest", slot, token).ConfigureAwait(false);
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_OffsetTestAsync);
|
||||
|
||||
try
|
||||
@@ -2012,6 +2153,10 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
|
||||
public PreAdjustmentProcessResult PreAdjustment_OffsetTestDirect()
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return SimBatchPhase("PreAdjustment_OffsetTest", CancellationToken.None).GetAwaiter().GetResult();
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_OffsetTestDirect);
|
||||
|
||||
try
|
||||
@@ -2047,6 +2192,11 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
int slot,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
ValidateSimulationSlot(slot);
|
||||
return await SimPhase("PreAdjustment_Completion", slot, token).ConfigureAwait(false);
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_CompletionAsync);
|
||||
|
||||
try
|
||||
@@ -2092,6 +2242,10 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
|
||||
public PreAdjustmentProcessResult PreAdjustment_CompletionDirect()
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return SimBatchPhase("PreAdjustment_Completion", CancellationToken.None).GetAwaiter().GetResult();
|
||||
}
|
||||
const string operation = nameof(PreAdjustment_CompletionDirect);
|
||||
|
||||
try
|
||||
@@ -2158,8 +2312,12 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
|
||||
public List<string> GetAllRegisterNames()
|
||||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
return Simulation.Registers.Keys.Select(k => k.Substring(k.IndexOf(':') + 1)).Distinct().ToList();
|
||||
}
|
||||
EnsureExternalInterface();
|
||||
return _gciEngine.gciExternalInterface.GetAllRegisterNames();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
{
|
||||
// Source-editable simulation profiles. Configure before starting a test.
|
||||
public sealed class GciSimulationProfile
|
||||
{
|
||||
public int DurationMs { get; set; } = 5000;
|
||||
public bool Success { get; set; } = true;
|
||||
public string ErrorMessage { get; set; } = "";
|
||||
public string PcbId { get; set; } // Null generates a deterministic nine-digit ID per slot.
|
||||
public string Password { get; set; } = "000000000000";
|
||||
public string RawHex { get; set; } = "00000000";
|
||||
public Dictionary<string, UInt32> CalibrationParams { get; set; } = new Dictionary<string, UInt32>();
|
||||
|
||||
internal GciSimulationProfile Snapshot()
|
||||
{
|
||||
if (DurationMs < 0) throw new ArgumentOutOfRangeException("DurationMs");
|
||||
return new GciSimulationProfile
|
||||
{
|
||||
DurationMs = DurationMs, Success = Success, ErrorMessage = ErrorMessage,
|
||||
PcbId = PcbId, Password = Password, RawHex = RawHex,
|
||||
CalibrationParams = new Dictionary<string, UInt32>(CalibrationParams)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class GciSimulationSettings
|
||||
{
|
||||
public Dictionary<string, GciSimulationProfile> Operations { get; } = new Dictionary<string, GciSimulationProfile>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "MeterActivity", new GciSimulationProfile() },
|
||||
{ "InitSlotAsync", new GciSimulationProfile() },
|
||||
{ "UpdateSlotAsync", new GciSimulationProfile() },
|
||||
{ "GetSlotAsync", new GciSimulationProfile() },
|
||||
{ "CleanSlotAsync", new GciSimulationProfile() },
|
||||
{ "CleanAllSlotsAsync", new GciSimulationProfile() },
|
||||
{ "GetPcbIdAsync", new GciSimulationProfile() },
|
||||
{ "ConnectAsync", new GciSimulationProfile() },
|
||||
{ "LoginAsync", new GciSimulationProfile() },
|
||||
{ "DisconnectAsync", new GciSimulationProfile() },
|
||||
{ "SetPasswordAsync", new GciSimulationProfile() },
|
||||
{ "ReadRegisterAsync", new GciSimulationProfile() },
|
||||
{ "WriteRegisterAsync", new GciSimulationProfile() },
|
||||
{ "GetPasswordAsync", new GciSimulationProfile() },
|
||||
{ "GetPreAdjustmentCalibrationParamsAsync", new GciSimulationProfile() },
|
||||
{ "ConnectFullPassLoginWithRetryAsync", new GciSimulationProfile() },
|
||||
{ "Preadjustment_Initialization", new GciSimulationProfile() },
|
||||
{ "PreAdjustment_Detect", new GciSimulationProfile() },
|
||||
{ "PreAdjustment_Preparation", new GciSimulationProfile() },
|
||||
{ "PreAdjustment_AmplitudeTest", new GciSimulationProfile() },
|
||||
{ "PreAdjustment_TemperatureCalibration", new GciSimulationProfile() },
|
||||
{ "PreAdjustment_PushTemperature", new GciSimulationProfile() },
|
||||
{ "PreAdjustment_OffsetTest", new GciSimulationProfile() },
|
||||
{ "PreAdjustment_Completion", new GciSimulationProfile() },
|
||||
};
|
||||
|
||||
// Optional exact register profiles, e.g. WriteRegisterAsync:GENESISFLOW_TriggerActive.
|
||||
public Dictionary<string, GciSimulationProfile> Registers { get; } = new Dictionary<string, GciSimulationProfile>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
internal GciSimulationProfile Get(string operation, string register)
|
||||
{
|
||||
GciSimulationProfile profile;
|
||||
if (register != null && Registers.TryGetValue(operation + ":" + register, out profile)) return profile.Snapshot();
|
||||
if (!Operations.TryGetValue(operation, out profile)) throw new InvalidOperationException("Missing simulation profile: " + operation);
|
||||
return profile.Snapshot();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,18 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
|
||||
|
||||
System.Windows.Forms.Form modelessDlg;
|
||||
private GenesisCommunicationDiagnosticsForm preadjustmentDiagnosticsForm;
|
||||
private GenesisCommunicationDiagnosticsForm diagnosticsForm;
|
||||
|
||||
private void DiagnosticUi(Action action)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Program.MainWnd == null || Program.MainWnd.IsDisposed) return;
|
||||
if (Program.MainWnd.InvokeRequired) Program.MainWnd.Invoke(action);
|
||||
else action();
|
||||
}
|
||||
catch (Exception ex) { log.Warn("GCI diagnostic UI failed; execution continues.", ex); }
|
||||
}
|
||||
///
|
||||
delegate void iPerlCommFormDlgt(GenesisCommunicationSeq myRef, TestMethod method, Test test, iPerlCommunicationParams testParams);
|
||||
///
|
||||
@@ -71,40 +82,6 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
modelessDlg = null;
|
||||
}
|
||||
|
||||
private delegate void PreadjustmentDiagnosticsFormDelegate(GenesisCommunicationSeq sequence, GciBridgeType bridge, string activity);
|
||||
|
||||
private void OpenPreadjustmentDiagnosticsForm(GenesisCommunicationSeq sequence, GciBridgeType bridge, string activity)
|
||||
{
|
||||
sequence.ClosePreadjustmentDiagnosticsForm();
|
||||
sequence.preadjustmentDiagnosticsForm = new GenesisCommunicationDiagnosticsForm(bridge, activity);
|
||||
sequence.preadjustmentDiagnosticsForm.Show();
|
||||
}
|
||||
|
||||
private void ClosePreadjustmentDiagnosticsForm()
|
||||
{
|
||||
if (preadjustmentDiagnosticsForm == null)
|
||||
return;
|
||||
|
||||
if (!preadjustmentDiagnosticsForm.IsDisposed)
|
||||
preadjustmentDiagnosticsForm.Close();
|
||||
|
||||
preadjustmentDiagnosticsForm.Dispose();
|
||||
preadjustmentDiagnosticsForm = null;
|
||||
}
|
||||
|
||||
private void ShowPreadjustmentDiagnostics(GciBridgeType bridge, string activity)
|
||||
{
|
||||
Program.MainWnd.Invoke(new PreadjustmentDiagnosticsFormDelegate(OpenPreadjustmentDiagnosticsForm), new object[] { this, bridge, activity });
|
||||
}
|
||||
|
||||
private void HidePreadjustmentDiagnostics()
|
||||
{
|
||||
if (Program.MainWnd == null || Program.MainWnd.IsDisposed)
|
||||
return;
|
||||
|
||||
Program.MainWnd.Invoke(new Action(ClosePreadjustmentDiagnosticsForm));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Flying start mass collection method sequence
|
||||
@@ -127,7 +104,7 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, false);
|
||||
|
||||
iPerlCommunicationParams genesisTestParams = testParams as iPerlCommunicationParams;
|
||||
if (genesisTestParams != null && IsPreadjustmentActivity(genesisTestParams.Activity))
|
||||
if (genesisTestParams != null && (IsPreadjustmentActivity(genesisTestParams.Activity) || method.DebugLevel == DebugMode.Simulate))
|
||||
{
|
||||
return ExecutePreadjustment(test, method, genesisTestParams);
|
||||
}
|
||||
@@ -471,6 +448,52 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
return new List<Event> { Event.Done };
|
||||
}
|
||||
|
||||
private static bool ExecuteSimulatedMeterActivity(GciBridgeType bridge, IList<KeyValuePair<int, GenesisSmartReader>> readers, iPerlCommunicationParams parameters, out string response)
|
||||
{
|
||||
var tasks = readers.Select(item => System.Threading.Tasks.Task.Run(async () =>
|
||||
{
|
||||
int slot = item.Value.GetSlotNr;
|
||||
string activity = parameters.Activity;
|
||||
bool ok;
|
||||
string message;
|
||||
switch (activity)
|
||||
{
|
||||
case GenesisCommunicationForm.SlotInitializeStr:
|
||||
case GenesisCommunicationForm.SlotUpdateStr:
|
||||
var request = new GciPublicModels.GciInitSlotRequest { SlotId = slot };
|
||||
var init = activity == GenesisCommunicationForm.SlotInitializeStr ? await bridge.InitSlotAsync(request) : await bridge.UpdateSlotAsync(request);
|
||||
ok = init.Success; message = init.Message; break;
|
||||
case GenesisCommunicationForm.SlotConnectStr:
|
||||
var connected = await bridge.ConnectAsync(slot); ok = connected.Success; message = connected.Message; break;
|
||||
case GenesisCommunicationForm.SlotPCBSlotStr:
|
||||
var pcb = await bridge.GetPcbIdAsync(slot); ok = pcb.Success; message = pcb.ToString(); break;
|
||||
case GenesisCommunicationForm.SlotSetPasswordStr:
|
||||
var password = await bridge.SetPasswordAsync(slot, bridge.Simulation.Operations["SetPasswordAsync"].Password); ok = password.Success; message = password.Message; break;
|
||||
case GenesisCommunicationForm.SlotLoginStr:
|
||||
var login = await bridge.LoginAsync(slot); ok = login.Success; message = login.Message; break;
|
||||
case GenesisCommunicationForm.SlotGroupedLoginStr:
|
||||
var full = await bridge.ConnectFullPassLoginWithRetryAsync(slot); ok = full.Success; message = full.Message; break;
|
||||
case GenesisCommunicationForm.SlotDisconnectStr:
|
||||
var disconnected = await bridge.DisconnectAsync(slot); ok = disconnected.Success; message = disconnected.Message; break;
|
||||
case GenesisCommunicationForm.SlotSetTestModeStr:
|
||||
case GenesisCommunicationForm.SlotSetActiveModeStr:
|
||||
var mode = await bridge.WriteRegisterAsync(slot, TBF.Rig.RegisterReaders.GenesisRegReader.communication.RadioService.LedMode, activity == GenesisCommunicationForm.SlotSetTestModeStr ? (byte)6 : (byte)0);
|
||||
ok = mode.Success; message = mode.ErrorMessage; break;
|
||||
case GenesisCommunicationForm.PrepareSlotQ3CalibrationStr:
|
||||
case GenesisCommunicationForm.WriteSlotQ3CalibrationStr:
|
||||
case GenesisCommunicationForm.CheckMeterPrepareStr:
|
||||
case GenesisCommunicationForm.HoldSlotStr:
|
||||
var aggregate = await bridge.SimulateMeterActivityAsync(activity, slot); ok = aggregate.Success; message = aggregate.ErrorMessage; break;
|
||||
default:
|
||||
throw new InvalidOperationException("No simulated Genesis activity mapping: " + activity);
|
||||
}
|
||||
return new KeyValuePair<bool, string>(ok, string.Format("Slot={0}, Success={1}, Message={2}", slot, ok, message));
|
||||
})).ToArray();
|
||||
var results = System.Threading.Tasks.Task.WhenAll(tasks).GetAwaiter().GetResult();
|
||||
response = string.Join(Environment.NewLine, results.Select(r => r.Value));
|
||||
return results.All(r => r.Key);
|
||||
}
|
||||
|
||||
private static bool IsPreadjustmentActivity(string activity)
|
||||
{
|
||||
return string.Equals(activity, PreadjustmentInitializationStr, StringComparison.OrdinalIgnoreCase) ||
|
||||
@@ -486,9 +509,12 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
private IList<Event> ExecutePreadjustment(Test test, TestMethod method, iPerlCommunicationParams testParams)
|
||||
{
|
||||
DateTime startTime = DateTime.Now;
|
||||
GenesisPreadjustmentBatchState batchState = null;
|
||||
bool preadjustment = IsPreadjustmentActivity(testParams.Activity);
|
||||
bool success = false;
|
||||
string response = string.Empty;
|
||||
List<KeyValuePair<int, GenesisSmartReader>> readers = new List<KeyValuePair<int, GenesisSmartReader>>();
|
||||
List<KeyValuePair<int, GenesisSmartReader>> resultReaders = readers;
|
||||
|
||||
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
|
||||
@@ -506,7 +532,16 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
try
|
||||
{
|
||||
readers = GetPreadjustmentReaders(test);
|
||||
resultReaders = readers;
|
||||
GciBridgeType bridge = GetCommonGciBridge(readers);
|
||||
if (preadjustment) batchState = GenesisPreadjustmentBatchState.For(ProcessData.BatchRslts, bridge);
|
||||
if (preadjustment)
|
||||
{
|
||||
foreach (int slot in batchState.Slots.Where(batchState.IsExcluded)) bridge.ExcludePreadjustmentSlot(slot);
|
||||
readers = readers.Where(item => !batchState.IsExcluded(item.Value.GetSlotNr)).ToList();
|
||||
}
|
||||
if (method.DebugLevel == DebugMode.Simulate && !bridge.IsSimulation)
|
||||
throw new InvalidOperationException("GenesisCommunication is simulated, but GCI Bridge is not in Simulate mode.");
|
||||
|
||||
preadjustmentLogger.Info(
|
||||
"[PREADJUSTMENT] CONTEXT Test={0}, Activity={1}, Bridge={2}, Slots={3}, ReaderCount={4}",
|
||||
@@ -516,11 +551,66 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
string.Join(",", readers.Select(item => item.Value.GetSlotNr)),
|
||||
readers.Count);
|
||||
|
||||
ShowPreadjustmentDiagnostics(bridge, testParams.Activity);
|
||||
success = ExecutePreadjustmentActivity(bridge, readers, testParams, out response);
|
||||
if (preadjustment) DiagnosticUi(() =>
|
||||
{
|
||||
diagnosticsForm = new GenesisCommunicationDiagnosticsForm(bridge, testParams.Activity, batchState);
|
||||
if (!bridge.IsSimulation) diagnosticsForm.AttachProgress(bridge.gciExternalInterface._innerMeterAPI._progressProcess);
|
||||
diagnosticsForm.Show(Program.MainWnd);
|
||||
});
|
||||
try
|
||||
{
|
||||
if (preadjustment) batchState.Start(readers.Select(item => item.Value.GetSlotNr), testParams.Activity);
|
||||
if (readers.Count == 0) throw new InvalidOperationException("No eligible slots remain: failed slots are excluded for this batch.");
|
||||
using (method.DebugLevel == DebugMode.Simulate ? bridge.BeginSimulation(new TBF.Rig.BridgeComponents.GciBridge.GciSimulationProfile { DurationMs = testParams.SimulationDurationMs, Success = testParams.SimulationSuccess, ErrorMessage = testParams.SimulationErrorMessage }) : null)
|
||||
{
|
||||
success = IsPreadjustmentActivity(testParams.Activity)
|
||||
? ExecutePreadjustmentActivity(bridge, readers, testParams, out response)
|
||||
: ExecuteSimulatedMeterActivity(bridge, readers, testParams, out response);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
response = ex.Message;
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (preadjustment && batchState != null)
|
||||
{
|
||||
foreach (var item in readers)
|
||||
{
|
||||
int slot = item.Value.GetSlotNr;
|
||||
bool passed = success;
|
||||
if (passed && !bridge.IsSimulation && !string.Equals(testParams.Activity, PreadjustmentInitializationStr, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var controls = bridge.gciExternalInterface._innerMeterAPI._meterControls;
|
||||
var control = controls == null ? null : controls.FirstOrDefault(c => c.Slot == slot);
|
||||
passed = control != null && control.IsEnabled && !control.Failed;
|
||||
}
|
||||
batchState.Finish(slot, testParams.Activity, passed, response);
|
||||
if (!passed) bridge.ExcludePreadjustmentSlot(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DiagnosticUi(() =>
|
||||
{
|
||||
if (diagnosticsForm != null)
|
||||
{
|
||||
diagnosticsForm.RefreshProgress();
|
||||
diagnosticsForm.Dispose();
|
||||
}
|
||||
diagnosticsForm = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
success = false;
|
||||
response = ex.Message;
|
||||
log.Error(string.Format("{0} failed.", testParams.Activity), ex);
|
||||
|
||||
@@ -533,12 +623,8 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
(long)(DateTime.Now - startTime).TotalMilliseconds,
|
||||
ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
HidePreadjustmentDiagnostics();
|
||||
}
|
||||
|
||||
UpdatePreadjustmentResult(test, method, readers, success, startTime);
|
||||
UpdatePreadjustmentResult(test, method, resultReaders, success, startTime, preadjustment ? batchState : null);
|
||||
|
||||
if (success)
|
||||
{
|
||||
@@ -621,7 +707,7 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
return commonBridge;
|
||||
}
|
||||
|
||||
private static bool ExecutePreadjustmentActivity(GciBridgeType bridge, IList<KeyValuePair<int, GenesisSmartReader>> readers, iPerlCommunicationParams testParams, out string response)
|
||||
private bool ExecutePreadjustmentActivity(GciBridgeType bridge, IList<KeyValuePair<int, GenesisSmartReader>> readers, iPerlCommunicationParams testParams, out string response)
|
||||
{
|
||||
preadjustmentLogger.Debug(
|
||||
"[PREADJUSTMENT] DISPATCH Activity={0}, Bridge={1}, Slots={2}, Thread={3}",
|
||||
@@ -658,6 +744,10 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
meterControls.Add(meterControl);
|
||||
}
|
||||
|
||||
DiagnosticUi(() =>
|
||||
{
|
||||
if (diagnosticsForm != null && !diagnosticsForm.IsDisposed) diagnosticsForm.AttachProgress(progress);
|
||||
});
|
||||
PublicModels.PreAdjustmentInitializationResult result = bridge.Preadjustment_Initialization(progress, meterControls);
|
||||
response = result.ToString();
|
||||
|
||||
@@ -728,7 +818,7 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
return processResult.Success;
|
||||
}
|
||||
|
||||
private static void UpdatePreadjustmentResult(Test test, TestMethod method, IEnumerable<KeyValuePair<int, GenesisSmartReader>> readers, bool success, DateTime startTime)
|
||||
private static void UpdatePreadjustmentResult(Test test, TestMethod method, IEnumerable<KeyValuePair<int, GenesisSmartReader>> readers, bool success, DateTime startTime, GenesisPreadjustmentBatchState batchState)
|
||||
{
|
||||
TestRslt testResult = ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part);
|
||||
if (testResult == null)
|
||||
@@ -747,7 +837,7 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
continue;
|
||||
|
||||
meterResult.WaterMeter.SerialNr = item.Value.SerialNr;
|
||||
meterResult.Passed = success;
|
||||
meterResult.Passed = success && (batchState == null || !batchState.IsExcluded(item.Value.GetSlotNr));
|
||||
meterResult.TestDone = true;
|
||||
|
||||
preadjustmentLogger.Debug(
|
||||
@@ -756,7 +846,7 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
test.Part,
|
||||
item.Key,
|
||||
item.Value.GetSlotNr,
|
||||
success);
|
||||
meterResult.Passed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using GciBridgeType = TBF.Rig.BridgeComponents.GciBridge.GciBridge;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
{
|
||||
// Owned by the batch result object, never by the diagnostic window.
|
||||
internal sealed class GenesisPreadjustmentBatchState
|
||||
{
|
||||
private static readonly ConditionalWeakTable<object, Dictionary<GciBridgeType, GenesisPreadjustmentBatchState>> batches = new ConditionalWeakTable<object, Dictionary<GciBridgeType, GenesisPreadjustmentBatchState>>();
|
||||
private readonly object sync = new object();
|
||||
private readonly Dictionary<int, Dictionary<string, string>> phases = new Dictionary<int, Dictionary<string, string>>();
|
||||
private readonly Dictionary<int, Queue<string>> logs = new Dictionary<int, Queue<string>>();
|
||||
private readonly HashSet<int> excluded = new HashSet<int>();
|
||||
public static GenesisPreadjustmentBatchState For(object batch, GciBridgeType bridge)
|
||||
{
|
||||
lock (batches)
|
||||
{
|
||||
var states = batches.GetOrCreateValue(batch);
|
||||
GenesisPreadjustmentBatchState state;
|
||||
if (!states.TryGetValue(bridge, out state)) states.Add(bridge, state = new GenesisPreadjustmentBatchState());
|
||||
return state;
|
||||
}
|
||||
}
|
||||
public int[] Slots { get { lock (sync) return phases.Keys.ToArray(); } }
|
||||
public bool IsExcluded(int slot) { lock (sync) return excluded.Contains(slot); }
|
||||
public string Phase(int slot, string phase)
|
||||
{
|
||||
lock (sync)
|
||||
{
|
||||
Dictionary<string, string> values;
|
||||
string value;
|
||||
return phases.TryGetValue(slot, out values) && values.TryGetValue(phase, out value) ? value : "Pending";
|
||||
}
|
||||
}
|
||||
public void Start(IEnumerable<int> slots, string phase)
|
||||
{
|
||||
lock (sync)
|
||||
{
|
||||
foreach (int slot in slots)
|
||||
{
|
||||
if (!phases.ContainsKey(slot)) phases.Add(slot, new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase));
|
||||
if (excluded.Contains(slot)) continue;
|
||||
phases[slot][phase] = "Running";
|
||||
AddLog(slot, phase + " — START");
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Finish(int slot, string phase, bool success, string message)
|
||||
{
|
||||
lock (sync)
|
||||
{
|
||||
if (!phases.ContainsKey(slot)) phases.Add(slot, new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase));
|
||||
phases[slot][phase] = success ? "Passed" : "Failed";
|
||||
if (!success) excluded.Add(slot);
|
||||
AddLog(slot, phase + " — Success=" + success + ". " + message);
|
||||
}
|
||||
}
|
||||
public void AddLog(int slot, string message)
|
||||
{
|
||||
if (slot <= 0) return;
|
||||
lock (sync)
|
||||
{
|
||||
Queue<string> queue;
|
||||
if (!logs.TryGetValue(slot, out queue)) logs.Add(slot, queue = new Queue<string>());
|
||||
queue.Enqueue(DateTime.Now.ToString("HH:mm:ss.fff") + " " + message);
|
||||
while (queue.Count > 1000) queue.Dequeue();
|
||||
}
|
||||
}
|
||||
public string LogText(int slot) { lock (sync) return logs.ContainsKey(slot) ? string.Join(Environment.NewLine, logs[slot]) : ""; }
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
|
||||
public IList<Event> Execute(Test test, int repetNr, bool isLastRepetition)
|
||||
{
|
||||
if (DebugLevel == DebugMode.Normal)
|
||||
if (DebugLevel == DebugMode.Normal || DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return (new GenesisCommunicationSeq()).Execute(test, repetNr, this, testMethodCfg.TestParams);
|
||||
}
|
||||
|
||||
@@ -23,11 +23,25 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new TestMethodCfgCtrl(); }
|
||||
|
||||
//
|
||||
public override IParamsProvider GetRuntimeTestParamsProvider() { return TestParams; }
|
||||
public override IParamsProvider GetRuntimeTestParamsProvider()
|
||||
{
|
||||
var parameters = TestParams as iPerlCommunicationParams;
|
||||
if (parameters != null) parameters.ShowSimulationParameters = SimulationColumnsEnabled();
|
||||
return TestParams;
|
||||
}
|
||||
public override IParamsProvider CreateTestParamsProvider() { return new iPerlCommunicationParams(true); }
|
||||
public override IParamsProvider GetUITestParamsProvider(Test test)
|
||||
{
|
||||
return (test.Method == Name) ? base.GetUITestParamsProvider(test) : null;
|
||||
var provider = (test.Method == Name) ? base.GetUITestParamsProvider(test) : null;
|
||||
var genesis = provider as iPerlCommunicationParams;
|
||||
if (genesis != null) genesis.ShowSimulationParameters = SimulationColumnsEnabled();
|
||||
return provider;
|
||||
}
|
||||
|
||||
private bool SimulationColumnsEnabled()
|
||||
{
|
||||
var component = TbfComponents.FindComponent(Name) as TestMethod;
|
||||
return component != null && component.DebugLevel == DebugMode.Simulate;
|
||||
}
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
|
||||
Generated
+81
-324
@@ -1,346 +1,103 @@
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
{
|
||||
partial class GenesisCommunicationDiagnosticsForm
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
private System.ComponentModel.IContainer components;
|
||||
private System.Windows.Forms.SplitContainer verticalSplit;
|
||||
private System.Windows.Forms.SplitContainer overviewSplit;
|
||||
private System.Windows.Forms.DataGridView slotsGrid;
|
||||
private System.Windows.Forms.DataGridView workersGrid;
|
||||
private System.Windows.Forms.TabControl slotTabs;
|
||||
private System.Windows.Forms.Timer refreshTimer;
|
||||
private System.Windows.Forms.StatusStrip statusStrip;
|
||||
private System.Windows.Forms.ToolStripStatusLabel statusLabel;
|
||||
private System.Windows.Forms.ToolStrip toolbar;
|
||||
private System.Windows.Forms.ToolStripButton refreshButton;
|
||||
private System.Windows.Forms.ToolStripButton bridgeButton;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
components.Dispose();
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
ReleaseDiagnostics();
|
||||
if (components != null) components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.Windows.Forms.DataGridViewCellStyle lastActivityCellStyle = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
this.diagnosticsToolStrip = new System.Windows.Forms.ToolStrip();
|
||||
this.activityToolStripLabel = new System.Windows.Forms.ToolStripLabel();
|
||||
this.refreshToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.showBridgeToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.mainSplitContainer = new System.Windows.Forms.SplitContainer();
|
||||
this.slotsGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.slotsDataGridView = new System.Windows.Forms.DataGridView();
|
||||
this.slotColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.selectedColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn();
|
||||
this.pcbIdColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.connectedColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn();
|
||||
this.loggedOnColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn();
|
||||
this.fwVersionColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.requestPortColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.requestPortTypeColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.streamingPortColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.interfaceVersionColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.workersGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.workersDataGridView = new System.Windows.Forms.DataGridView();
|
||||
this.workerSlotColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.workerNameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.queueLengthColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.busyColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn();
|
||||
this.currentOperationColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.lastErrorColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.lastActivityColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.diagnosticsStatusStrip = new System.Windows.Forms.StatusStrip();
|
||||
this.statusToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.verticalSplit = new System.Windows.Forms.SplitContainer();
|
||||
this.overviewSplit = new System.Windows.Forms.SplitContainer();
|
||||
this.slotsGrid = new System.Windows.Forms.DataGridView();
|
||||
this.workersGrid = new System.Windows.Forms.DataGridView();
|
||||
this.slotTabs = new System.Windows.Forms.TabControl();
|
||||
this.refreshTimer = new System.Windows.Forms.Timer(this.components);
|
||||
this.diagnosticsToolStrip.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.mainSplitContainer)).BeginInit();
|
||||
this.mainSplitContainer.Panel1.SuspendLayout();
|
||||
this.mainSplitContainer.Panel2.SuspendLayout();
|
||||
this.mainSplitContainer.SuspendLayout();
|
||||
this.slotsGroupBox.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.slotsDataGridView)).BeginInit();
|
||||
this.workersGroupBox.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.workersDataGridView)).BeginInit();
|
||||
this.diagnosticsStatusStrip.SuspendLayout();
|
||||
this.statusStrip = new System.Windows.Forms.StatusStrip();
|
||||
this.statusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.toolbar = new System.Windows.Forms.ToolStrip();
|
||||
this.refreshButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.bridgeButton = new System.Windows.Forms.ToolStripButton();
|
||||
((System.ComponentModel.ISupportInitialize)(this.verticalSplit)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.overviewSplit)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.slotsGrid)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.workersGrid)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// diagnosticsToolStrip
|
||||
//
|
||||
this.diagnosticsToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
|
||||
this.diagnosticsToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.activityToolStripLabel,
|
||||
this.refreshToolStripButton,
|
||||
this.showBridgeToolStripButton});
|
||||
this.diagnosticsToolStrip.Location = new System.Drawing.Point(0, 0);
|
||||
this.diagnosticsToolStrip.Name = "diagnosticsToolStrip";
|
||||
this.diagnosticsToolStrip.Size = new System.Drawing.Size(1234, 25);
|
||||
this.diagnosticsToolStrip.TabIndex = 0;
|
||||
//
|
||||
// activityToolStripLabel
|
||||
//
|
||||
this.activityToolStripLabel.Name = "activityToolStripLabel";
|
||||
this.activityToolStripLabel.Size = new System.Drawing.Size(99, 22);
|
||||
this.activityToolStripLabel.Text = "Running activity:";
|
||||
//
|
||||
// refreshToolStripButton
|
||||
//
|
||||
this.refreshToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.refreshToolStripButton.Name = "refreshToolStripButton";
|
||||
this.refreshToolStripButton.Size = new System.Drawing.Size(50, 22);
|
||||
this.refreshToolStripButton.Text = "Refresh";
|
||||
this.refreshToolStripButton.Click += new System.EventHandler(this.refreshToolStripButton_Click);
|
||||
//
|
||||
// showBridgeToolStripButton
|
||||
//
|
||||
this.showBridgeToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.showBridgeToolStripButton.Name = "showBridgeToolStripButton";
|
||||
this.showBridgeToolStripButton.Size = new System.Drawing.Size(124, 22);
|
||||
this.showBridgeToolStripButton.Text = "Open GCI Bridge GUI";
|
||||
this.showBridgeToolStripButton.Click += new System.EventHandler(this.showBridgeToolStripButton_Click);
|
||||
//
|
||||
// mainSplitContainer
|
||||
//
|
||||
this.mainSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.mainSplitContainer.Location = new System.Drawing.Point(0, 25);
|
||||
this.mainSplitContainer.Name = "mainSplitContainer";
|
||||
this.mainSplitContainer.Panel1.Controls.Add(this.slotsGroupBox);
|
||||
this.mainSplitContainer.Panel2.Controls.Add(this.workersGroupBox);
|
||||
this.mainSplitContainer.Size = new System.Drawing.Size(1234, 534);
|
||||
this.mainSplitContainer.SplitterDistance = 710;
|
||||
this.mainSplitContainer.TabIndex = 1;
|
||||
//
|
||||
// slotsGroupBox
|
||||
//
|
||||
this.slotsGroupBox.Controls.Add(this.slotsDataGridView);
|
||||
this.slotsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.slotsGroupBox.Location = new System.Drawing.Point(0, 0);
|
||||
this.slotsGroupBox.Name = "slotsGroupBox";
|
||||
this.slotsGroupBox.Padding = new System.Windows.Forms.Padding(6);
|
||||
this.slotsGroupBox.Size = new System.Drawing.Size(710, 534);
|
||||
this.slotsGroupBox.TabIndex = 0;
|
||||
this.slotsGroupBox.TabStop = false;
|
||||
this.slotsGroupBox.Text = "GCI slots";
|
||||
//
|
||||
// slotsDataGridView
|
||||
//
|
||||
this.slotsDataGridView.AllowUserToAddRows = false;
|
||||
this.slotsDataGridView.AllowUserToDeleteRows = false;
|
||||
this.slotsDataGridView.AllowUserToResizeRows = false;
|
||||
this.slotsDataGridView.AutoGenerateColumns = false;
|
||||
this.slotsDataGridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.DisplayedCells;
|
||||
this.slotsDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
this.slotsDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||
this.slotColumn,
|
||||
this.selectedColumn,
|
||||
this.pcbIdColumn,
|
||||
this.connectedColumn,
|
||||
this.loggedOnColumn,
|
||||
this.fwVersionColumn,
|
||||
this.requestPortColumn,
|
||||
this.requestPortTypeColumn,
|
||||
this.streamingPortColumn,
|
||||
this.interfaceVersionColumn});
|
||||
this.slotsDataGridView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.slotsDataGridView.Location = new System.Drawing.Point(6, 19);
|
||||
this.slotsDataGridView.MultiSelect = false;
|
||||
this.slotsDataGridView.Name = "slotsDataGridView";
|
||||
this.slotsDataGridView.ReadOnly = true;
|
||||
this.slotsDataGridView.RowHeadersWidth = 35;
|
||||
this.slotsDataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||
this.slotsDataGridView.Size = new System.Drawing.Size(698, 509);
|
||||
this.slotsDataGridView.TabIndex = 0;
|
||||
//
|
||||
// slot columns
|
||||
//
|
||||
this.slotColumn.DataPropertyName = "Slot";
|
||||
this.slotColumn.HeaderText = "Slot";
|
||||
this.slotColumn.Name = "slotColumn";
|
||||
this.slotColumn.ReadOnly = true;
|
||||
this.selectedColumn.DataPropertyName = "Selected";
|
||||
this.selectedColumn.HeaderText = "Selected";
|
||||
this.selectedColumn.Name = "selectedColumn";
|
||||
this.selectedColumn.ReadOnly = true;
|
||||
this.pcbIdColumn.DataPropertyName = "PcbId";
|
||||
this.pcbIdColumn.HeaderText = "PCB ID";
|
||||
this.pcbIdColumn.Name = "pcbIdColumn";
|
||||
this.pcbIdColumn.ReadOnly = true;
|
||||
this.connectedColumn.DataPropertyName = "IsConnected";
|
||||
this.connectedColumn.HeaderText = "Connected";
|
||||
this.connectedColumn.Name = "connectedColumn";
|
||||
this.connectedColumn.ReadOnly = true;
|
||||
this.loggedOnColumn.DataPropertyName = "IsLoggedOn";
|
||||
this.loggedOnColumn.HeaderText = "Logged on";
|
||||
this.loggedOnColumn.Name = "loggedOnColumn";
|
||||
this.loggedOnColumn.ReadOnly = true;
|
||||
this.fwVersionColumn.DataPropertyName = "FwVersion";
|
||||
this.fwVersionColumn.HeaderText = "FW version";
|
||||
this.fwVersionColumn.Name = "fwVersionColumn";
|
||||
this.fwVersionColumn.ReadOnly = true;
|
||||
this.requestPortColumn.DataPropertyName = "RequestPort";
|
||||
this.requestPortColumn.HeaderText = "Request port";
|
||||
this.requestPortColumn.Name = "requestPortColumn";
|
||||
this.requestPortColumn.ReadOnly = true;
|
||||
this.requestPortTypeColumn.DataPropertyName = "RequestPortType";
|
||||
this.requestPortTypeColumn.HeaderText = "Request type";
|
||||
this.requestPortTypeColumn.Name = "requestPortTypeColumn";
|
||||
this.requestPortTypeColumn.ReadOnly = true;
|
||||
this.streamingPortColumn.DataPropertyName = "StreamingPort";
|
||||
this.streamingPortColumn.HeaderText = "Streaming port";
|
||||
this.streamingPortColumn.Name = "streamingPortColumn";
|
||||
this.streamingPortColumn.ReadOnly = true;
|
||||
this.interfaceVersionColumn.DataPropertyName = "InterfaceVersion";
|
||||
this.interfaceVersionColumn.HeaderText = "Interface version";
|
||||
this.interfaceVersionColumn.Name = "interfaceVersionColumn";
|
||||
this.interfaceVersionColumn.ReadOnly = true;
|
||||
//
|
||||
// workersGroupBox
|
||||
//
|
||||
this.workersGroupBox.Controls.Add(this.workersDataGridView);
|
||||
this.workersGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.workersGroupBox.Location = new System.Drawing.Point(0, 0);
|
||||
this.workersGroupBox.Name = "workersGroupBox";
|
||||
this.workersGroupBox.Padding = new System.Windows.Forms.Padding(6);
|
||||
this.workersGroupBox.Size = new System.Drawing.Size(520, 534);
|
||||
this.workersGroupBox.TabIndex = 0;
|
||||
this.workersGroupBox.TabStop = false;
|
||||
this.workersGroupBox.Text = "GCI workers";
|
||||
//
|
||||
// workersDataGridView
|
||||
//
|
||||
this.workersDataGridView.AllowUserToAddRows = false;
|
||||
this.workersDataGridView.AllowUserToDeleteRows = false;
|
||||
this.workersDataGridView.AllowUserToResizeRows = false;
|
||||
this.workersDataGridView.AutoGenerateColumns = false;
|
||||
this.workersDataGridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.DisplayedCells;
|
||||
this.workersDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
this.workersDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||
this.workerSlotColumn,
|
||||
this.workerNameColumn,
|
||||
this.queueLengthColumn,
|
||||
this.busyColumn,
|
||||
this.currentOperationColumn,
|
||||
this.lastErrorColumn,
|
||||
this.lastActivityColumn});
|
||||
this.workersDataGridView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.workersDataGridView.Location = new System.Drawing.Point(6, 19);
|
||||
this.workersDataGridView.MultiSelect = false;
|
||||
this.workersDataGridView.Name = "workersDataGridView";
|
||||
this.workersDataGridView.ReadOnly = true;
|
||||
this.workersDataGridView.RowHeadersWidth = 35;
|
||||
this.workersDataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||
this.workersDataGridView.Size = new System.Drawing.Size(508, 509);
|
||||
this.workersDataGridView.TabIndex = 0;
|
||||
//
|
||||
// worker columns
|
||||
//
|
||||
this.workerSlotColumn.DataPropertyName = "Slot";
|
||||
this.workerSlotColumn.HeaderText = "Slot";
|
||||
this.workerSlotColumn.Name = "workerSlotColumn";
|
||||
this.workerSlotColumn.ReadOnly = true;
|
||||
this.workerNameColumn.DataPropertyName = "Name";
|
||||
this.workerNameColumn.HeaderText = "Name";
|
||||
this.workerNameColumn.Name = "workerNameColumn";
|
||||
this.workerNameColumn.ReadOnly = true;
|
||||
this.queueLengthColumn.DataPropertyName = "QueueLength";
|
||||
this.queueLengthColumn.HeaderText = "Queue length";
|
||||
this.queueLengthColumn.Name = "queueLengthColumn";
|
||||
this.queueLengthColumn.ReadOnly = true;
|
||||
this.busyColumn.DataPropertyName = "IsBusy";
|
||||
this.busyColumn.HeaderText = "Busy";
|
||||
this.busyColumn.Name = "busyColumn";
|
||||
this.busyColumn.ReadOnly = true;
|
||||
this.currentOperationColumn.DataPropertyName = "CurrentOperation";
|
||||
this.currentOperationColumn.HeaderText = "Current operation";
|
||||
this.currentOperationColumn.Name = "currentOperationColumn";
|
||||
this.currentOperationColumn.ReadOnly = true;
|
||||
this.lastErrorColumn.DataPropertyName = "LastError";
|
||||
this.lastErrorColumn.HeaderText = "Last error";
|
||||
this.lastErrorColumn.Name = "lastErrorColumn";
|
||||
this.lastErrorColumn.ReadOnly = true;
|
||||
this.lastActivityColumn.DataPropertyName = "LastActivity";
|
||||
lastActivityCellStyle.Format = "G";
|
||||
this.lastActivityColumn.DefaultCellStyle = lastActivityCellStyle;
|
||||
this.lastActivityColumn.HeaderText = "Last activity";
|
||||
this.lastActivityColumn.Name = "lastActivityColumn";
|
||||
this.lastActivityColumn.ReadOnly = true;
|
||||
//
|
||||
// diagnosticsStatusStrip
|
||||
//
|
||||
this.diagnosticsStatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.statusToolStripStatusLabel});
|
||||
this.diagnosticsStatusStrip.Location = new System.Drawing.Point(0, 559);
|
||||
this.diagnosticsStatusStrip.Name = "diagnosticsStatusStrip";
|
||||
this.diagnosticsStatusStrip.Size = new System.Drawing.Size(1234, 22);
|
||||
this.diagnosticsStatusStrip.TabIndex = 2;
|
||||
//
|
||||
// statusToolStripStatusLabel
|
||||
//
|
||||
this.statusToolStripStatusLabel.Name = "statusToolStripStatusLabel";
|
||||
this.statusToolStripStatusLabel.Size = new System.Drawing.Size(122, 17);
|
||||
this.statusToolStripStatusLabel.Text = "Waiting for GCI data...";
|
||||
//
|
||||
// refreshTimer
|
||||
//
|
||||
this.verticalSplit.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.verticalSplit.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||
this.verticalSplit.Size = new System.Drawing.Size(1280, 720);
|
||||
this.verticalSplit.SplitterDistance = 220;
|
||||
this.verticalSplit.Name = "verticalSplit";
|
||||
this.verticalSplit.Panel1.Controls.Add(this.overviewSplit);
|
||||
this.verticalSplit.Panel2.Controls.Add(this.slotTabs);
|
||||
this.overviewSplit.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.overviewSplit.Size = new System.Drawing.Size(1280, 220);
|
||||
this.overviewSplit.SplitterDistance = 640;
|
||||
this.overviewSplit.Name = "overviewSplit";
|
||||
this.overviewSplit.Panel1.Controls.Add(this.slotsGrid);
|
||||
this.overviewSplit.Panel2.Controls.Add(this.workersGrid);
|
||||
this.slotsGrid.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.slotsGrid.Name = "slotsGrid";
|
||||
this.slotsGrid.ReadOnly = true;
|
||||
this.slotsGrid.AllowUserToAddRows = false;
|
||||
this.slotsGrid.AllowUserToDeleteRows = false;
|
||||
this.workersGrid.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.workersGrid.Name = "workersGrid";
|
||||
this.workersGrid.ReadOnly = true;
|
||||
this.workersGrid.AllowUserToAddRows = false;
|
||||
this.workersGrid.AllowUserToDeleteRows = false;
|
||||
this.slotTabs.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.slotTabs.Name = "slotTabs";
|
||||
this.refreshTimer.Interval = 250;
|
||||
this.refreshTimer.Tick += new System.EventHandler(this.refreshTimer_Tick);
|
||||
//
|
||||
// GenesisCommunicationDiagnosticsForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.refreshTimer.Tick += new System.EventHandler(this.RefreshTick);
|
||||
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.statusLabel });
|
||||
this.statusStrip.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.statusStrip.Name = "statusStrip";
|
||||
this.statusLabel.Text = "Waiting for slot data";
|
||||
this.Controls.Add(this.verticalSplit);
|
||||
this.Controls.Add(this.statusStrip);
|
||||
this.refreshButton.Text = "Refresh";
|
||||
this.refreshButton.Click += new System.EventHandler(this.RefreshTick);
|
||||
this.bridgeButton.Text = "Open GCI Bridge GUI";
|
||||
this.bridgeButton.Click += new System.EventHandler(this.OpenBridge);
|
||||
this.toolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.refreshButton, this.bridgeButton });
|
||||
this.toolbar.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.Controls.Add(this.toolbar);
|
||||
this.ClientSize = new System.Drawing.Size(1280, 742);
|
||||
this.MinimumSize = new System.Drawing.Size(900, 550);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1234, 581);
|
||||
this.Controls.Add(this.mainSplitContainer);
|
||||
this.Controls.Add(this.diagnosticsStatusStrip);
|
||||
this.Controls.Add(this.diagnosticsToolStrip);
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(900, 400);
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Name = "GenesisCommunicationDiagnosticsForm";
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Genesis Communication - GCI diagnostics";
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.GenesisCommunicationDiagnosticsForm_FormClosed);
|
||||
this.Load += new System.EventHandler(this.GenesisCommunicationDiagnosticsForm_Load);
|
||||
this.diagnosticsToolStrip.ResumeLayout(false);
|
||||
this.diagnosticsToolStrip.PerformLayout();
|
||||
this.mainSplitContainer.Panel1.ResumeLayout(false);
|
||||
this.mainSplitContainer.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.mainSplitContainer)).EndInit();
|
||||
this.mainSplitContainer.ResumeLayout(false);
|
||||
this.slotsGroupBox.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.slotsDataGridView)).EndInit();
|
||||
this.workersGroupBox.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.workersDataGridView)).EndInit();
|
||||
this.diagnosticsStatusStrip.ResumeLayout(false);
|
||||
this.diagnosticsStatusStrip.PerformLayout();
|
||||
this.Text = "Genesis diagnostics";
|
||||
this.Load += new System.EventHandler(this.FormLoaded);
|
||||
((System.ComponentModel.ISupportInitialize)(this.slotsGrid)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.workersGrid)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.overviewSplit)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.verticalSplit)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ToolStrip diagnosticsToolStrip;
|
||||
private System.Windows.Forms.ToolStripLabel activityToolStripLabel;
|
||||
private System.Windows.Forms.ToolStripButton refreshToolStripButton;
|
||||
private System.Windows.Forms.ToolStripButton showBridgeToolStripButton;
|
||||
private System.Windows.Forms.SplitContainer mainSplitContainer;
|
||||
private System.Windows.Forms.GroupBox slotsGroupBox;
|
||||
private System.Windows.Forms.DataGridView slotsDataGridView;
|
||||
private System.Windows.Forms.GroupBox workersGroupBox;
|
||||
private System.Windows.Forms.DataGridView workersDataGridView;
|
||||
private System.Windows.Forms.StatusStrip diagnosticsStatusStrip;
|
||||
private System.Windows.Forms.ToolStripStatusLabel statusToolStripStatusLabel;
|
||||
private System.Windows.Forms.Timer refreshTimer;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn slotColumn;
|
||||
private System.Windows.Forms.DataGridViewCheckBoxColumn selectedColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn pcbIdColumn;
|
||||
private System.Windows.Forms.DataGridViewCheckBoxColumn connectedColumn;
|
||||
private System.Windows.Forms.DataGridViewCheckBoxColumn loggedOnColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn fwVersionColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn requestPortColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn requestPortTypeColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn streamingPortColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn interfaceVersionColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn workerSlotColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn workerNameColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn queueLengthColumn;
|
||||
private System.Windows.Forms.DataGridViewCheckBoxColumn busyColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn currentOperationColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn lastErrorColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn lastActivityColumn;
|
||||
}
|
||||
}
|
||||
|
||||
+194
-54
@@ -1,78 +1,218 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using CordonelPreadjustmentUi;
|
||||
using CordonelPreadjustmentUi.Processes.Itinerary;
|
||||
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||
using GciBridgeType = TBF.Rig.BridgeComponents.GciBridge.GciBridge;
|
||||
using GciPublicModels = GenesisCordonelInterface.API.PublicModels;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays live GCI slot and worker information while a GenesisCommunication
|
||||
/// preadjustment activity is running.
|
||||
/// </summary>
|
||||
public partial class GenesisCommunicationDiagnosticsForm : Form
|
||||
{
|
||||
private readonly GciBridgeType bridge;
|
||||
private readonly string activity;
|
||||
private GciBridgeType bridge;
|
||||
private string activity;
|
||||
private ProcessProgress progress;
|
||||
private GenesisPreadjustmentBatchState batchState;
|
||||
private readonly Dictionary<int, Dictionary<string, Label>> phaseLabels = new Dictionary<int, Dictionary<string, Label>>();
|
||||
private readonly Dictionary<int, TabPage> pages = new Dictionary<int, TabPage>();
|
||||
private readonly Dictionary<int, Label> states = new Dictionary<int, Label>();
|
||||
private readonly Dictionary<int, Label> activePhases = new Dictionary<int, Label>();
|
||||
private readonly Dictionary<int, RichTextBox> memos = new Dictionary<int, RichTextBox>();
|
||||
private readonly object logLock = new object();
|
||||
private readonly Queue<KeyValuePair<int, string>> pending = new Queue<KeyValuePair<int, string>>();
|
||||
private bool acceptingLogs;
|
||||
private int dropped;
|
||||
private static readonly string[] Phases = { "Initialization", "Detect", "Preparation", "Amplitude Test", "Temperature Calibration", "Push Temperature", "Offset Test", "Completion" };
|
||||
|
||||
public GenesisCommunicationDiagnosticsForm(GciBridgeType bridge, string activity)
|
||||
public GenesisCommunicationDiagnosticsForm()
|
||||
{
|
||||
if (bridge == null)
|
||||
throw new ArgumentNullException("bridge");
|
||||
|
||||
this.bridge = bridge;
|
||||
this.activity = activity ?? string.Empty;
|
||||
|
||||
InitializeComponent();
|
||||
activityToolStripLabel.Text = "Running activity: " + this.activity;
|
||||
slotTabs.DrawMode = TabDrawMode.OwnerDrawFixed;
|
||||
slotTabs.DrawItem += DrawSlotTab;
|
||||
slotTabs.ItemSize = new Size(100, 28);
|
||||
slotTabs.SizeMode = TabSizeMode.Fixed;
|
||||
}
|
||||
|
||||
private void GenesisCommunicationDiagnosticsForm_Load(object sender, EventArgs e)
|
||||
public GenesisCommunicationDiagnosticsForm(GciBridgeType bridge, string activity) : this(bridge, activity, new GenesisPreadjustmentBatchState()) { }
|
||||
|
||||
internal GenesisCommunicationDiagnosticsForm(GciBridgeType bridge, string activity, GenesisPreadjustmentBatchState batchState) : this()
|
||||
{
|
||||
RefreshDiagnostics();
|
||||
this.batchState = batchState;
|
||||
this.bridge = bridge;
|
||||
this.activity = activity;
|
||||
Text = "Genesis diagnostics — " + activity;
|
||||
acceptingLogs = true;
|
||||
if (bridge.IsSimulation) bridge.SimulationLog += OnSimulationLog;
|
||||
}
|
||||
|
||||
public void AttachProgress(ProcessProgress value)
|
||||
{
|
||||
if (ReferenceEquals(progress, value)) return;
|
||||
if (progress != null) progress.OnDebugMessageChanged -= OnDebugMessage;
|
||||
progress = value;
|
||||
if (progress != null) progress.OnDebugMessageChanged += OnDebugMessage;
|
||||
}
|
||||
|
||||
private void OnDebugMessage(object sender, EventArgsDebug e)
|
||||
{
|
||||
if (!e.Slot.HasValue || e.Slot.Value <= 0) return;
|
||||
lock (logLock)
|
||||
{
|
||||
if (!acceptingLogs) return;
|
||||
if (pending.Count >= 5000) { pending.Dequeue(); dropped++; }
|
||||
pending.Enqueue(new KeyValuePair<int, string>(e.Slot.Value, string.Format("{0:HH:mm:ss.fff} [{1}] {2}", DateTime.Now, e.Source, e.Value)));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSimulationLog(int slot, string message)
|
||||
{
|
||||
lock (logLock)
|
||||
{
|
||||
if (!acceptingLogs) return;
|
||||
if (pending.Count >= 5000) { pending.Dequeue(); dropped++; }
|
||||
pending.Enqueue(new KeyValuePair<int, string>(slot, DateTime.Now.ToString("HH:mm:ss.fff") + " " + message));
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshTick(object sender, EventArgs e)
|
||||
{
|
||||
if (bridge == null) return;
|
||||
try
|
||||
{
|
||||
var api = bridge.IsSimulation ? null : bridge.gciExternalInterface;
|
||||
var slots = bridge.GetMeterBatchDebugStatuses();
|
||||
slotsGrid.DataSource = slots;
|
||||
workersGrid.DataSource = bridge.GetWorkerDebugStatuses();
|
||||
var selected = new HashSet<int>((slots ?? new List<GenesisCordonelInterface.API.PublicModels.MeterBatchDebugStatus>()).Where(s => s.Selected).Select(s => s.Slot));
|
||||
foreach (int slot in batchState.Slots.Where(batchState.IsExcluded)) selected.Add(slot);
|
||||
foreach (int slot in batchState.Slots.Where(slot => batchState.Phase(slot, activity) == "Running")) selected.Add(slot);
|
||||
foreach (int slot in selected.OrderBy(s => s))
|
||||
{
|
||||
if (!pages.ContainsKey(slot)) CreateSlot(slot);
|
||||
if (!slotTabs.TabPages.Contains(pages[slot])) slotTabs.TabPages.Add(pages[slot]);
|
||||
bool excluded = batchState.IsExcluded(slot);
|
||||
states[slot].Text = excluded ? "Excluded from further preadjustment phases in this batch" : activity;
|
||||
states[slot].BackColor = excluded ? Color.FromArgb(253, 226, 226) : Color.FromArgb(255, 237, 213);
|
||||
states[slot].ForeColor = excluded ? Color.DarkRed : Color.FromArgb(124, 65, 12);
|
||||
foreach (var phase in phaseLabels[slot])
|
||||
{
|
||||
string state = batchState.Phase(slot, "Preadjustment " + phase.Key);
|
||||
phase.Value.Text = phase.Key + Environment.NewLine + (excluded && state == "Pending" ? "Excluded" : state);
|
||||
phase.Value.BackColor = state == "Passed" ? Color.FromArgb(209, 250, 229) : state == "Failed" ? Color.FromArgb(254, 202, 202) : state == "Running" ? Color.FromArgb(255, 214, 153) : Color.FromArgb(235, 239, 244);
|
||||
phase.Value.ForeColor = state == "Passed" ? Color.FromArgb(6, 95, 70) : state == "Failed" ? Color.FromArgb(153, 27, 27) : state == "Running" ? Color.FromArgb(146, 64, 14) : Color.FromArgb(80, 95, 115);
|
||||
}
|
||||
foreach (DataGridViewRow row in slotsGrid.Rows)
|
||||
{
|
||||
if (row.Cells["Slot"].Value != null && Convert.ToInt32(row.Cells["Slot"].Value) == slot && excluded)
|
||||
{
|
||||
row.Cells["Selected"].Value = false;
|
||||
row.DefaultCellStyle.BackColor = Color.FromArgb(253, 226, 226);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (int slot in pages.Keys.Where(s => !selected.Contains(s)).ToArray()) slotTabs.TabPages.Remove(pages[slot]);
|
||||
slotTabs.Invalidate();
|
||||
statusLabel.Text = string.Format("Selected slots: {0} | Refresh: {1:HH:mm:ss} | Dropped log messages: {2}", selected.Count, DateTime.Now, dropped);
|
||||
}
|
||||
catch (Exception ex) { statusLabel.Text = "Diagnostics: " + ex.Message; }
|
||||
FlushLogs();
|
||||
}
|
||||
|
||||
private void CreateSlot(int slot)
|
||||
{
|
||||
var page = new TabPage("Slot " + slot) { Tag = slot, BackColor = Color.White };
|
||||
phaseLabels[slot] = new Dictionary<string, Label>();
|
||||
var phasePanel = new FlowLayoutPanel { Dock = DockStyle.Top, Height = 100, AutoScroll = true };
|
||||
foreach (string phase in Phases)
|
||||
{
|
||||
bool current = string.Equals(activity, "Preadjustment " + phase, StringComparison.OrdinalIgnoreCase);
|
||||
var label = new Label { Text = phase + (current ? "\nRunning" : "\nPending"), AutoSize = false, Size = new Size(145, 60), TextAlign = ContentAlignment.MiddleCenter, BackColor = Color.FromArgb(235, 239, 244), Margin = new Padding(5), Font = new Font("Segoe UI", 9F, FontStyle.Bold) };
|
||||
phasePanel.Controls.Add(label);
|
||||
phaseLabels[slot].Add(phase, label);
|
||||
if (current) activePhases[slot] = label;
|
||||
}
|
||||
var state = new Label { Dock = DockStyle.Top, Height = 30, TextAlign = ContentAlignment.MiddleLeft };
|
||||
var memo = new RichTextBox { Dock = DockStyle.Fill, ReadOnly = true, WordWrap = false, DetectUrls = false, BackColor = Color.White, Font = new Font("Consolas", 9), HideSelection = false };
|
||||
page.Controls.Add(memo);
|
||||
page.Controls.Add(state);
|
||||
page.Controls.Add(phasePanel);
|
||||
pages.Add(slot, page);
|
||||
states.Add(slot, state);
|
||||
memos.Add(slot, memo);
|
||||
}
|
||||
|
||||
private void FlushLogs()
|
||||
{
|
||||
var batch = new List<KeyValuePair<int, string>>();
|
||||
lock (logLock) { while (pending.Count > 0 && batch.Count < 500) batch.Add(pending.Dequeue()); }
|
||||
foreach (var entry in batch) batchState.AddLog(entry.Key, entry.Value);
|
||||
foreach (var pair in memos)
|
||||
{
|
||||
string text = batchState.LogText(pair.Key);
|
||||
if (pair.Value.Text == text) continue;
|
||||
bool atEnd = pair.Value.SelectionStart + pair.Value.SelectionLength >= pair.Value.TextLength;
|
||||
int selection = pair.Value.SelectionStart;
|
||||
pair.Value.Text = text;
|
||||
pair.Value.Select(atEnd ? pair.Value.TextLength : Math.Min(selection, pair.Value.TextLength), 0);
|
||||
if (atEnd) pair.Value.ScrollToCaret();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSlotTab(object sender, DrawItemEventArgs e)
|
||||
{
|
||||
var page = slotTabs.TabPages[e.Index];
|
||||
int slot = (int)page.Tag;
|
||||
bool failed = batchState != null && batchState.IsExcluded(slot);
|
||||
Color color = failed ? Color.FromArgb(185, 28, 28) : e.Index == slotTabs.SelectedIndex ? Color.FromArgb(30, 64, 105) : Color.FromArgb(226, 232, 240);
|
||||
using (var brush = new SolidBrush(color)) e.Graphics.FillRectangle(brush, e.Bounds);
|
||||
TextRenderer.DrawText(e.Graphics, page.Text + (failed ? " !" : ""), Font, e.Bounds, failed || e.Index == slotTabs.SelectedIndex ? Color.White : Color.FromArgb(30, 41, 59), TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
|
||||
}
|
||||
|
||||
public void RefreshProgress()
|
||||
{
|
||||
if (IsDisposed) return;
|
||||
RefreshTick(this, EventArgs.Empty);
|
||||
Update();
|
||||
}
|
||||
|
||||
private void FormLoaded(object sender, EventArgs e)
|
||||
{
|
||||
if (bridge == null) return;
|
||||
// Fit the results region, keeping the top toolbar and right TBF controls visible.
|
||||
var ownerArea = Owner == null ? Screen.FromControl(this).WorkingArea : Owner.RectangleToScreen(Owner.ClientRectangle);
|
||||
var workArea = Screen.FromControl(Owner ?? this).WorkingArea;
|
||||
int topInset = (int)Math.Round(ownerArea.Height * 0.09);
|
||||
int rightInset = (int)Math.Round(ownerArea.Width * 0.125);
|
||||
StartPosition = FormStartPosition.Manual;
|
||||
WindowState = FormWindowState.Normal;
|
||||
MinimumSize = new Size(640, 360);
|
||||
Bounds = Rectangle.Intersect(workArea, new Rectangle(ownerArea.Left, ownerArea.Top + topInset, ownerArea.Width - rightInset, ownerArea.Height - topInset - 24));
|
||||
RefreshTick(sender, e);
|
||||
refreshTimer.Start();
|
||||
}
|
||||
|
||||
private void GenesisCommunicationDiagnosticsForm_FormClosed(object sender, FormClosedEventArgs e)
|
||||
private void OpenBridge(object sender, EventArgs e)
|
||||
{
|
||||
try { if (bridge != null) bridge.ShowGui(); }
|
||||
catch (Exception ex) { statusLabel.Text = "GCI GUI: " + ex.Message; }
|
||||
}
|
||||
|
||||
private void ReleaseDiagnostics()
|
||||
{
|
||||
refreshTimer.Stop();
|
||||
}
|
||||
|
||||
private void refreshTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
RefreshDiagnostics();
|
||||
}
|
||||
|
||||
private void refreshToolStripButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
RefreshDiagnostics();
|
||||
}
|
||||
|
||||
private void showBridgeToolStripButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
bridge.ShowGui();
|
||||
}
|
||||
|
||||
private void RefreshDiagnostics()
|
||||
{
|
||||
try
|
||||
lock (logLock) { acceptingLogs = false; }
|
||||
if (batchState != null)
|
||||
{
|
||||
var api = bridge.gciExternalInterface;
|
||||
List<GciPublicModels.MeterBatchDebugStatus> slotStatuses = api == null
|
||||
? new List<GciPublicModels.MeterBatchDebugStatus>()
|
||||
: api.GetMeterBatchDebugStatuses() ?? new List<GciPublicModels.MeterBatchDebugStatus>();
|
||||
List<GciPublicModels.WorkerDebugStatus> workerStatuses = api == null
|
||||
? new List<GciPublicModels.WorkerDebugStatus>()
|
||||
: api.GetWorkerDebugStatuses() ?? new List<GciPublicModels.WorkerDebugStatus>();
|
||||
|
||||
slotsDataGridView.DataSource = slotStatuses;
|
||||
workersDataGridView.DataSource = workerStatuses;
|
||||
statusToolStripStatusLabel.Text = string.Format("Updated {0:HH:mm:ss.fff} | Slots: {1} | Workers: {2}", DateTime.Now, slotStatuses.Count, workerStatuses.Count);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
statusToolStripStatusLabel.Text = "Diagnostic refresh failed: " + ex.Message;
|
||||
// No producer can append after acceptingLogs is cleared.
|
||||
do { FlushLogs(); } while (pending.Count > 0);
|
||||
}
|
||||
AttachProgress(null);
|
||||
if (bridge != null) bridge.SimulationLog -= OnSimulationLog;
|
||||
foreach (var page in pages.Values) page.Dispose();
|
||||
pages.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-58
@@ -1,61 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="resmimetype"><value>text/microsoft-resx</value></resheader>
|
||||
<resheader name="version"><value>2.0</value></resheader>
|
||||
<resheader name="reader"><value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader>
|
||||
<resheader name="writer"><value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader>
|
||||
</root>
|
||||
|
||||
@@ -10,6 +10,7 @@ using Config.Entities;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.TestMethods.iPerlCommunication;
|
||||
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
{
|
||||
@@ -29,6 +30,11 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
public bool SimultWithNext;
|
||||
public string MeterSize = "DN50";
|
||||
public float Temperature = 20.0f;
|
||||
public int SimulationDurationMs = 5000;
|
||||
public bool SimulationSuccess = true;
|
||||
public string SimulationErrorMessage = "";
|
||||
[XmlIgnore]
|
||||
public bool ShowSimulationParameters;
|
||||
|
||||
public override void InitializeAll()
|
||||
{
|
||||
@@ -37,6 +43,9 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
SimultWithNext = false;
|
||||
MeterSize = "DN50";
|
||||
Temperature = 20.0f;
|
||||
SimulationDurationMs = 5000;
|
||||
SimulationSuccess = true;
|
||||
SimulationErrorMessage = "";
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +56,12 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
Strings.Simultaneous_with_next_step,
|
||||
"Meter size",
|
||||
"Temperature [°C]",
|
||||
"Simulation duration [ms]",
|
||||
"Simulation Success",
|
||||
"Simulation ErrorMessage",
|
||||
};
|
||||
public override string ParamName(int i) { return paramNames[i]; }
|
||||
public override int ParamsCount() { return paramNames.Length; }
|
||||
public override int ParamsCount() { return ShowSimulationParameters ? paramNames.Length : 5; }
|
||||
|
||||
public override ICollection<string> ParamValues(int i)
|
||||
{
|
||||
@@ -140,14 +152,14 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
|
||||
return retVal;
|
||||
}
|
||||
else if (i == 1 || i == 2)
|
||||
else if (i == 1 || i == 2 || i == 6)
|
||||
{
|
||||
return new string[] { Strings.yes, Strings.no };
|
||||
}
|
||||
else if (i == 3)
|
||||
{
|
||||
var meterSizes = new List<string>(System.Enum.GetNames(typeof(Xylem.Common.Logic.ProductionOrderCore.OrderData.MeterSize)));
|
||||
meterSizes.Remove(Xylem.Common.Logic.ProductionOrderCore.OrderData.MeterSize.NA.ToString());
|
||||
var meterSizes = new List<string>(System.Enum.GetNames(typeof(MeterSize)));
|
||||
meterSizes.RemoveAll(value => value.EndsWith("MAX", System.StringComparison.OrdinalIgnoreCase));
|
||||
return meterSizes;
|
||||
}
|
||||
|
||||
@@ -163,6 +175,9 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
case 2: return (SimultWithNext ? Strings.yes : Strings.no);
|
||||
case 3: return MeterSize;
|
||||
case 4: return Temperature.ToString();
|
||||
case 5: return SimulationDurationMs.ToString();
|
||||
case 6: return SimulationSuccess ? Strings.yes : Strings.no;
|
||||
case 7: return SimulationErrorMessage;
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -176,6 +191,9 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
case 2: SimultWithNext = strValue.ToLower().Equals(Strings.yes.ToLower()); return CfgUpdateFlags.None;
|
||||
case 3: MeterSize = strValue; return CfgUpdateFlags.None;
|
||||
case 4: Temperature = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 5: SimulationDurationMs = int.Parse(strValue); return CfgUpdateFlags.None;
|
||||
case 6: SimulationSuccess = strValue.Equals(Strings.yes, System.StringComparison.OrdinalIgnoreCase); return CfgUpdateFlags.None;
|
||||
case 7: SimulationErrorMessage = strValue; return CfgUpdateFlags.None;
|
||||
default: return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
@@ -191,13 +209,19 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
return true;
|
||||
case 1:
|
||||
case 2:
|
||||
case 6:
|
||||
if (strValue.Equals(Strings.yes) || strValue.Equals(Strings.no)) return true;
|
||||
break;
|
||||
case 3:
|
||||
return System.Enum.TryParse(strValue, true, out Xylem.Common.Logic.ProductionOrderCore.OrderData.MeterSize meterSize) && meterSize != Xylem.Common.Logic.ProductionOrderCore.OrderData.MeterSize.NA;
|
||||
MeterSize meterSize;
|
||||
return System.Enum.TryParse(strValue, true, out meterSize) && !meterSize.ToString().EndsWith("MAX", System.StringComparison.OrdinalIgnoreCase);
|
||||
case 4:
|
||||
if (Utils.TryParseSFloat(strValue, out temperature) && temperature >= -20.0f && temperature <= 100.0f) return true;
|
||||
break;
|
||||
case 5:
|
||||
int duration;
|
||||
return int.TryParse(strValue, out duration) && duration >= 0;
|
||||
case 7: return true;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
@@ -214,12 +238,16 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
prms.SimultWithNext = this.SimultWithNext;
|
||||
prms.MeterSize = this.MeterSize;
|
||||
prms.Temperature = this.Temperature;
|
||||
prms.SimulationDurationMs = SimulationDurationMs;
|
||||
prms.SimulationSuccess = SimulationSuccess;
|
||||
prms.SimulationErrorMessage = SimulationErrorMessage;
|
||||
}
|
||||
|
||||
public IParamsProvider Clone()
|
||||
{
|
||||
iPerlCommunicationParams pars = new iPerlCommunicationParams();
|
||||
CopyContentTo(pars);
|
||||
pars.ShowSimulationParameters = ShowSimulationParameters;
|
||||
return pars;
|
||||
}
|
||||
|
||||
|
||||
@@ -249,6 +249,7 @@
|
||||
<Compile Include="Rig\Ambient\Greco\Factory.cs" />
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\Factory.cs" />
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\GciBridge.cs" />
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\GciBridge.Simulation.cs" />
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\GciBridgeCfg.cs" />
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\GciBridgeCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
@@ -257,6 +258,7 @@
|
||||
<DependentUpon>GciBridgeCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\GciBridgeOp.cs" />
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\GciSimulationSettings.cs" />
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\Interfaces\PublicModels.cs" />
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\Debug\DebugModels.cs" />
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\Debug\MeterBatchConfigPanel.cs">
|
||||
@@ -2001,6 +2003,7 @@
|
||||
<Compile Include="Rig\TestMethods\AllyCalibration\TestMethodParams.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\Factory.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisCommunicationSeq.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisPreadjustmentBatchState.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\iPerlCommunicationParams.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\SequenceConditionOp.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\TestMethod.cs" />
|
||||
|
||||
Reference in New Issue
Block a user