Compare commits
4 Commits
5e637ae02e
...
9700ba7900
| Author | SHA1 | Date | |
|---|---|---|---|
| 9700ba7900 | |||
| bc72130d09 | |||
| ad208f9633 | |||
| ad2bfd3639 |
@ -1,9 +1,15 @@
|
||||
using GenesisCordonelInterface.Core.Threading;
|
||||
using CordonelPreadjustmentUi;
|
||||
using CordonelPreadjustmentUi.Processes;
|
||||
using CordonelPreadjustmentUi.Processes.Actions;
|
||||
using CordonelPreadjustmentUi.Processes.Itinerary;
|
||||
using GenesisCordonelInterface.Core.Threading;
|
||||
using GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI;
|
||||
using NLog;
|
||||
using NLog.Fluent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@ -16,7 +22,9 @@ using Xylem.Common.Hardware.Interfaces.Ports.PortCore.EventArguments;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters;
|
||||
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||
using static GenesisCordonelInterface.API.PublicModels;
|
||||
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
|
||||
using static Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Register;
|
||||
@ -30,8 +38,14 @@ namespace GenesisCordonelInterface.API
|
||||
//private static readonly Lazy<ILogger> Logger = new Lazy<ILogger>(() => LogManager.GetLogger("GCI"));
|
||||
private static readonly NLog.ILogger Logger = NLog.LogManager.GetLogger("GenesisCordonelInterface");
|
||||
|
||||
//GenesisToolBox
|
||||
private readonly MeterBatch _meterBatch = new MeterBatch();
|
||||
|
||||
//Preadjustment
|
||||
public PreAdjustmentSettingsContainer _settings = new PreAdjustmentSettingsContainer();
|
||||
public List<MeterStateControl> _meterControls = new List<MeterStateControl>();
|
||||
public List<MeterStateControl> _tempMeterControls = new List<MeterStateControl>();
|
||||
|
||||
// Protects all access to _meterBatch.ListOfMeters
|
||||
private readonly object _meterBatchLock = new object();
|
||||
private static readonly object _setupGenesisMeterLock = new object();
|
||||
@ -75,16 +89,19 @@ namespace GenesisCordonelInterface.API
|
||||
#endregion
|
||||
|
||||
#region ================================== MeterBatch Debug ==================================
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<MeterBatchDebugStatus> GetMeterBatchDebugStatuses()
|
||||
{
|
||||
List<GenesisMeter> meters;
|
||||
List<ZeroFlowGenesisMeter> meters;
|
||||
|
||||
//just snapshot of list under lock
|
||||
lock (_meterBatchLock)
|
||||
{
|
||||
meters = _meterBatch.ListOfMeters
|
||||
.OfType<GenesisMeter>()
|
||||
.OfType<ZeroFlowGenesisMeter>()
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@ -152,7 +169,7 @@ namespace GenesisCordonelInterface.API
|
||||
lock (_meterBatchLock)
|
||||
{
|
||||
return _meterBatch.ListOfMeters
|
||||
.OfType<GenesisMeter>()
|
||||
.OfType<ZeroFlowGenesisMeter>()
|
||||
.FirstOrDefault(m => m.Slot == slot);
|
||||
}
|
||||
}
|
||||
@ -193,7 +210,7 @@ namespace GenesisCordonelInterface.API
|
||||
{
|
||||
lock (_meterBatchLock)
|
||||
{
|
||||
foreach (var meter in _meterBatch.ListOfMeters.OfType<GenesisMeter>())
|
||||
foreach (var meter in _meterBatch.ListOfMeters.OfType<ZeroFlowGenesisMeter>())
|
||||
{
|
||||
meter.DisposeMeter();
|
||||
}
|
||||
@ -228,6 +245,16 @@ namespace GenesisCordonelInterface.API
|
||||
return string.IsNullOrWhiteSpace(port) ? "<empty>" : port;
|
||||
}
|
||||
|
||||
public ConcurrentDictionary<RegisterDefinition, Byte[]> GetRegistersDicForSlot(int slot)
|
||||
{
|
||||
var meter = GetMeterThreadSafe(slot);
|
||||
|
||||
if (meter == null)
|
||||
throw new Exception($"Slot {slot} not initialized.");
|
||||
|
||||
return meter.GetRegistersDic();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================================== INIT/UPDATE ==================================
|
||||
@ -345,7 +372,7 @@ namespace GenesisCordonelInterface.API
|
||||
PortConfig? req,
|
||||
PortConfig? str)
|
||||
{
|
||||
GenesisMeter meter = new GenesisMeter();
|
||||
ZeroFlowGenesisMeter meter = new ZeroFlowGenesisMeter(0, 3, !(_meterControls is TempMeterStateControl), useForPreadjustmentUI: false);
|
||||
|
||||
meter.Slot = slot;
|
||||
|
||||
@ -354,7 +381,8 @@ namespace GenesisCordonelInterface.API
|
||||
meter.requestPortConfig = req;
|
||||
meter.streamingPortConfig = str;
|
||||
|
||||
//meter.SetupGenesisMeter(slot, req, str, true);
|
||||
meter.onlineOperation = false;
|
||||
|
||||
lock (_meterBatchLock)
|
||||
{
|
||||
_meterBatch.AddMeter2(meter);
|
||||
@ -942,9 +970,17 @@ namespace GenesisCordonelInterface.API
|
||||
|
||||
var meter = GetMeterThreadSafe(slot);
|
||||
|
||||
meter.Logout();
|
||||
bool logoutSuccess = meter.Logout();
|
||||
meter.Disconnect();
|
||||
|
||||
if (meter.IsLoggedOn)
|
||||
{
|
||||
meter.MarkLoggedOut();
|
||||
meter.LastLogoutStatus = logoutSuccess
|
||||
? "Successfully logged out"
|
||||
: "Logout failed, but connection was closed";
|
||||
}
|
||||
|
||||
bool success = !meter.IsConnected && !meter.IsLoggedOn;
|
||||
|
||||
if (success)
|
||||
@ -1370,5 +1406,812 @@ namespace GenesisCordonelInterface.API
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// GCI to PreadjustmentUI - MANUAL - Laatzen GUI
|
||||
|
||||
#region ================================== PreAdjustmentUI form call ==================================
|
||||
|
||||
private FrmCordonelPreadjustmentUI _preadjustmentForm;
|
||||
private readonly object _formLock = new object();
|
||||
|
||||
public event EventHandler PreadjustmentFormClosedByUser;
|
||||
|
||||
/// <summary>
|
||||
/// Shows singleton instance of preadjustment form.
|
||||
///
|
||||
/// Behavior:
|
||||
///
|
||||
/// ShowPreadjustmentForm()
|
||||
/// ↓
|
||||
/// create form instance if necessary
|
||||
/// ↓
|
||||
/// user works with form
|
||||
/// ↓
|
||||
/// user clicks X
|
||||
/// ↓
|
||||
/// FormClosing
|
||||
/// ↓
|
||||
/// Cancel closing
|
||||
/// ↓
|
||||
/// Hide()
|
||||
/// ↓
|
||||
/// PreadjustmentFormClosedByUser
|
||||
/// ↓
|
||||
/// external workflow continues
|
||||
///
|
||||
/// Notes:
|
||||
/// - form instance is reused
|
||||
/// - form is hidden instead of disposed
|
||||
/// - event notification is non-blocking
|
||||
/// - repeated calls bring existing form to front
|
||||
/// - actual disposal happens only during application shutdown
|
||||
///
|
||||
/// Typical usage:
|
||||
///
|
||||
/// _bridge.PreadjustmentFormClosedByUser += (s,e)=>
|
||||
/// {
|
||||
/// ContinueWorkflow();
|
||||
/// };
|
||||
///
|
||||
/// _bridge.ShowPreadjustmentForm(this);
|
||||
///
|
||||
/// </summary>
|
||||
public void ShowPreadjustmentForm(IWin32Window owner)
|
||||
{
|
||||
lock (_formLock)
|
||||
{
|
||||
// Create form only if it does not exist
|
||||
// or has already been disposed
|
||||
if (_preadjustmentForm == null || _preadjustmentForm.IsDisposed)
|
||||
{
|
||||
_preadjustmentForm = new FrmCordonelPreadjustmentUI(_meterBatch);
|
||||
|
||||
_preadjustmentForm.FormClosing += (s, e) =>
|
||||
{
|
||||
// Hide the form instead of destroying it
|
||||
// when user clicks the close button
|
||||
if (e.CloseReason == CloseReason.UserClosing)
|
||||
{
|
||||
e.Cancel = true;
|
||||
_preadjustmentForm.Hide();
|
||||
|
||||
// Notify outside code that the form was closed by user
|
||||
PreadjustmentFormClosedByUser?.Invoke(
|
||||
this,
|
||||
EventArgs.Empty);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// If already visible, bring it to front
|
||||
if (_preadjustmentForm.Visible)
|
||||
{
|
||||
_preadjustmentForm.Activate();
|
||||
_preadjustmentForm.BringToFront();
|
||||
return;
|
||||
}
|
||||
|
||||
// Show existing form instance
|
||||
_preadjustmentForm.Show(owner);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================================== Create context for PreAdjustmentUI ==================================
|
||||
|
||||
/*public interface IGciToolContext
|
||||
{
|
||||
IReadOnlyList<int> GetEnabledSlots();
|
||||
|
||||
string GetPcbId(int slot);
|
||||
string GetSerialNumber(int slot);
|
||||
|
||||
bool Login(int slot);
|
||||
bool Logout(int slot);
|
||||
|
||||
bool ReadRegister(int slot, int address, out string value);
|
||||
bool WriteRegister(int slot, int address, string value);
|
||||
|
||||
void LogInfo(string message);
|
||||
void LogError(string message);
|
||||
|
||||
event EventHandler<GciMeterChangedEventArgs> MeterChanged;
|
||||
}*/
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
// GCI to PreadjustmentUI - AUTOMATIC - STANDALONE - Laatzen GUI
|
||||
|
||||
#region ================================== PreAdjustmentUI DETECT process ==================================
|
||||
|
||||
public Task<PreadjustmentDetectResult> Preadjustment_DetectAsync(
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return Task.Run(() => Preadjustment_DetectCore(token), token);
|
||||
}
|
||||
|
||||
private PreadjustmentDetectResult Preadjustment_DetectCore(
|
||||
CancellationToken token)
|
||||
{
|
||||
const string operation = nameof(Preadjustment_DetectCore);
|
||||
|
||||
try
|
||||
{
|
||||
MeterBatch globalMeterBatch = new MeterBatch();
|
||||
MeterBatch thermoMeterBatch = new MeterBatch();
|
||||
|
||||
if (_settings == null)
|
||||
throw new ArgumentNullException(nameof(_settings));
|
||||
|
||||
if (_meterControls == null)
|
||||
throw new ArgumentNullException(nameof(_meterControls));
|
||||
|
||||
if (_tempMeterControls == null)
|
||||
_tempMeterControls = new List<MeterStateControl>();
|
||||
|
||||
if (globalMeterBatch.ListOfMeters.Any())
|
||||
globalMeterBatch.RemoveAllMeters();
|
||||
|
||||
if (thermoMeterBatch.ListOfMeters.Any())
|
||||
thermoMeterBatch.RemoveAllMeters();
|
||||
|
||||
globalMeterBatch = _meterBatch;
|
||||
|
||||
if (!_settings.GetTempUseTempFlansh())
|
||||
_tempMeterControls.Clear();
|
||||
|
||||
var allMeterControls = new List<MeterStateControl>();
|
||||
|
||||
allMeterControls.AddRange(_meterControls);
|
||||
allMeterControls.AddRange(_tempMeterControls);
|
||||
|
||||
CreateZeroFlowMeters(
|
||||
globalMeterBatch,
|
||||
thermoMeterBatch,
|
||||
allMeterControls,
|
||||
token);
|
||||
|
||||
SetEnableOpeningState(allMeterControls);
|
||||
|
||||
if (!_meterControls.Any(a => a.EnableOpening))
|
||||
{
|
||||
return new PreadjustmentDetectResult
|
||||
{
|
||||
Success = false,
|
||||
DetectedMeterCount = 0,
|
||||
DetectedThermometerCount = _tempMeterControls.Count(t => t.IsEnabled),
|
||||
ErrorMessage = "No enabled meter found."
|
||||
};
|
||||
}
|
||||
|
||||
SetUnknownStatus(allMeterControls);
|
||||
|
||||
CheckTemperatureMeters(
|
||||
_settings,
|
||||
_tempMeterControls,
|
||||
token);
|
||||
|
||||
return new PreadjustmentDetectResult
|
||||
{
|
||||
Success = true,
|
||||
DetectedMeterCount = _meterControls.Count(m => m.IsEnabled),
|
||||
DetectedThermometerCount = _tempMeterControls.Count(t => t.IsEnabled)
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new PreadjustmentDetectResult
|
||||
{
|
||||
Success = false,
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateZeroFlowMeters(
|
||||
MeterBatch globalMeterBatch,
|
||||
MeterBatch thermoMeterBatch,
|
||||
List<MeterStateControl> allMeterControls,
|
||||
CancellationToken token)
|
||||
{
|
||||
foreach (var meterStateCtl in allMeterControls)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
if (!(meterStateCtl.IsEnabled ||
|
||||
meterStateCtl is TempMeterStateControl))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (meterStateCtl.Slot == -1)
|
||||
continue;
|
||||
|
||||
ZeroFlowGenesisMeter currentMeter = new ZeroFlowGenesisMeter(meterStateCtl.Slot, 3, !(meterStateCtl is TempMeterStateControl));
|
||||
|
||||
var convertedMeter = GetMeterThreadSafe(meterStateCtl.Slot);
|
||||
if (convertedMeter != null)
|
||||
{
|
||||
convertedMeter.CopySafeStateTo(currentMeter);
|
||||
}
|
||||
|
||||
currentMeter.LogOnEnable = true;
|
||||
currentMeter.LoginFailed = false;
|
||||
currentMeter.PreparationFailed = false;
|
||||
currentMeter.AmplitudeFailed = false;
|
||||
currentMeter.ZeroFlowOffsetFailed = false;
|
||||
currentMeter.CompletionFailed = false;
|
||||
currentMeter.Ok = false;
|
||||
currentMeter.EmptyPipeCheckEnable = false;
|
||||
currentMeter.EmptyPipeCheckFailed = false;
|
||||
|
||||
if (meterStateCtl is TempMeterStateControl)
|
||||
{
|
||||
thermoMeterBatch.AddMeter(currentMeter);
|
||||
meterStateCtl.IsEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentMeter.useConfigSource != ConfigSource.InterfaceInputConfig)
|
||||
globalMeterBatch.AddMeter(currentMeter);
|
||||
else
|
||||
globalMeterBatch.AddMeter2(currentMeter);
|
||||
}
|
||||
|
||||
meterStateCtl.Meter = currentMeter;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetEnableOpeningState(
|
||||
List<MeterStateControl> allMeterControls)
|
||||
{
|
||||
foreach (var meterState in allMeterControls)
|
||||
{
|
||||
meterState.EnableOpening =
|
||||
meterState.IsEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetUnknownStatus(
|
||||
List<MeterStateControl> allMeterControls)
|
||||
{
|
||||
foreach (var meterState in allMeterControls)
|
||||
{
|
||||
meterState.SetToUnknownStatus =
|
||||
!meterState.EnableOpening;
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckNormalMeters(
|
||||
List<MeterStateControl> meterControls,
|
||||
CancellationToken token)
|
||||
{
|
||||
foreach (var meterCtl in meterControls)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
if (meterCtl != null && meterCtl.IsEnabled)
|
||||
{
|
||||
meterCtl.Ok =
|
||||
meterCtl.Meter.CheckRequestPort() &&
|
||||
meterCtl.Meter.CheckStreamingPort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckTemperatureMeters(
|
||||
PreAdjustmentSettingsContainer settings,
|
||||
List<MeterStateControl> tempMeterControls,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (settings.GetTempUseManualInput())
|
||||
return;
|
||||
|
||||
foreach (var meterCtl in tempMeterControls)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
if (meterCtl != null && meterCtl.IsEnabled)
|
||||
{
|
||||
meterCtl.Ok =
|
||||
meterCtl.Meter.CheckStreamingPort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================================== PreAdjustmentUI PREPARATION process ==================================
|
||||
public Task<PreadjustmentProcessResult> Preadjustment_PreparationAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetWorker(slot).RunAsync(
|
||||
() => Preadjustment_Preparation(slot, pp),
|
||||
token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes standalone preparation process.
|
||||
/// </summary>
|
||||
public PreadjustmentProcessResult Preadjustment_Preparation(
|
||||
int slot,
|
||||
ProcessProgress pp)
|
||||
{
|
||||
const string operation = nameof(Preadjustment_Preparation);
|
||||
|
||||
try
|
||||
{
|
||||
LogInfo(operation, $"Start. Slot={slot}");
|
||||
|
||||
var meter = GetMeterThreadSafe(slot);
|
||||
EnsureConnected(meter);
|
||||
|
||||
BaseProcess process =
|
||||
CreatePreparationProcess(pp);
|
||||
|
||||
bool success =
|
||||
ExecuteProcess(process, pp);
|
||||
|
||||
var result =
|
||||
new PreadjustmentProcessResult
|
||||
{
|
||||
Success = success,
|
||||
Slot = slot,
|
||||
ProcessName = process.ProcessName,
|
||||
ErrorMessage = success
|
||||
? null
|
||||
: process.FailedMessage
|
||||
};
|
||||
|
||||
LogInfo(operation, result.ToString());
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError(operation, ex);
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = false,
|
||||
Slot = slot,
|
||||
ProcessName = "Preparation",
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates preparation process instance based on current configuration.
|
||||
/// </summary>
|
||||
/// <param name="pp">Current process progress context</param>
|
||||
/// <returns>Configured preparation process</returns>
|
||||
private BaseProcess CreatePreparationProcess(ProcessProgress pp)
|
||||
{
|
||||
if (pp.Setting.NumberOfPaths == 1)
|
||||
{
|
||||
return new SPPreparationProcess(
|
||||
"Preparation Single",
|
||||
PreAdjustmentControl.StatusPanelItems.Prepare,
|
||||
PreAdjustmentControl.PredefinedMessages.WaitUntilPreparationFinished(pp.Setting.Culture),
|
||||
PreAdjustmentControl.PredefinedMessages.PreparationFailed(pp.Setting.Culture),
|
||||
60);
|
||||
}
|
||||
|
||||
return new PreparationProcess(
|
||||
"Preparation",
|
||||
PreAdjustmentControl.StatusPanelItems.Prepare,
|
||||
PreAdjustmentControl.PredefinedMessages.WaitUntilPreparationFinished(pp.Setting.Culture),
|
||||
PreAdjustmentControl.PredefinedMessages.PreparationFailed(pp.Setting.Culture),
|
||||
60);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================================== PreAdjustmentUI AMPLITUDE TEST process ==================================
|
||||
public Task<PreadjustmentProcessResult> Preadjustment_AmplitudeTestAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetWorker(slot).RunAsync(
|
||||
() => Preadjustment_AmplitudeTest(slot, pp),
|
||||
token);
|
||||
}
|
||||
|
||||
public PreadjustmentProcessResult Preadjustment_AmplitudeTest(
|
||||
int slot,
|
||||
ProcessProgress pp)
|
||||
{
|
||||
const string operation = nameof(Preadjustment_AmplitudeTest);
|
||||
|
||||
try
|
||||
{
|
||||
LogInfo(operation, $"Start. Slot={slot}");
|
||||
|
||||
var meter = GetMeterThreadSafe(slot);
|
||||
EnsureConnected(meter);
|
||||
|
||||
if (pp.Setting.TempOnly)
|
||||
{
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = true,
|
||||
Slot = slot,
|
||||
ProcessName = "Amplitude Test"
|
||||
};
|
||||
}
|
||||
|
||||
BaseProcess process = CreateAmplitudeTestProcess(pp);
|
||||
|
||||
bool success = ExecuteProcess(process, pp);
|
||||
|
||||
LogInfo(operation, $"Finished. Slot={slot}, Success={success}");
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = success,
|
||||
Slot = slot,
|
||||
ProcessName = process.ProcessName,
|
||||
ErrorMessage = success ? null : process.FailedMessage
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError(operation, ex);
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = false,
|
||||
Slot = slot,
|
||||
ProcessName = "Amplitude Test",
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates amplitude test process instance based on current configuration.
|
||||
/// </summary>
|
||||
/// <param name="pp">Current process progress context</param>
|
||||
/// <returns>Configured amplitude test process</returns>
|
||||
private BaseProcess CreateAmplitudeTestProcess(ProcessProgress pp)
|
||||
{
|
||||
if (pp.Setting.NumberOfPaths == 1)
|
||||
{
|
||||
return new SPAmplitudeTestProcess(
|
||||
"Amplitude Test Single",
|
||||
PreAdjustmentControl.StatusPanelItems.Amplitude,
|
||||
PreAdjustmentControl.PredefinedMessages.WaitUntilAmplitudeTestFinished(pp.Setting.Culture),
|
||||
PreAdjustmentControl.PredefinedMessages.AmplitudeFailed(pp.Setting.Culture),
|
||||
4 * 60);
|
||||
}
|
||||
|
||||
return new AmplitudeTestProcess(
|
||||
"Amplitude Test",
|
||||
PreAdjustmentControl.StatusPanelItems.Amplitude,
|
||||
PreAdjustmentControl.PredefinedMessages.WaitUntilAmplitudeTestFinished(pp.Setting.Culture),
|
||||
PreAdjustmentControl.PredefinedMessages.AmplitudeFailed(pp.Setting.Culture),
|
||||
4 * 60);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================================== PreAdjustmentUI TEMPERATURE CALIBRATION process ==================================
|
||||
|
||||
public Task<PreadjustmentProcessResult> Preadjustment_TemperatureCalibrationAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetWorker(slot).RunAsync(
|
||||
() => Preadjustment_TemperatureCalibration(slot, pp),
|
||||
token);
|
||||
}
|
||||
|
||||
public PreadjustmentProcessResult Preadjustment_TemperatureCalibration(
|
||||
int slot,
|
||||
ProcessProgress pp)
|
||||
{
|
||||
const string operation =
|
||||
nameof(Preadjustment_TemperatureCalibration);
|
||||
|
||||
try
|
||||
{
|
||||
LogInfo(operation, $"Start. Slot={slot}");
|
||||
|
||||
var meter =
|
||||
GetMeterThreadSafe(slot);
|
||||
|
||||
EnsureConnected(meter);
|
||||
|
||||
BaseProcess process =
|
||||
CreateTemperatureCalibrationProcess(pp);
|
||||
|
||||
bool success =
|
||||
ExecuteProcess(process, pp);
|
||||
|
||||
var result =
|
||||
new PreadjustmentProcessResult
|
||||
{
|
||||
Success = success,
|
||||
Slot = slot,
|
||||
ProcessName = process.ProcessName,
|
||||
ErrorMessage = success
|
||||
? null
|
||||
: process.FailedMessage
|
||||
};
|
||||
|
||||
LogInfo(operation, result.ToString());
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError(operation, ex);
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = false,
|
||||
Slot = slot,
|
||||
ProcessName = "Temperature Calibration",
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates temperature calibration process instance based on current configuration.
|
||||
/// </summary>
|
||||
/// <param name="pp">Current process progress context</param>
|
||||
/// <returns>Configured temperature calibration process</returns>
|
||||
private BaseProcess CreateTemperatureCalibrationProcess(ProcessProgress pp)
|
||||
{
|
||||
if (pp.Setting.NumberOfPaths == 1)
|
||||
{
|
||||
return new SPTemperatureCalibrationProcess(
|
||||
"Temperature Calibration Single",
|
||||
PreAdjustmentControl.StatusPanelItems.TempCal,
|
||||
PreAdjustmentControl.PredefinedMessages.WaitUntilTemperatureCalibrationFinished(pp.Setting.Culture),
|
||||
PreAdjustmentControl.PredefinedMessages.TempCalFailed(pp.Setting.Culture),
|
||||
2 * 60);
|
||||
}
|
||||
|
||||
return new TemperatureCalibrationProcess(
|
||||
"Temperature Calibration",
|
||||
PreAdjustmentControl.StatusPanelItems.TempCal,
|
||||
PreAdjustmentControl.PredefinedMessages.WaitUntilTemperatureCalibrationFinished(pp.Setting.Culture),
|
||||
PreAdjustmentControl.PredefinedMessages.TempCalFailed(pp.Setting.Culture),
|
||||
2 * 60);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================================== PreAdjustmentUI OFFSET TEST process ==================================
|
||||
|
||||
public Task<PreadjustmentProcessResult> Preadjustment_OffsetTestAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetWorker(slot).RunAsync(
|
||||
() => Preadjustment_OffsetTest(slot, pp),
|
||||
token);
|
||||
}
|
||||
|
||||
public PreadjustmentProcessResult Preadjustment_OffsetTest(
|
||||
int slot,
|
||||
ProcessProgress pp)
|
||||
{
|
||||
const string operation =
|
||||
nameof(Preadjustment_OffsetTest);
|
||||
|
||||
try
|
||||
{
|
||||
LogInfo(operation, $"Start. Slot={slot}");
|
||||
|
||||
var meter =
|
||||
GetMeterThreadSafe(slot);
|
||||
|
||||
EnsureConnected(meter);
|
||||
|
||||
if (pp.Setting.TempOnly)
|
||||
{
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = true,
|
||||
Slot = slot,
|
||||
ProcessName = "Offset Test"
|
||||
};
|
||||
}
|
||||
|
||||
BaseProcess process =
|
||||
CreateOffsetTestProcess(pp);
|
||||
|
||||
bool success =
|
||||
ExecuteProcess(process, pp);
|
||||
|
||||
var result =
|
||||
new PreadjustmentProcessResult
|
||||
{
|
||||
Success = success,
|
||||
Slot = slot,
|
||||
ProcessName = process.ProcessName,
|
||||
ErrorMessage = success
|
||||
? null
|
||||
: process.FailedMessage
|
||||
};
|
||||
|
||||
LogInfo(operation, result.ToString());
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError(operation, ex);
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = false,
|
||||
Slot = slot,
|
||||
ProcessName = "Offset Test",
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates offset test process instance based on current configuration.
|
||||
/// </summary>
|
||||
/// <param name="pp">Current process progress context</param>
|
||||
/// <returns>Configured offset test process</returns>
|
||||
private BaseProcess CreateOffsetTestProcess(ProcessProgress pp)
|
||||
{
|
||||
if (pp.Setting.NumberOfPaths == 1)
|
||||
{
|
||||
return new SPOffsetTestProcess(
|
||||
"Offset Test Single",
|
||||
PreAdjustmentControl.StatusPanelItems.Offset,
|
||||
PreAdjustmentControl.PredefinedMessages.WaitUntilZeroflowOffsetTestFinished(pp.Setting.Culture),
|
||||
PreAdjustmentControl.PredefinedMessages.ZeroflowOffsetTestFailed(pp.Setting.Culture),
|
||||
18 * 60);
|
||||
}
|
||||
|
||||
return new OffsetTestProcess(
|
||||
"Offset Test",
|
||||
PreAdjustmentControl.StatusPanelItems.Offset,
|
||||
PreAdjustmentControl.PredefinedMessages.WaitUntilZeroflowOffsetTestFinished(pp.Setting.Culture),
|
||||
PreAdjustmentControl.PredefinedMessages.ZeroflowOffsetTestFailed(pp.Setting.Culture),
|
||||
18 * 60);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================================== PreAdjustmentUI COMPLETION process ==================================
|
||||
|
||||
public Task<PreadjustmentProcessResult> Preadjustment_CompletionAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetWorker(slot).RunAsync(
|
||||
() => Preadjustment_Completion(slot, pp),
|
||||
token);
|
||||
}
|
||||
|
||||
public PreadjustmentProcessResult Preadjustment_Completion(
|
||||
int slot,
|
||||
ProcessProgress pp)
|
||||
{
|
||||
const string operation =
|
||||
nameof(Preadjustment_Completion);
|
||||
|
||||
try
|
||||
{
|
||||
LogInfo(operation, $"Start. Slot={slot}");
|
||||
|
||||
var meter =
|
||||
GetMeterThreadSafe(slot);
|
||||
|
||||
EnsureConnected(meter);
|
||||
|
||||
BaseProcess process =
|
||||
CreateCompletionProcess(pp);
|
||||
|
||||
bool success =
|
||||
ExecuteProcess(process, pp);
|
||||
|
||||
var result =
|
||||
new PreadjustmentProcessResult
|
||||
{
|
||||
Success = success,
|
||||
Slot = slot,
|
||||
ProcessName = process.ProcessName,
|
||||
ErrorMessage = success
|
||||
? null
|
||||
: process.FailedMessage
|
||||
};
|
||||
|
||||
LogInfo(operation, result.ToString());
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError(operation, ex);
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = false,
|
||||
Slot = slot,
|
||||
ProcessName = "Completion",
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates completion process instance based on current configuration.
|
||||
/// </summary>
|
||||
/// <param name="pp">Current process progress context</param>
|
||||
/// <returns>Configured completion process</returns>
|
||||
private BaseProcess CreateCompletionProcess(ProcessProgress pp)
|
||||
{
|
||||
if (pp.Setting.NumberOfPaths == 1)
|
||||
{
|
||||
return new SPCompletionProcess(
|
||||
"Completion Single",
|
||||
PreAdjustmentControl.StatusPanelItems.Completion,
|
||||
PreAdjustmentControl.PredefinedMessages.WaitUntilCompletionFinished(pp.Setting.Culture),
|
||||
PreAdjustmentControl.PredefinedMessages.CompletionFailed(pp.Setting.Culture),
|
||||
1 * 60);
|
||||
}
|
||||
|
||||
return new CompletionProcess(
|
||||
"Completion",
|
||||
PreAdjustmentControl.StatusPanelItems.Completion,
|
||||
PreAdjustmentControl.PredefinedMessages.WaitUntilCompletionFinished(pp.Setting.Culture),
|
||||
PreAdjustmentControl.PredefinedMessages.CompletionFailed(pp.Setting.Culture),
|
||||
1 * 60);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================================== PreAdjustmentUI ExecuteProcess ==================================
|
||||
private bool ExecuteProcess(
|
||||
BaseProcess process,
|
||||
ProcessProgress pp)
|
||||
{
|
||||
pp.IsBusy = true;
|
||||
|
||||
process.StartProcess(
|
||||
pp,
|
||||
_meterControls,
|
||||
_tempMeterControls);
|
||||
|
||||
while (pp.IsBusy && !pp.StopSequence)
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
|
||||
foreach (var meterCtrl in _meterControls)
|
||||
{
|
||||
if (meterCtrl.IsEnabled && meterCtrl.Failed)
|
||||
{
|
||||
pp.GenerateReturnNote(process.FailedMessage, meterCtrl);
|
||||
meterCtrl.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (pp.StopSequence)
|
||||
return false;
|
||||
|
||||
return _meterControls.Any(m => m.IsEnabled && !m.Failed);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,12 @@
|
||||
using System;
|
||||
using CordonelPreadjustmentUi;
|
||||
using CordonelPreadjustmentUi.Processes.Itinerary;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||
using static GenesisCordonelInterface.API.PublicModels;
|
||||
|
||||
namespace GenesisCordonelInterface.API
|
||||
@ -22,6 +26,8 @@ namespace GenesisCordonelInterface.API
|
||||
_innerMeterAPI = new InterfaceGCIToLaatzen();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#region ================================== PORT DETECTION ==================================
|
||||
|
||||
public PortDetectionResult DetectStreamingPort(int slot)
|
||||
@ -424,7 +430,6 @@ namespace GenesisCordonelInterface.API
|
||||
#endregion
|
||||
|
||||
#region ================================== METER BATCH SETUP ==================================
|
||||
// ----------------------------------------------------
|
||||
|
||||
public void ReloadSlotSetup()
|
||||
{
|
||||
@ -438,12 +443,63 @@ namespace GenesisCordonelInterface.API
|
||||
RaiseMeterBatchStatusChanged();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
#endregion
|
||||
|
||||
#region ================================== Register names ==================================
|
||||
|
||||
public List<string> GetAllRegisterNames()
|
||||
{
|
||||
return _innerMeterAPI.GetAllRegisterNames();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// Preadjustment
|
||||
|
||||
public Task<PreadjustmentDetectResult> Preadjustment_DetectAsync(
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return _innerMeterAPI.Preadjustment_DetectAsync(token);
|
||||
}
|
||||
|
||||
public Task<PreadjustmentProcessResult> Preadjustment_PreparationAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return _innerMeterAPI.Preadjustment_PreparationAsync(slot, pp, token);
|
||||
}
|
||||
|
||||
public Task<PreadjustmentProcessResult> Preadjustment_AmplitudeTestAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return _innerMeterAPI.Preadjustment_AmplitudeTestAsync(slot, pp, token);
|
||||
}
|
||||
|
||||
public Task<PreadjustmentProcessResult> Preadjustment_TemperatureCalibrationAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return _innerMeterAPI.Preadjustment_TemperatureCalibrationAsync(slot, pp, token);
|
||||
}
|
||||
|
||||
public Task<PreadjustmentProcessResult> Preadjustment_OffsetTestAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return _innerMeterAPI.Preadjustment_OffsetTestAsync(slot, pp, token);
|
||||
}
|
||||
|
||||
public Task<PreadjustmentProcessResult> Preadjustment_CompletionAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return _innerMeterAPI.Preadjustment_CompletionAsync(slot, pp, token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -447,6 +447,42 @@ namespace GenesisCordonelInterface.API
|
||||
Message);
|
||||
}
|
||||
}
|
||||
|
||||
public class PreadjustmentProcessResult
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public int Slot { get; set; }
|
||||
public string ProcessName { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"Success={Success}, " +
|
||||
$"Slot={Slot}, " +
|
||||
$"Process={ProcessName}, " +
|
||||
$"Error={ErrorMessage ?? "None"}";
|
||||
}
|
||||
}
|
||||
|
||||
public class PreadjustmentDetectResult
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public int DetectedMeterCount { get; set; }
|
||||
public int DetectedThermometerCount { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"Success={Success}, " +
|
||||
$"Meters={DetectedMeterCount}, " +
|
||||
$"Thermometers={DetectedThermometerCount}, " +
|
||||
$"Error={ErrorMessage ?? "None"}";
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,15 @@ namespace GenesisCordonelInterface.Core.Threading
|
||||
|
||||
public static class RetryWorker
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes an asynchronous operation with retry and timeout protection.
|
||||
///
|
||||
/// Important:
|
||||
/// The timeout here protects the caller from waiting forever, but it does not forcibly abort
|
||||
/// the underlying hardware operation. Because hardware/COM calls may continue running after
|
||||
/// the timeout signal, this method waits for the original action to finish before starting
|
||||
/// the next retry. This prevents overlapping COM requests on the same device.
|
||||
/// </summary>
|
||||
public static async Task<RetryResult<T>> RunWithRetryAsync<T>(
|
||||
Func<Task<T>> action,
|
||||
Func<T, bool> isSuccess,
|
||||
@ -41,21 +50,53 @@ namespace GenesisCordonelInterface.Core.Threading
|
||||
|
||||
for (int attempt = 1; attempt <= maxAttempts; attempt++)
|
||||
{
|
||||
var actionTask = action();
|
||||
var timeoutTask = Task.Delay(timeoutMs);
|
||||
Task<T> actionTask = null;
|
||||
|
||||
var completedTask = await Task.WhenAny(actionTask, timeoutTask);
|
||||
|
||||
if (completedTask == timeoutTask)
|
||||
try
|
||||
{
|
||||
timedOut = true;
|
||||
log?.Invoke($"{operationName} timeout attempt {attempt}/{maxAttempts}");
|
||||
}
|
||||
else
|
||||
{
|
||||
lastResult = await actionTask;
|
||||
log?.Invoke($"{operationName} started. Attempt {attempt}/{maxAttempts}");
|
||||
|
||||
if (isSuccess(lastResult))
|
||||
// Start real operation, for example Connect/GetPcbId/Login.
|
||||
actionTask = action();
|
||||
|
||||
// Start independent timeout timer.
|
||||
var timeoutTask = Task.Delay(timeoutMs);
|
||||
|
||||
// Wait until either operation completes or timeout expires.
|
||||
var completedTask = await Task.WhenAny(actionTask, timeoutTask)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (completedTask == timeoutTask)
|
||||
{
|
||||
timedOut = true;
|
||||
|
||||
log?.Invoke(
|
||||
$"{operationName} timed out. Attempt {attempt}/{maxAttempts}. " +
|
||||
"Waiting for the running operation to finish before retry.");
|
||||
|
||||
// Critical part:
|
||||
// Do NOT immediately start another retry.
|
||||
// The hardware operation may still be active in ApiWorker.
|
||||
// Starting another attempt immediately could corrupt communication.
|
||||
try
|
||||
{
|
||||
lastResult = await actionTask.ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log?.Invoke(
|
||||
$"{operationName} finished after timeout with exception: " +
|
||||
$"{ex.GetType().Name}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Operation completed before timeout.
|
||||
lastResult = await actionTask.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// Decide whether the returned result means success.
|
||||
if (lastResult != null && isSuccess(lastResult))
|
||||
{
|
||||
return new RetryResult<T>
|
||||
{
|
||||
@ -63,15 +104,29 @@ namespace GenesisCordonelInterface.Core.Threading
|
||||
Success = true,
|
||||
Attempts = attempt,
|
||||
Duration = DateTime.Now - started,
|
||||
TimedOut = false
|
||||
TimedOut = timedOut
|
||||
};
|
||||
}
|
||||
|
||||
logResult?.Invoke($"{operationName} failed attempt {attempt}/{maxAttempts}", lastResult);
|
||||
logResult?.Invoke(
|
||||
$"{operationName} failed. Attempt {attempt}/{maxAttempts}",
|
||||
lastResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Covers exceptions thrown before timeout handling or by action startup.
|
||||
log?.Invoke(
|
||||
$"{operationName} exception on attempt {attempt}/{maxAttempts}: " +
|
||||
$"{ex.GetType().Name}: {ex.Message}");
|
||||
}
|
||||
|
||||
// Delay before next retry, except after the final attempt.
|
||||
if (attempt < maxAttempts)
|
||||
await Task.Delay(delayMs);
|
||||
{
|
||||
log?.Invoke($"{operationName} waiting {delayMs} ms before retry.");
|
||||
|
||||
await Task.Delay(delayMs).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
return new RetryResult<T>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using CordonelPreadjustmentUi;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
@ -10,18 +11,26 @@ using System.Windows.Forms;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||
using CordonelPreadjustmentUi;
|
||||
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
|
||||
using System.Linq;//...MF
|
||||
|
||||
namespace GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI
|
||||
{
|
||||
public partial class FrmCordonelPreadjustmentUI : Form
|
||||
{
|
||||
private PreAdjustmentControl preadjustCtl;
|
||||
public PreAdjustmentControl preadjustCtl;//...MF
|
||||
private PreAdjustmentSettingsContainer mainSettings = new PreAdjustmentSettingsContainer();
|
||||
public MeterBatch _externMetersBatch;
|
||||
|
||||
public FrmCordonelPreadjustmentUI()
|
||||
{
|
||||
}
|
||||
public FrmCordonelPreadjustmentUI(MeterBatch externMetersBatch)
|
||||
{
|
||||
_externMetersBatch = externMetersBatch;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@ -29,7 +38,7 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI
|
||||
{
|
||||
|
||||
|
||||
preadjustCtl = new PreAdjustmentControl(mainSettings);
|
||||
preadjustCtl = new PreAdjustmentControl(mainSettings, _externMetersBatch);
|
||||
tab_ZeroFlowCal.Controls.Add(preadjustCtl);
|
||||
|
||||
|
||||
@ -71,7 +80,7 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI
|
||||
{
|
||||
if (e.TabPage.Name == tab_ZeroFlowCal.Name)
|
||||
{
|
||||
try
|
||||
/*try
|
||||
{
|
||||
var _serialConfigFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Genesis", ProgramConfig.SerialConfigFileName);
|
||||
|
||||
@ -99,11 +108,81 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"use default meters because of {ex.Message}");
|
||||
}*/
|
||||
|
||||
try //...MF
|
||||
{
|
||||
mainSettings.Meters = new List<int>();
|
||||
mainSettings.TempMeters = new List<int>();
|
||||
|
||||
// ==========================================
|
||||
// Try loading configuration from GCI meters
|
||||
// ==========================================
|
||||
|
||||
bool loadedFromInterface = false;
|
||||
|
||||
if (_externMetersBatch != null &&
|
||||
_externMetersBatch.ListOfMeters.Any())
|
||||
{
|
||||
foreach (GenesisMeter meter in _externMetersBatch.ListOfMeters)
|
||||
{
|
||||
// Skip meters that should use file configuration
|
||||
if (meter.useConfigSource != ConfigSource.InterfaceInputConfig)
|
||||
continue;
|
||||
|
||||
loadedFromInterface = true;
|
||||
|
||||
// Split normal and temperature meters
|
||||
//if (meter.Type == SlotType.TemperatureMeter)
|
||||
//{
|
||||
// mainSettings.TempMeters.Add(meter.Slot);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
mainSettings.Meters.Add(meter.Slot);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// Fallback to configuration file
|
||||
// ==========================================
|
||||
|
||||
if (!loadedFromInterface)
|
||||
{
|
||||
var _serialConfigFile =
|
||||
Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"Genesis",
|
||||
ProgramConfig.SerialConfigFileName);
|
||||
|
||||
SlotConfig[] meterConfigList;
|
||||
|
||||
using (var tr = new StreamReader(_serialConfigFile))
|
||||
{
|
||||
var _fileString = tr.ReadToEnd();
|
||||
|
||||
meterConfigList =
|
||||
JsonConvert.DeserializeObject<SlotConfig[]>(_fileString);
|
||||
}
|
||||
|
||||
foreach (var item in meterConfigList)
|
||||
{
|
||||
if (item.Type != SlotType.TemperatureMeter)
|
||||
{
|
||||
mainSettings.Meters.Add(item.Slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
mainSettings.TempMeters.Add(item.Slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Use default meters because of {ex.Message}");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mainSettings.NumberOfPaths = cB_SinglePath.Checked ? 1 : 3;
|
||||
mainSettings.LowerTempLimit = (double)nUD_SettingsTempMonitorLowerValue.Value;
|
||||
@ -156,7 +235,7 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI
|
||||
|
||||
}
|
||||
|
||||
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
/*private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (preadjustCtl != null)
|
||||
{
|
||||
@ -177,7 +256,68 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI
|
||||
}
|
||||
|
||||
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Raised when user closes the preadjustment window
|
||||
/// using the window close button (X).
|
||||
///
|
||||
/// Note:
|
||||
/// Form is hidden, not disposed.
|
||||
/// This event allows external code to continue
|
||||
/// workflow asynchronously.
|
||||
/// </summary>
|
||||
public event EventHandler OnUserClosed;
|
||||
|
||||
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
// User clicked X button - hide form only
|
||||
if (e.CloseReason == CloseReason.UserClosing)
|
||||
{
|
||||
e.Cancel = true;
|
||||
this.Hide();
|
||||
|
||||
OnUserClosed?.Invoke(this, EventArgs.Empty);
|
||||
return;
|
||||
}
|
||||
|
||||
// Real application shutdown / dispose
|
||||
DisposeResources();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose all internal resources that should
|
||||
/// only be released during real application shutdown.
|
||||
///
|
||||
/// Do not call when form is hidden.
|
||||
/// </summary>
|
||||
private void DisposeResources()
|
||||
{
|
||||
if (preadjustCtl != null)
|
||||
{
|
||||
preadjustCtl.CloseConnections();
|
||||
preadjustCtl.Dispose();
|
||||
preadjustCtl = null;
|
||||
}
|
||||
|
||||
if (ThermoMeterBatch != null)
|
||||
{
|
||||
ThermoMeterBatch.Dispose();
|
||||
ThermoMeterBatch = null;
|
||||
}
|
||||
|
||||
if (TempMeterStateCtls != null)
|
||||
{
|
||||
foreach (var item in TempMeterStateCtls)
|
||||
{
|
||||
item.Dispose();
|
||||
}
|
||||
|
||||
TempMeterStateCtls.Clear();
|
||||
TempMeterStateCtls = null;
|
||||
}
|
||||
}
|
||||
|
||||
private MeterBatch ThermoMeterBatch = new MeterBatch();
|
||||
private List<MeterStateControl> TempMeterStateCtls = new List<MeterStateControl>();
|
||||
private void tmpStart(int slot, bool RaspiMode = false)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using CordonelPreadjustmentUi.Processes;
|
||||
using CordonelPreadjustmentUi;
|
||||
using CordonelPreadjustmentUi.Processes;
|
||||
using CordonelPreadjustmentUi.Processes.Actions;
|
||||
using CordonelPreadjustmentUi.Processes.Itinerary;
|
||||
using System;
|
||||
@ -6,16 +7,18 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
|
||||
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
|
||||
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||
using Xylem.Common.Ui.CordonelPreadjustmentUi.Parameters;
|
||||
using CordonelPreadjustmentUi;
|
||||
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
|
||||
|
||||
namespace GenesisCordonelInterface.UI
|
||||
{
|
||||
@ -41,11 +44,18 @@ namespace GenesisCordonelInterface.UI
|
||||
private Boolean abortIndicator = false;
|
||||
public Boolean AbortIndicator { get { return abortIndicator; } set { abortIndicator = value; } }
|
||||
public int TestRunNumber;
|
||||
public PreAdjustmentControl(PreAdjustmentSettingsContainer Settings = null)
|
||||
public PreAdjustmentControl(PreAdjustmentSettingsContainer Settings = null, MeterBatch externalMetersBatch = null)//...MF
|
||||
{
|
||||
InitializeComponent();
|
||||
SetSettings(Settings);
|
||||
rTB_ZeroFlowCal.AutoSize = true;
|
||||
|
||||
//...MF
|
||||
// Use external batch only if supplied
|
||||
if (externalMetersBatch != null)
|
||||
{
|
||||
GlobalMeterBatch = externalMetersBatch;
|
||||
}
|
||||
}
|
||||
public void SetSettings(PreAdjustmentSettingsContainer Settings = null)
|
||||
{
|
||||
@ -120,6 +130,49 @@ namespace GenesisCordonelInterface.UI
|
||||
}
|
||||
cb_Metersize.SelectedItem = setM;
|
||||
|
||||
//...MF
|
||||
// Create UI controls for configured meter slots.
|
||||
//
|
||||
// Flow:
|
||||
//
|
||||
// settings.Meters
|
||||
// ↓
|
||||
// create MeterStateControl
|
||||
// ↓
|
||||
// position control in UI
|
||||
// ↓
|
||||
// check whether slot exists in externally supplied MeterBatch
|
||||
// ↓
|
||||
// automatically enable corresponding checkbox
|
||||
// ↓
|
||||
// register UI events
|
||||
// ↓
|
||||
// add control into internal collection and group box
|
||||
//
|
||||
// Notes:
|
||||
// - allows external GCI workflow to preselect meters
|
||||
// - keeps UI synchronized with externally injected MeterBatch
|
||||
// - slots contained in GlobalMeterBatch are automatically checked
|
||||
//
|
||||
foreach (var Meter in settings.Meters)
|
||||
{
|
||||
var ctl = new MeterStateControl(Meter);
|
||||
ctl.Location = new Point(5 + ((tmpI - 1) * ctl.Width), 15);
|
||||
|
||||
// Check meter if it exists in external MeterBatch
|
||||
if (GlobalMeterBatch != null &&
|
||||
GlobalMeterBatch.ListOfMeters != null &&
|
||||
GlobalMeterBatch.ListOfMeters.Any(m => m.Slot == Meter))
|
||||
{
|
||||
ctl.SetChecked(true);
|
||||
}
|
||||
|
||||
MeterStateCtls.Add(ctl);
|
||||
gB_Meters.Controls.Add(ctl);
|
||||
ctl.OnRequestDetails += Ctl_MouseEnter;
|
||||
tmpI = tmpI + 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1694,13 +1747,46 @@ namespace GenesisCordonelInterface.UI
|
||||
|
||||
List<IProcess> listOfProgrammParts = new List<IProcess>();
|
||||
|
||||
//...MF
|
||||
bool requiresInternalLoginFlow = true;
|
||||
requiresInternalLoginFlow =
|
||||
GlobalMeterBatch.ListOfMeters.All(
|
||||
m =>
|
||||
{
|
||||
var meter = m as GenesisMeter;
|
||||
|
||||
return meter == null ||
|
||||
meter.usePasswordSource !=
|
||||
PasswordSource.InterfaceInputPassword;
|
||||
});
|
||||
|
||||
listOfProgrammParts.Add(new PrepareTestProcess("PrepareTest", CordonelPreadjustmentUi.PreAdjustmentControl.StatusPanelItems.Detect, string.Empty, string.Empty, 1 * 60));
|
||||
//...MF
|
||||
bool requiresInternalConfigFlow = true;
|
||||
requiresInternalConfigFlow =
|
||||
GlobalMeterBatch.ListOfMeters.All(
|
||||
m =>
|
||||
{
|
||||
var meter = m as GenesisMeter;
|
||||
|
||||
listOfProgrammParts.Add(new LoginProcess("Login", CordonelPreadjustmentUi.PreAdjustmentControl.StatusPanelItems.Detect, PredefinedMessages.WaitUntilLoginFinished(pp.Setting.Culture), PredefinedMessages.LoginFailed(pp.Setting.Culture), 1 * 60));
|
||||
return meter == null ||
|
||||
meter.useConfigSource !=
|
||||
ConfigSource.InterfaceInputConfig;
|
||||
});
|
||||
|
||||
listOfProgrammParts.Add(new FlushProcess("First Flush", CordonelPreadjustmentUi.PreAdjustmentControl.StatusPanelItems.Detect, PredefinedMessages.WaitUntilFlushFinished(pp.Setting.Culture), string.Empty, 2 * 60));
|
||||
if (requiresInternalConfigFlow)//...MF
|
||||
{
|
||||
listOfProgrammParts.Add(new PrepareTestProcess("PrepareTest", CordonelPreadjustmentUi.PreAdjustmentControl.StatusPanelItems.Detect, string.Empty, string.Empty, 1 * 60));
|
||||
}
|
||||
|
||||
if (requiresInternalLoginFlow)//...MF
|
||||
{
|
||||
listOfProgrammParts.Add(new LoginProcess("Login", CordonelPreadjustmentUi.PreAdjustmentControl.StatusPanelItems.Detect, PredefinedMessages.WaitUntilLoginFinished(pp.Setting.Culture), PredefinedMessages.LoginFailed(pp.Setting.Culture), 1 * 60));
|
||||
}
|
||||
|
||||
if (requiresInternalConfigFlow)//...MF
|
||||
{
|
||||
listOfProgrammParts.Add(new FlushProcess("First Flush", CordonelPreadjustmentUi.PreAdjustmentControl.StatusPanelItems.Detect, PredefinedMessages.WaitUntilFlushFinished(pp.Setting.Culture), string.Empty, 2 * 60));
|
||||
}
|
||||
|
||||
//listOfProgrammParts.Add(new PressureTestProcess("PreussureTest", StatusPanelItems.Prepare, PredefinedMessages.WaitUntilPreparationFinished(pp.Setting.Culture), PredefinedMessages.PreparationFailed(pp.Setting.Culture), 1 * 60));
|
||||
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
using GenesisCordonelInterface.API;
|
||||
using CordonelPreadjustmentUi;
|
||||
using CordonelPreadjustmentUi.Processes.Itinerary;
|
||||
using GenesisCordonelInterface.API;
|
||||
using GenesisCordonelInterface.Core.Threading;
|
||||
using log4net;
|
||||
///
|
||||
/// Copyright (c) 2015-2021 Sensus Slovensko a.s.
|
||||
@ -13,6 +16,9 @@ using TBF.Rig.BridgeComponents.GciBridge.UI;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.Input.DataStorage.UniDataStorageReader;
|
||||
using TBF.Rig.Input.DataStorage.UniDataStorageReader.Searching.Database;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||
using static GenesisCordonelInterface.API.PublicModels;
|
||||
using static TBF.Rig.BridgeComponents.GciBridge.Interfaces.PublicModels;
|
||||
using GciGUIType = GenesisCordonelInterface.UI.MainView;
|
||||
using GciPublicModels = GenesisCordonelInterface.API.PublicModels;
|
||||
@ -20,7 +26,6 @@ using GciType = GenesisCordonelInterface.API.InterfaceOutsideToGCI;
|
||||
using UdsReaderType = TBF.Rig.Input.DataStorage.UniDataStorageReader.Reader;
|
||||
using UDSRPublicModels = TBF.Rig.Input.DataStorage.UniDataStorageReader.Interfaces.PublicModels;
|
||||
using UdsWriterType = TBF.Rig.Output.DataStorage.UniDataStorageWriter.Writer;
|
||||
using GenesisCordonelInterface.Core.Threading;
|
||||
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
{
|
||||
@ -47,8 +52,8 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
Form gciGuiHostForm;
|
||||
|
||||
//diag GUI for GciBridge
|
||||
public UserControl gciBridgeGUI;
|
||||
public MainForm gciBridgeGuiForm;
|
||||
public UserControl gciBridgeGUIUserControl;
|
||||
public UI.MainForm gciBridgeGuiForm;
|
||||
|
||||
public GciType gciExternalInterface;
|
||||
|
||||
@ -119,7 +124,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
if (gciBridgeGuiForm != null && !gciBridgeGuiForm.IsDisposed)
|
||||
return;
|
||||
|
||||
gciBridgeGuiForm = new MainForm(this);
|
||||
gciBridgeGuiForm = new UI.MainForm(this);
|
||||
gciBridgeGuiForm.Text = "Gci Bridge GUI";
|
||||
gciBridgeGuiForm.Width = 1300;
|
||||
gciBridgeGuiForm.Height = 600;
|
||||
@ -1417,6 +1422,334 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
||||
|
||||
#endregion
|
||||
|
||||
// Preadjustment API:
|
||||
|
||||
#region ================================== Preadjustment DETECT bridge ==================================
|
||||
|
||||
public async Task<PreadjustmentDetectResult> Preadjustment_DetectAsync(
|
||||
CancellationToken token = default)
|
||||
{
|
||||
const string operation = nameof(Preadjustment_DetectAsync);
|
||||
|
||||
try
|
||||
{
|
||||
EnsureExternalInterface();
|
||||
|
||||
log.InfoFormat("{0}: {1} Start.", Name, operation);
|
||||
|
||||
PreadjustmentDetectResult result =
|
||||
await gciExternalInterface
|
||||
.Preadjustment_DetectAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Finish. {2}",
|
||||
Name,
|
||||
operation,
|
||||
result);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(
|
||||
string.Format("{0}: {1} failed.", Name, operation),
|
||||
ex);
|
||||
|
||||
return new PreadjustmentDetectResult
|
||||
{
|
||||
Success = false,
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================================== PreAdjustment PREPARATION bridge ==================================
|
||||
|
||||
public async Task<PreadjustmentProcessResult> Preadjustment_PreparationAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
const string operation = nameof(Preadjustment_PreparationAsync);
|
||||
|
||||
try
|
||||
{
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (pp == null)
|
||||
throw new ArgumentNullException(nameof(pp));
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Start. Slot={2}",
|
||||
Name,
|
||||
operation,
|
||||
slot);
|
||||
|
||||
PreadjustmentProcessResult result =
|
||||
await gciExternalInterface
|
||||
.Preadjustment_PreparationAsync(
|
||||
slot,
|
||||
pp,
|
||||
token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Finish. {2}",
|
||||
Name,
|
||||
operation,
|
||||
result);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(
|
||||
string.Format("{0}: {1} failed.", Name, operation),
|
||||
ex);
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = false,
|
||||
Slot = slot,
|
||||
ProcessName = "Preparation",
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================================== PreAdjustment AMPLITUDE TEST bridge ==================================
|
||||
|
||||
public async Task<PreadjustmentProcessResult> Preadjustment_AmplitudeTestAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
const string operation = nameof(Preadjustment_AmplitudeTestAsync);
|
||||
|
||||
try
|
||||
{
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (pp == null)
|
||||
throw new ArgumentNullException(nameof(pp));
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Start. Slot={2}",
|
||||
Name,
|
||||
operation,
|
||||
slot);
|
||||
|
||||
PreadjustmentProcessResult result =
|
||||
await gciExternalInterface
|
||||
.Preadjustment_AmplitudeTestAsync(
|
||||
slot,
|
||||
pp,
|
||||
token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Finish. {2}",
|
||||
Name,
|
||||
operation,
|
||||
result);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(
|
||||
string.Format("{0}: {1} failed.", Name, operation),
|
||||
ex);
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = false,
|
||||
Slot = slot,
|
||||
ProcessName = "Amplitude Test",
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================================== PreAdjustment TEMPERATURE CALIBRATION bridge ==================================
|
||||
|
||||
public async Task<PreadjustmentProcessResult> Preadjustment_TemperatureCalibrationAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
const string operation = nameof(Preadjustment_TemperatureCalibrationAsync);
|
||||
|
||||
try
|
||||
{
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (pp == null)
|
||||
throw new ArgumentNullException(nameof(pp));
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Start. Slot={2}",
|
||||
Name,
|
||||
operation,
|
||||
slot);
|
||||
|
||||
PreadjustmentProcessResult result =
|
||||
await gciExternalInterface
|
||||
.Preadjustment_TemperatureCalibrationAsync(
|
||||
slot,
|
||||
pp,
|
||||
token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Finish. {2}",
|
||||
Name,
|
||||
operation,
|
||||
result);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(
|
||||
string.Format("{0}: {1} failed.", Name, operation),
|
||||
ex);
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = false,
|
||||
Slot = slot,
|
||||
ProcessName = "Temperature Calibration",
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================================== PreAdjustment OFFSET TEST bridge ==================================
|
||||
|
||||
public async Task<PreadjustmentProcessResult> Preadjustment_OffsetTestAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
const string operation = nameof(Preadjustment_OffsetTestAsync);
|
||||
|
||||
try
|
||||
{
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (pp == null)
|
||||
throw new ArgumentNullException(nameof(pp));
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Start. Slot={2}",
|
||||
Name,
|
||||
operation,
|
||||
slot);
|
||||
|
||||
PreadjustmentProcessResult result =
|
||||
await gciExternalInterface
|
||||
.Preadjustment_OffsetTestAsync(
|
||||
slot,
|
||||
pp,
|
||||
token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Finish. {2}",
|
||||
Name,
|
||||
operation,
|
||||
result);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(
|
||||
string.Format("{0}: {1} failed.", Name, operation),
|
||||
ex);
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = false,
|
||||
Slot = slot,
|
||||
ProcessName = "Offset Test",
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================================== PreAdjustment COMPLETION bridge ==================================
|
||||
|
||||
public async Task<PreadjustmentProcessResult> Preadjustment_CompletionAsync(
|
||||
int slot,
|
||||
ProcessProgress pp,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
const string operation = nameof(Preadjustment_CompletionAsync);
|
||||
|
||||
try
|
||||
{
|
||||
EnsureExternalInterface();
|
||||
|
||||
if (pp == null)
|
||||
throw new ArgumentNullException(nameof(pp));
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Start. Slot={2}",
|
||||
Name,
|
||||
operation,
|
||||
slot);
|
||||
|
||||
PreadjustmentProcessResult result =
|
||||
await gciExternalInterface
|
||||
.Preadjustment_CompletionAsync(
|
||||
slot,
|
||||
pp,
|
||||
token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.InfoFormat(
|
||||
"{0}: {1} Finish. {2}",
|
||||
Name,
|
||||
operation,
|
||||
result);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(
|
||||
string.Format("{0}: {1} failed.", Name, operation),
|
||||
ex);
|
||||
|
||||
return new PreadjustmentProcessResult
|
||||
{
|
||||
Success = false,
|
||||
Slot = slot,
|
||||
ProcessName = "Completion",
|
||||
ErrorMessage = ex.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ======================================= Helpers =======================================
|
||||
private UDSRPublicModels.DataQuery CreatePasswordQuery(string pcbId)
|
||||
{
|
||||
|
||||
@ -15,6 +15,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug
|
||||
private MainForm _mainform;
|
||||
private MainView _mainView;
|
||||
public Grid.MeterGridManager _gridManager;
|
||||
public event Action GetMeterRegistersClicked;
|
||||
|
||||
private bool isRefreshing;
|
||||
private List<string> comPorts = new List<string>();
|
||||
@ -36,6 +37,9 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug
|
||||
|
||||
_mainView._gciApi.MeterBatchStatusChanged += Api_MeterBatchStatusChanged; //global event of table
|
||||
|
||||
grid.CellContentClick += grid_CellContentClick;
|
||||
|
||||
|
||||
UpdateGrid(_api.GetMeterBatchDebugStatuses());
|
||||
}
|
||||
|
||||
@ -267,8 +271,16 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug
|
||||
|
||||
if (columnName == "Selected")
|
||||
{
|
||||
bool selected = Convert.ToBoolean(grid.Rows[e.RowIndex].Cells["Selected"].Value);
|
||||
bool selected =
|
||||
Convert.ToBoolean(
|
||||
grid.Rows[e.RowIndex]
|
||||
.Cells["Selected"]
|
||||
.Value);
|
||||
|
||||
_api.SetSlotSelected(slot, selected);
|
||||
|
||||
//SelectedSlotsChanged?.Invoke();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -302,13 +314,14 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug
|
||||
|
||||
if (columnName == "DetectRequest")
|
||||
{
|
||||
await DetectRequestPortAsync(slot);
|
||||
//await DetectRequestPortAsync(slot);
|
||||
GetMeterRegistersClicked?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
if (columnName == "DetectStreaming")
|
||||
{
|
||||
await DetectStreamingPortAsync(slot);
|
||||
//await DetectStreamingPortAsync(slot);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
private System.Windows.Forms.Button btnRegisterStore;
|
||||
private System.Windows.Forms.Button btnPulseSetup;
|
||||
private System.Windows.Forms.Button preadjustmentButton;
|
||||
private System.Windows.Forms.Button btnMetersAction;
|
||||
private System.Windows.Forms.Button slotsComPortsRegistersActionsViewButton;
|
||||
private System.Windows.Forms.SplitContainer splitWorkArea;
|
||||
private System.Windows.Forms.Panel pnlGciViewHost;
|
||||
|
||||
@ -43,9 +43,11 @@
|
||||
this.btnRegisterStore = new System.Windows.Forms.Button();
|
||||
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||
this.groupBox5 = new System.Windows.Forms.GroupBox();
|
||||
this.btnMetersAction = new System.Windows.Forms.Button();
|
||||
this.storageActionButton = new System.Windows.Forms.Button();
|
||||
this.combinedActionButton = new System.Windows.Forms.Button();
|
||||
this.ScenariousViewButton = new System.Windows.Forms.Button();
|
||||
this.preadjustmenActionsViewButton = new System.Windows.Forms.Button();
|
||||
this.slotsComPortsRegistersActionsViewButton = new System.Windows.Forms.Button();
|
||||
this.uniDataSorageActionsViewButton = new System.Windows.Forms.Button();
|
||||
this.combinedActionsViewButton = new System.Windows.Forms.Button();
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.btnDiagTablesConfigurationButton = new System.Windows.Forms.Button();
|
||||
this.pnlMain = new System.Windows.Forms.Panel();
|
||||
@ -104,7 +106,6 @@
|
||||
//
|
||||
this.tabPage1.Controls.Add(this.groupBox2);
|
||||
this.tabPage1.Controls.Add(this.groupBox1);
|
||||
this.tabPage1.Enabled = false;
|
||||
this.tabPage1.Location = new System.Drawing.Point(4, 22);
|
||||
this.tabPage1.Name = "tabPage1";
|
||||
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
||||
@ -189,45 +190,66 @@
|
||||
//
|
||||
// groupBox5
|
||||
//
|
||||
this.groupBox5.Controls.Add(this.btnMetersAction);
|
||||
this.groupBox5.Controls.Add(this.storageActionButton);
|
||||
this.groupBox5.Controls.Add(this.combinedActionButton);
|
||||
this.groupBox5.Controls.Add(this.ScenariousViewButton);
|
||||
this.groupBox5.Controls.Add(this.preadjustmenActionsViewButton);
|
||||
this.groupBox5.Controls.Add(this.slotsComPortsRegistersActionsViewButton);
|
||||
this.groupBox5.Controls.Add(this.uniDataSorageActionsViewButton);
|
||||
this.groupBox5.Controls.Add(this.combinedActionsViewButton);
|
||||
this.groupBox5.Location = new System.Drawing.Point(6, 85);
|
||||
this.groupBox5.Name = "groupBox5";
|
||||
this.groupBox5.Size = new System.Drawing.Size(166, 131);
|
||||
this.groupBox5.Size = new System.Drawing.Size(166, 202);
|
||||
this.groupBox5.TabIndex = 3;
|
||||
this.groupBox5.TabStop = false;
|
||||
this.groupBox5.Text = "Interface";
|
||||
this.groupBox5.Text = "Interface testing";
|
||||
//
|
||||
// btnMetersAction
|
||||
// ScenariousViewButton
|
||||
//
|
||||
this.btnMetersAction.Location = new System.Drawing.Point(6, 19);
|
||||
this.btnMetersAction.Name = "btnMetersAction";
|
||||
this.btnMetersAction.Size = new System.Drawing.Size(150, 30);
|
||||
this.btnMetersAction.TabIndex = 1;
|
||||
this.btnMetersAction.Text = "GenesisCordonelInterface";
|
||||
this.btnMetersAction.UseVisualStyleBackColor = true;
|
||||
this.btnMetersAction.Click += new System.EventHandler(this.btnMetersAction_Click);
|
||||
this.ScenariousViewButton.Location = new System.Drawing.Point(6, 163);
|
||||
this.ScenariousViewButton.Name = "ScenariousViewButton";
|
||||
this.ScenariousViewButton.Size = new System.Drawing.Size(150, 30);
|
||||
this.ScenariousViewButton.TabIndex = 3;
|
||||
this.ScenariousViewButton.Text = "Scenarious";
|
||||
this.ScenariousViewButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// storageActionButton
|
||||
// preadjustmenActionsViewButton
|
||||
//
|
||||
this.storageActionButton.Location = new System.Drawing.Point(6, 55);
|
||||
this.storageActionButton.Name = "storageActionButton";
|
||||
this.storageActionButton.Size = new System.Drawing.Size(150, 30);
|
||||
this.storageActionButton.TabIndex = 0;
|
||||
this.storageActionButton.Text = "UniDataStorageReader";
|
||||
this.storageActionButton.UseVisualStyleBackColor = true;
|
||||
this.storageActionButton.Click += new System.EventHandler(this.button1_Click_1);
|
||||
this.preadjustmenActionsViewButton.Location = new System.Drawing.Point(6, 127);
|
||||
this.preadjustmenActionsViewButton.Name = "preadjustmenActionsViewButton";
|
||||
this.preadjustmenActionsViewButton.Size = new System.Drawing.Size(150, 30);
|
||||
this.preadjustmenActionsViewButton.TabIndex = 2;
|
||||
this.preadjustmenActionsViewButton.Text = "Preadjustment";
|
||||
this.preadjustmenActionsViewButton.UseVisualStyleBackColor = true;
|
||||
this.preadjustmenActionsViewButton.Click += new System.EventHandler(this.preadjustmenActionsViewButton_Click);
|
||||
//
|
||||
// combinedActionButton
|
||||
// slotsComPortsRegistersActionsViewButton
|
||||
//
|
||||
this.combinedActionButton.Location = new System.Drawing.Point(6, 91);
|
||||
this.combinedActionButton.Name = "combinedActionButton";
|
||||
this.combinedActionButton.Size = new System.Drawing.Size(150, 30);
|
||||
this.combinedActionButton.TabIndex = 0;
|
||||
this.combinedActionButton.Text = "Combined Action";
|
||||
this.combinedActionButton.UseVisualStyleBackColor = true;
|
||||
this.combinedActionButton.Click += new System.EventHandler(this.button2_Click);
|
||||
this.slotsComPortsRegistersActionsViewButton.Location = new System.Drawing.Point(6, 19);
|
||||
this.slotsComPortsRegistersActionsViewButton.Name = "slotsComPortsRegistersActionsViewButton";
|
||||
this.slotsComPortsRegistersActionsViewButton.Size = new System.Drawing.Size(150, 30);
|
||||
this.slotsComPortsRegistersActionsViewButton.TabIndex = 1;
|
||||
this.slotsComPortsRegistersActionsViewButton.Text = "Slots, ComPorts, Registers";
|
||||
this.slotsComPortsRegistersActionsViewButton.UseVisualStyleBackColor = true;
|
||||
this.slotsComPortsRegistersActionsViewButton.Click += new System.EventHandler(this.btnMetersAction_Click);
|
||||
//
|
||||
// uniDataSorageActionsViewButton
|
||||
//
|
||||
this.uniDataSorageActionsViewButton.Location = new System.Drawing.Point(6, 55);
|
||||
this.uniDataSorageActionsViewButton.Name = "uniDataSorageActionsViewButton";
|
||||
this.uniDataSorageActionsViewButton.Size = new System.Drawing.Size(150, 30);
|
||||
this.uniDataSorageActionsViewButton.TabIndex = 0;
|
||||
this.uniDataSorageActionsViewButton.Text = "UniDataStorageReader";
|
||||
this.uniDataSorageActionsViewButton.UseVisualStyleBackColor = true;
|
||||
this.uniDataSorageActionsViewButton.Click += new System.EventHandler(this.button1_Click_1);
|
||||
//
|
||||
// combinedActionsViewButton
|
||||
//
|
||||
this.combinedActionsViewButton.Location = new System.Drawing.Point(6, 91);
|
||||
this.combinedActionsViewButton.Name = "combinedActionsViewButton";
|
||||
this.combinedActionsViewButton.Size = new System.Drawing.Size(150, 30);
|
||||
this.combinedActionsViewButton.TabIndex = 0;
|
||||
this.combinedActionsViewButton.Text = "Combined actions";
|
||||
this.combinedActionsViewButton.UseVisualStyleBackColor = true;
|
||||
this.combinedActionsViewButton.Click += new System.EventHandler(this.button2_Click);
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
@ -386,9 +408,11 @@
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
private System.Windows.Forms.Button storageActionButton;
|
||||
private System.Windows.Forms.Button uniDataSorageActionsViewButton;
|
||||
private System.Windows.Forms.GroupBox groupBox5;
|
||||
private System.Windows.Forms.Button combinedActionButton;
|
||||
private System.Windows.Forms.Button combinedActionsViewButton;
|
||||
private System.Windows.Forms.Button btnDiagTablesConfigurationButton;
|
||||
private System.Windows.Forms.Button preadjustmenActionsViewButton;
|
||||
private System.Windows.Forms.Button ScenariousViewButton;
|
||||
}
|
||||
}
|
||||
@ -72,58 +72,11 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI
|
||||
_uiLogFlushTimer.Interval = 250;
|
||||
_uiLogFlushTimer.Tick += UiLogFlushTimer_Tick;
|
||||
_uiLogFlushTimer.Start();
|
||||
|
||||
preadjustmentButton.Enabled = true;
|
||||
groupBox2.Enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Periodically flushes buffered log messages into RichTextBox.
|
||||
///
|
||||
/// Runs on the UI thread because WinForms Timer executes on UI thread.
|
||||
/// Processes messages in batches to reduce UI overhead.
|
||||
/// </summary>
|
||||
/// Plynule pridavanie do mema
|
||||
/*private void UiLogFlushTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (IsDisposed || !IsHandleCreated)
|
||||
return;
|
||||
|
||||
List<string> messages = new List<string>();
|
||||
|
||||
lock (_uiLogLock)
|
||||
{
|
||||
while (_pendingUiLogs.Count > 0 && messages.Count < 500)
|
||||
{
|
||||
messages.Add(_pendingUiLogs.Dequeue());
|
||||
}
|
||||
}
|
||||
|
||||
if (messages.Count == 0)
|
||||
return;
|
||||
|
||||
rtbMainLog.SuspendLayout();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (string msg in messages)
|
||||
{
|
||||
AppendLogMessage(msg);
|
||||
}
|
||||
|
||||
const int maxTextLength = 200000;
|
||||
|
||||
if (rtbMainLog.TextLength > maxTextLength)
|
||||
{
|
||||
rtbMainLog.Select(0, rtbMainLog.TextLength - maxTextLength);
|
||||
rtbMainLog.SelectedText = "";
|
||||
}
|
||||
|
||||
rtbMainLog.SelectionStart = rtbMainLog.TextLength;
|
||||
rtbMainLog.ScrollToCaret();
|
||||
}
|
||||
finally
|
||||
{
|
||||
rtbMainLog.ResumeLayout();
|
||||
}
|
||||
}*/
|
||||
|
||||
private void UiLogFlushTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
@ -277,153 +230,6 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private IWin32Window DialogOwner
|
||||
{
|
||||
get
|
||||
{
|
||||
Form owner = FindForm();
|
||||
return owner ?? (IWin32Window)this;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowGciView(Control view)
|
||||
{
|
||||
pnlGciViewHost.Controls.Clear();
|
||||
|
||||
view.Dock = DockStyle.Fill;
|
||||
pnlGciViewHost.Controls.Add(view);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves current slot configuration from the grid into backend storage.
|
||||
/// </summary>
|
||||
public void SaveSlots()
|
||||
{
|
||||
var data = _batchPanel.GetGridData();
|
||||
_laatzenApi.SaveSlotSetup(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switches currently displayed GCI view inside the host panel.
|
||||
/// </summary>
|
||||
private void button2_Click(object sender, EventArgs e)
|
||||
{
|
||||
SwitchGciView(
|
||||
"CombinedInterfaceView",
|
||||
new CombinedInterfaceView(this, _bridge));
|
||||
}
|
||||
|
||||
private void button1_Click_1(object sender, EventArgs e)
|
||||
{
|
||||
SwitchGciView(
|
||||
"StorageAction",
|
||||
new UniDataStorageReaderInterfaceView(this, _bridge));
|
||||
}
|
||||
|
||||
#region BUTTONS
|
||||
|
||||
private void btnMetersAction_Click(object sender, EventArgs e)
|
||||
{
|
||||
SwitchGciView(
|
||||
"SlotsMetersAction",
|
||||
new GenesisCordonelInterfaceView(this, _bridge, AddSlotRow, SaveSlots));
|
||||
}
|
||||
|
||||
private void btnSetup_Click(object sender, EventArgs e)
|
||||
{
|
||||
/*Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace("FORM: Setup open");
|
||||
|
||||
using (FrmSetup frm = new FrmSetup())
|
||||
{
|
||||
frm.ShowDialog(DialogOwner);
|
||||
}
|
||||
|
||||
Logger.Trace("FORM: Setup closed.");*/
|
||||
}
|
||||
|
||||
private void btnRegisterStore_Click(object sender, EventArgs e)
|
||||
{
|
||||
/*Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace("FORM: Register Store open.");
|
||||
|
||||
using (FrmRegisterStore frm = new FrmRegisterStore())
|
||||
{
|
||||
frm.ShowDialog(DialogOwner);
|
||||
}
|
||||
|
||||
Logger.Trace("FORM: Register Store closed.");*/
|
||||
}
|
||||
|
||||
private void btnPulseSetup_Click(object sender, EventArgs e)
|
||||
{
|
||||
/*Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace("FORM: Pulse Setup open.");
|
||||
|
||||
using (FrmConfigurations frm = new FrmConfigurations())
|
||||
{
|
||||
frm.ShowDialog(DialogOwner);
|
||||
}
|
||||
|
||||
Logger.Trace("FORM: Pulse Setup closed.");*/
|
||||
}
|
||||
|
||||
private void preadjustmentButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
/*Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace("FORM: Preadjustment open.");
|
||||
|
||||
using (FrmCordonelPreadjustmentUI frm = new FrmCordonelPreadjustmentUI())
|
||||
{
|
||||
frm.ShowDialog(DialogOwner);
|
||||
}
|
||||
|
||||
Logger.Trace("FORM: Preadjustment closed.");*/
|
||||
}
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace("FORM: GciBridge GUI open.");
|
||||
|
||||
using (var frm = new FrmGCIAPI(_gciApi))
|
||||
{
|
||||
frm.ShowDialog(this);
|
||||
}
|
||||
|
||||
Logger.Trace("FORM: GciBridge closed.");
|
||||
}
|
||||
|
||||
private void SwitchGciView(string name, Control view)
|
||||
{
|
||||
Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace($"FORM: GciBridge VIEW -> {name} OPEN");
|
||||
|
||||
pnlGciViewHost.Controls.Clear();
|
||||
|
||||
view.Dock = DockStyle.Fill;
|
||||
pnlGciViewHost.Controls.Add(view);
|
||||
view.BringToFront();
|
||||
|
||||
Logger.Trace($"FORM: GciBridge VIEW -> {name} LOADED");
|
||||
}
|
||||
|
||||
private void btnMeterInit_Click(object sender, EventArgs e)
|
||||
{
|
||||
SwitchGciView(
|
||||
"MeterInit",
|
||||
new MeterInitView(_gciApi, AddSlotRow, SaveSlots));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the main UI log window.
|
||||
/// </summary>
|
||||
public void ClearLog()
|
||||
{
|
||||
rtbMainLog.Clear();
|
||||
Logger.Trace("Log cleared.");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GLOBAL LOGGING to memo in this view
|
||||
|
||||
@ -545,11 +351,164 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI
|
||||
|
||||
#endregion
|
||||
|
||||
private IWin32Window DialogOwner
|
||||
{
|
||||
get
|
||||
{
|
||||
Form owner = FindForm();
|
||||
return owner ?? (IWin32Window)this;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowGciView(Control view)
|
||||
{
|
||||
pnlGciViewHost.Controls.Clear();
|
||||
|
||||
view.Dock = DockStyle.Fill;
|
||||
pnlGciViewHost.Controls.Add(view);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves current slot configuration from the grid into backend storage.
|
||||
/// </summary>
|
||||
public void SaveSlots()
|
||||
{
|
||||
var data = _batchPanel.GetGridData();
|
||||
_laatzenApi.SaveSlotSetup(data);
|
||||
}
|
||||
|
||||
#region BUTTONS
|
||||
|
||||
private void btnSetup_Click(object sender, EventArgs e)
|
||||
{
|
||||
/*Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace("FORM: Setup open");
|
||||
|
||||
using (FrmSetup frm = new FrmSetup())
|
||||
{
|
||||
frm.ShowDialog(DialogOwner);
|
||||
}
|
||||
|
||||
Logger.Trace("FORM: Setup closed.");*/
|
||||
}
|
||||
|
||||
private void btnRegisterStore_Click(object sender, EventArgs e)
|
||||
{
|
||||
/*Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace("FORM: Register Store open.");
|
||||
|
||||
using (FrmRegisterStore frm = new FrmRegisterStore())
|
||||
{
|
||||
frm.ShowDialog(DialogOwner);
|
||||
}
|
||||
|
||||
Logger.Trace("FORM: Register Store closed.");*/
|
||||
}
|
||||
|
||||
private void btnPulseSetup_Click(object sender, EventArgs e)
|
||||
{
|
||||
/*Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace("FORM: Pulse Setup open.");
|
||||
|
||||
using (FrmConfigurations frm = new FrmConfigurations())
|
||||
{
|
||||
frm.ShowDialog(DialogOwner);
|
||||
}
|
||||
|
||||
Logger.Trace("FORM: Pulse Setup closed.");*/
|
||||
}
|
||||
|
||||
private void preadjustmentButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace("FORM: Preadjustment open.");
|
||||
|
||||
_laatzenApi.ShowPreadjustmentForm(DialogOwner);
|
||||
|
||||
Logger.Trace("FORM: Preadjustment shown.");
|
||||
}
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace("FORM: GciBridge GUI open.");
|
||||
|
||||
using (var frm = new FrmGCIAPI(_gciApi))
|
||||
{
|
||||
frm.ShowDialog(this);
|
||||
}
|
||||
|
||||
Logger.Trace("FORM: GciBridge closed.");
|
||||
}
|
||||
|
||||
private void SwitchGciView(string name, Control view)
|
||||
{
|
||||
Logger.Trace("FORM: ---------------------------------");
|
||||
Logger.Trace($"FORM: GciBridge VIEW -> {name} OPEN");
|
||||
|
||||
pnlGciViewHost.Controls.Clear();
|
||||
|
||||
view.Dock = DockStyle.Fill;
|
||||
pnlGciViewHost.Controls.Add(view);
|
||||
view.BringToFront();
|
||||
|
||||
Logger.Trace($"FORM: GciBridge VIEW -> {name} LOADED");
|
||||
}
|
||||
|
||||
private void btnMeterInit_Click(object sender, EventArgs e)
|
||||
{
|
||||
SwitchGciView(
|
||||
"MeterInit",
|
||||
new MeterInitView(_gciApi, AddSlotRow, SaveSlots));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the main UI log window.
|
||||
/// </summary>
|
||||
public void ClearLog()
|
||||
{
|
||||
rtbMainLog.Clear();
|
||||
Logger.Trace("Log cleared.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switches currently displayed GCI view inside the host panel.
|
||||
/// </summary>
|
||||
private void button2_Click(object sender, EventArgs e)
|
||||
{
|
||||
SwitchGciView(
|
||||
"CombinedActionsView",
|
||||
new CombinedActionsView(this, _bridge));
|
||||
}
|
||||
|
||||
private void button1_Click_1(object sender, EventArgs e)
|
||||
{
|
||||
SwitchGciView(
|
||||
"UniDataSorageActionsView",
|
||||
new UniDataSorageActionsView(this, _bridge));
|
||||
}
|
||||
|
||||
private void btnMetersAction_Click(object sender, EventArgs e)
|
||||
{
|
||||
SwitchGciView(
|
||||
"SlotsComPortsRegistersActionsView",
|
||||
new SlotsComPortsRegistersActionsView(this, _bridge, AddSlotRow, SaveSlots));
|
||||
}
|
||||
|
||||
private void btnMeterInit_Click_1(object sender, EventArgs e)
|
||||
{
|
||||
SwitchGciView(
|
||||
"ConfigurationView",
|
||||
new ConfigurationView(this));
|
||||
}
|
||||
|
||||
private void preadjustmenActionsViewButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
SwitchGciView(
|
||||
"PreadjustmenActionsView",
|
||||
new PreadjustmentActionsView(this, _bridge, AddSlotRow, SaveSlots));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
{
|
||||
partial class CombinedInterfaceView
|
||||
partial class CombinedActionsView
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
@ -10,7 +10,7 @@ using TBF.Rig.BridgeComponents.GciBridge.Interfaces;
|
||||
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
{
|
||||
public partial class CombinedInterfaceView : UserControl
|
||||
public partial class CombinedActionsView : UserControl
|
||||
{
|
||||
private readonly MainView _mainView;
|
||||
private readonly GciBridge _bridge;
|
||||
@ -19,7 +19,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
private readonly Dictionary<int, string> _pcbBySlot = new Dictionary<int, string>();
|
||||
private readonly Dictionary<int, string> _passwordBySlot = new Dictionary<int, string>();
|
||||
|
||||
public CombinedInterfaceView(MainView mainView, GciBridge bridge)
|
||||
public CombinedActionsView(MainView mainView, GciBridge bridge)
|
||||
{
|
||||
_mainView = mainView ?? throw new ArgumentNullException(nameof(mainView));
|
||||
_bridge = bridge ?? throw new ArgumentNullException(nameof(bridge));
|
||||
250
TBF/Rig/BridgeComponents/GciBridge/UI/StaraTuraAPI_GciBridge/PreadjustmentActionsView.Designer.cs
generated
Normal file
250
TBF/Rig/BridgeComponents/GciBridge/UI/StaraTuraAPI_GciBridge/PreadjustmentActionsView.Designer.cs
generated
Normal file
@ -0,0 +1,250 @@
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
{
|
||||
partial class PreadjustmentActionsView
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
private System.Windows.Forms.GroupBox grpSlots;
|
||||
|
||||
private System.Windows.Forms.Button preparationActionButton;
|
||||
private System.Windows.Forms.Button detectActionButton;
|
||||
private System.Windows.Forms.Button temperatureCalibrationActionButton;
|
||||
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
private System.Windows.Forms.TextBox txtLog;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && components != null)
|
||||
components.Dispose();
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.grpSlots = new System.Windows.Forms.GroupBox();
|
||||
this.completionActionButton = new System.Windows.Forms.Button();
|
||||
this.offsetTestActionButton = new System.Windows.Forms.Button();
|
||||
this.preparationActionButton = new System.Windows.Forms.Button();
|
||||
this.detectActionButton = new System.Windows.Forms.Button();
|
||||
this.temperatureCalibrationActionButton = new System.Windows.Forms.Button();
|
||||
this.amplitudeTestActionButton = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.txtLog = new System.Windows.Forms.TextBox();
|
||||
this.button1 = new System.Windows.Forms.Button();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.grpSlots.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// grpSlots
|
||||
//
|
||||
this.grpSlots.Controls.Add(this.label7);
|
||||
this.grpSlots.Controls.Add(this.label6);
|
||||
this.grpSlots.Controls.Add(this.label5);
|
||||
this.grpSlots.Controls.Add(this.label4);
|
||||
this.grpSlots.Controls.Add(this.label3);
|
||||
this.grpSlots.Controls.Add(this.label2);
|
||||
this.grpSlots.Controls.Add(this.label1);
|
||||
this.grpSlots.Controls.Add(this.button1);
|
||||
this.grpSlots.Controls.Add(this.completionActionButton);
|
||||
this.grpSlots.Controls.Add(this.offsetTestActionButton);
|
||||
this.grpSlots.Controls.Add(this.preparationActionButton);
|
||||
this.grpSlots.Controls.Add(this.detectActionButton);
|
||||
this.grpSlots.Controls.Add(this.temperatureCalibrationActionButton);
|
||||
this.grpSlots.Controls.Add(this.amplitudeTestActionButton);
|
||||
this.grpSlots.Location = new System.Drawing.Point(10, 10);
|
||||
this.grpSlots.Name = "grpSlots";
|
||||
this.grpSlots.Size = new System.Drawing.Size(689, 304);
|
||||
this.grpSlots.TabIndex = 2;
|
||||
this.grpSlots.TabStop = false;
|
||||
this.grpSlots.Text = "Slots by selection in the table";
|
||||
this.grpSlots.Enter += new System.EventHandler(this.grpSlots_Enter);
|
||||
//
|
||||
// completionActionButton
|
||||
//
|
||||
this.completionActionButton.Location = new System.Drawing.Point(390, 249);
|
||||
this.completionActionButton.Name = "completionActionButton";
|
||||
this.completionActionButton.Size = new System.Drawing.Size(150, 28);
|
||||
this.completionActionButton.TabIndex = 3;
|
||||
this.completionActionButton.Text = "Completition";
|
||||
//
|
||||
// offsetTestActionButton
|
||||
//
|
||||
this.offsetTestActionButton.Location = new System.Drawing.Point(334, 215);
|
||||
this.offsetTestActionButton.Name = "offsetTestActionButton";
|
||||
this.offsetTestActionButton.Size = new System.Drawing.Size(150, 28);
|
||||
this.offsetTestActionButton.TabIndex = 5;
|
||||
this.offsetTestActionButton.Text = "Offset test";
|
||||
//
|
||||
// preparationActionButton
|
||||
//
|
||||
this.preparationActionButton.Location = new System.Drawing.Point(203, 113);
|
||||
this.preparationActionButton.Name = "preparationActionButton";
|
||||
this.preparationActionButton.Size = new System.Drawing.Size(150, 28);
|
||||
this.preparationActionButton.TabIndex = 0;
|
||||
this.preparationActionButton.Text = "Preparation";
|
||||
this.preparationActionButton.Click += new System.EventHandler(this.preparationActionButton_Click);
|
||||
//
|
||||
// detectActionButton
|
||||
//
|
||||
this.detectActionButton.Location = new System.Drawing.Point(171, 79);
|
||||
this.detectActionButton.Name = "detectActionButton";
|
||||
this.detectActionButton.Size = new System.Drawing.Size(150, 28);
|
||||
this.detectActionButton.TabIndex = 1;
|
||||
this.detectActionButton.Text = "Detect";
|
||||
this.detectActionButton.Click += new System.EventHandler(this.detectActionButton_Click);
|
||||
//
|
||||
// temperatureCalibrationActionButton
|
||||
//
|
||||
this.temperatureCalibrationActionButton.Location = new System.Drawing.Point(285, 181);
|
||||
this.temperatureCalibrationActionButton.Name = "temperatureCalibrationActionButton";
|
||||
this.temperatureCalibrationActionButton.Size = new System.Drawing.Size(150, 28);
|
||||
this.temperatureCalibrationActionButton.TabIndex = 2;
|
||||
this.temperatureCalibrationActionButton.Text = "Temperature calibration";
|
||||
this.temperatureCalibrationActionButton.Click += new System.EventHandler(this.amplitudeTestActionButton_Click);
|
||||
//
|
||||
// amplitudeTestActionButton
|
||||
//
|
||||
this.amplitudeTestActionButton.Location = new System.Drawing.Point(246, 147);
|
||||
this.amplitudeTestActionButton.Name = "amplitudeTestActionButton";
|
||||
this.amplitudeTestActionButton.Size = new System.Drawing.Size(150, 28);
|
||||
this.amplitudeTestActionButton.TabIndex = 18;
|
||||
this.amplitudeTestActionButton.Text = "Amplitude test";
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Enabled = false;
|
||||
this.btnCancel.Location = new System.Drawing.Point(519, 320);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(180, 30);
|
||||
this.btnCancel.TabIndex = 4;
|
||||
this.btnCancel.Text = "Cancel task";
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// txtLog
|
||||
//
|
||||
this.txtLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.txtLog.Location = new System.Drawing.Point(10, 356);
|
||||
this.txtLog.Multiline = true;
|
||||
this.txtLog.Name = "txtLog";
|
||||
this.txtLog.ReadOnly = true;
|
||||
this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.txtLog.Size = new System.Drawing.Size(689, 232);
|
||||
this.txtLog.TabIndex = 5;
|
||||
this.txtLog.WordWrap = false;
|
||||
//
|
||||
// button1
|
||||
//
|
||||
this.button1.Location = new System.Drawing.Point(17, 28);
|
||||
this.button1.Name = "button1";
|
||||
this.button1.Size = new System.Drawing.Size(150, 28);
|
||||
this.button1.TabIndex = 108;
|
||||
this.button1.Text = "Preadjustment init";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(176, 121);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(22, 13);
|
||||
this.label1.TabIndex = 109;
|
||||
this.label1.Text = "--->";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(219, 155);
|
||||
this.label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(22, 13);
|
||||
this.label2.TabIndex = 110;
|
||||
this.label2.Text = "--->";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(258, 189);
|
||||
this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(22, 13);
|
||||
this.label3.TabIndex = 111;
|
||||
this.label3.Text = "--->";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(307, 223);
|
||||
this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(22, 13);
|
||||
this.label4.TabIndex = 112;
|
||||
this.label4.Text = "--->";
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(363, 257);
|
||||
this.label5.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(22, 13);
|
||||
this.label5.TabIndex = 113;
|
||||
this.label5.Text = "--->";
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(14, 87);
|
||||
this.label6.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(117, 13);
|
||||
this.label6.TabIndex = 114;
|
||||
this.label6.Text = "Preadjustment process:";
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Location = new System.Drawing.Point(144, 87);
|
||||
this.label7.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(22, 13);
|
||||
this.label7.TabIndex = 115;
|
||||
this.label7.Text = "--->";
|
||||
//
|
||||
// PreadjustmentActionsView
|
||||
//
|
||||
this.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.Controls.Add(this.grpSlots);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.Controls.Add(this.txtLog);
|
||||
this.Name = "PreadjustmentActionsView";
|
||||
this.Size = new System.Drawing.Size(719, 603);
|
||||
this.grpSlots.ResumeLayout(false);
|
||||
this.grpSlots.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Button completionActionButton;
|
||||
private System.Windows.Forms.Button offsetTestActionButton;
|
||||
private System.Windows.Forms.Button amplitudeTestActionButton;
|
||||
private System.Windows.Forms.Button button1;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.Label label6;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,405 @@
|
||||
using CordonelPreadjustmentUi;
|
||||
using CordonelPreadjustmentUi.Processes.Itinerary;
|
||||
using GenesisCordonelInterface.API;
|
||||
using GenesisCordonelInterface.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||
using static GenesisCordonelInterface.API.PublicModels;
|
||||
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.PreadjustmentMeter;
|
||||
using GciPublicModels = GenesisCordonelInterface.API.PublicModels;
|
||||
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
{
|
||||
public partial class PreadjustmentActionsView : UserControl
|
||||
{
|
||||
private readonly GciBridge _bridge;
|
||||
private readonly MainView _mainView;
|
||||
private CancellationTokenSource _cts;
|
||||
private readonly Action _addSlotAction;
|
||||
private readonly Action _saveAction;
|
||||
|
||||
public PreadjustmentActionsView(
|
||||
MainView mainview,
|
||||
GciBridge bridge,
|
||||
Action addSlotAction,
|
||||
Action saveAction)
|
||||
{
|
||||
_mainView = mainview ?? throw new ArgumentNullException(nameof(mainview));
|
||||
_bridge = bridge ?? throw new ArgumentNullException(nameof(bridge));
|
||||
|
||||
_addSlotAction = addSlotAction;
|
||||
_saveAction = saveAction;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
LoadRegisterComboBoxes();
|
||||
}
|
||||
|
||||
private void AddSlot()
|
||||
{
|
||||
_addSlotAction?.Invoke();
|
||||
}
|
||||
|
||||
private void SaveSlots()
|
||||
{
|
||||
_saveAction?.Invoke();
|
||||
}
|
||||
|
||||
private List<GciPublicModels.MeterBatchDebugStatus> GetSelectedSlots()
|
||||
{
|
||||
if (_mainView == null || _mainView._batchPanel == null)
|
||||
throw new Exception("Meter batch grid is not available.");
|
||||
|
||||
var slots = _mainView._batchPanel.GetSelectedGridData();
|
||||
|
||||
if (slots.Count == 0)
|
||||
throw new Exception("No selected slots in grid.");
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
private void RefreshGrid(int? removedSlot = null)
|
||||
{
|
||||
if (removedSlot.HasValue)
|
||||
{
|
||||
_mainView?._gciApi.SetSlotSelected(removedSlot.Value, false);
|
||||
_mainView?._batchPanel?.RemoveSlotRow(removedSlot.Value);
|
||||
}
|
||||
|
||||
if (_bridge?.gciExternalInterface != null)
|
||||
_bridge.gciExternalInterface.RaiseMeterBatchStatusChanged();
|
||||
}
|
||||
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
_cts?.Cancel();
|
||||
Log("Cancel requested.");
|
||||
}
|
||||
|
||||
private async void ExecuteAsync(Func<CancellationToken, Task> action)
|
||||
{
|
||||
try
|
||||
{
|
||||
SetBusy(true);
|
||||
|
||||
_cts = new CancellationTokenSource();
|
||||
|
||||
await action(_cts.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Log("Operation canceled.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log("ERROR: " + ex);
|
||||
|
||||
MessageBox.Show(
|
||||
ex.Message,
|
||||
"GciBridge API call failed",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_cts?.Dispose();
|
||||
_cts = null;
|
||||
|
||||
SetBusy(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetBusy(bool busy)
|
||||
{
|
||||
Cursor = busy ? Cursors.WaitCursor : Cursors.Default;
|
||||
|
||||
preparationActionButton.Enabled = !busy;
|
||||
detectActionButton.Enabled = !busy;
|
||||
temperatureCalibrationActionButton.Enabled = !busy;
|
||||
offsetTestActionButton.Enabled = !busy;
|
||||
completionActionButton.Enabled = !busy;
|
||||
amplitudeTestActionButton.Enabled = !busy;
|
||||
amplitudeTestActionButton.Enabled = !busy;
|
||||
temperatureCalibrationActionButton.Enabled = !busy;
|
||||
offsetTestActionButton.Enabled = !busy;
|
||||
completionActionButton.Enabled = !busy;
|
||||
|
||||
btnCancel.Enabled = busy;
|
||||
}
|
||||
|
||||
private void LogResult(string methodName, object result)
|
||||
{
|
||||
Log(methodName + " result:");
|
||||
Log(result == null ? "<null>" : result.ToString());
|
||||
}
|
||||
|
||||
private void Log(string message)
|
||||
{
|
||||
txtLog.AppendText(
|
||||
DateTime.Now.ToString("HH:mm:ss.fff") +
|
||||
" " +
|
||||
message +
|
||||
Environment.NewLine);
|
||||
}
|
||||
|
||||
private void LoadRegisterComboBoxes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void grpSlots_Enter(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void preparationActionButton_Click(
|
||||
object sender,
|
||||
EventArgs e)
|
||||
{
|
||||
ExecuteAsync(async token =>
|
||||
{
|
||||
await ExecutePreadjustmentForSelectedSlotsAsync(
|
||||
_bridge.Preadjustment_PreparationAsync,
|
||||
"Preparation",
|
||||
token);
|
||||
});
|
||||
}
|
||||
|
||||
private void amplitudeTestActionButton_Click(
|
||||
object sender,
|
||||
EventArgs e)
|
||||
{
|
||||
ExecuteAsync(async token =>
|
||||
{
|
||||
await ExecutePreadjustmentForSelectedSlotsAsync(
|
||||
_bridge.Preadjustment_AmplitudeTestAsync,
|
||||
"Amplitude Test",
|
||||
token);
|
||||
});
|
||||
}
|
||||
|
||||
private void temperatureCalibrationActionButton_Click(
|
||||
object sender,
|
||||
EventArgs e)
|
||||
{
|
||||
ExecuteAsync(async token =>
|
||||
{
|
||||
await ExecutePreadjustmentForSelectedSlotsAsync(
|
||||
_bridge.Preadjustment_TemperatureCalibrationAsync,
|
||||
"Temperature Calibration",
|
||||
token);
|
||||
});
|
||||
}
|
||||
|
||||
private void offsetTestActionButton_Click(
|
||||
object sender,
|
||||
EventArgs e)
|
||||
{
|
||||
ExecuteAsync(async token =>
|
||||
{
|
||||
await ExecutePreadjustmentForSelectedSlotsAsync(
|
||||
_bridge.Preadjustment_OffsetTestAsync,
|
||||
"Offset Test",
|
||||
token);
|
||||
});
|
||||
}
|
||||
|
||||
private void completionActionButton_Click(
|
||||
object sender,
|
||||
EventArgs e)
|
||||
{
|
||||
ExecuteAsync(async token =>
|
||||
{
|
||||
await ExecutePreadjustmentForSelectedSlotsAsync(
|
||||
_bridge.Preadjustment_CompletionAsync,
|
||||
"Completion",
|
||||
token);
|
||||
});
|
||||
}
|
||||
|
||||
private void detectActionButton_Click(
|
||||
object sender,
|
||||
EventArgs e)
|
||||
{
|
||||
ExecuteAsync(async token =>
|
||||
{
|
||||
var selectedSlots =
|
||||
_mainView._batchPanel.GetSelectedGridData();
|
||||
|
||||
if (!selectedSlots.Any())
|
||||
{
|
||||
Log("Detect: no selected slots.");
|
||||
return;
|
||||
}
|
||||
|
||||
_mainView._laatzenApi._settings =
|
||||
CreatePreAdjustmentSettings(selectedSlots);
|
||||
|
||||
_mainView._laatzenApi._meterControls =
|
||||
CreateMeterControls(selectedSlots);
|
||||
|
||||
PreadjustmentDetectResult result =
|
||||
await _bridge.Preadjustment_DetectAsync(token);
|
||||
|
||||
Log(
|
||||
result.Success
|
||||
? "Detect completed. " + result
|
||||
: "Detect failed. " + result);
|
||||
|
||||
RefreshGrid();
|
||||
});
|
||||
}
|
||||
|
||||
private ProcessProgress CreatePreparationProgress()
|
||||
{
|
||||
return new ProcessProgress
|
||||
{
|
||||
Setting = new PreAdjustmentSettingsContainer
|
||||
{
|
||||
|
||||
TempOnly = false,
|
||||
Culture =
|
||||
Thread.CurrentThread.CurrentCulture
|
||||
},
|
||||
|
||||
IsAutomaticMode = true
|
||||
};
|
||||
}
|
||||
|
||||
private List<MeterStateControl> CreateMeterControls(IEnumerable<GciPublicModels.MeterBatchDebugStatus> slots)
|
||||
{
|
||||
var controls =
|
||||
new List<MeterStateControl>();
|
||||
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
var ctl = new MeterStateControl(slot.Slot);
|
||||
|
||||
ctl.SetChecked(true);
|
||||
ctl.IsEnabled = true;
|
||||
|
||||
controls.Add(ctl);
|
||||
}
|
||||
|
||||
return controls;
|
||||
}
|
||||
|
||||
private PreAdjustmentSettingsContainer CreatePreAdjustmentSettings(IEnumerable<GciPublicModels.MeterBatchDebugStatus> slots)
|
||||
{
|
||||
var settings =
|
||||
new PreAdjustmentSettingsContainer();
|
||||
|
||||
settings.Meters =
|
||||
slots.Select(s => s.Slot).ToList();
|
||||
|
||||
settings.TempMeters =
|
||||
new List<int>();
|
||||
|
||||
settings.NumberOfPaths = 2;
|
||||
settings.TempOnly = false;
|
||||
settings.Culture =
|
||||
Thread.CurrentThread.CurrentCulture;
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void writeRegisterButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
/*ExecuteAsync(async token =>
|
||||
{
|
||||
string registerName = Convert.ToString(writeRegisterNameComboBox.Text).Trim();
|
||||
string valueText = writeRegisterValueTextBox.Text.Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(registerName))
|
||||
throw new Exception("Write register name is empty.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(valueText))
|
||||
throw new Exception("Write register value is empty.");
|
||||
|
||||
object value;
|
||||
|
||||
if (registerName == "GENESISFLOW_LedMode")
|
||||
{
|
||||
value = byte.Parse(valueText);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = valueText;
|
||||
}
|
||||
|
||||
var tasks = GetSelectedSlots()
|
||||
.Select(async slot =>
|
||||
{
|
||||
//var result = await _bridge.WriteRegisterAsync(slot.Slot, registerName, value, false, false, token);
|
||||
//var result = await _bridge.WriteRegisterWithRetryAsync(slot.Slot, registerName, value, false, false, token);
|
||||
|
||||
var result = Xylem.Common.Ui.CordonelPreadjustmentUi. Processes.WriteRegisterSafe(meter, "Calibration factor1", Register.Genesisflow.CalFactor1, setting.CalFactor1);
|
||||
Processes
|
||||
|
||||
return new
|
||||
{
|
||||
Slot = slot.Slot,
|
||||
Result = result
|
||||
};
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var results = await Task.WhenAll(tasks);
|
||||
|
||||
foreach (var item in results.OrderBy(x => x.Slot))
|
||||
{
|
||||
LogResult(
|
||||
$"WriteRegisterAsync slot {item.Slot}, register {registerName}, value {value}",
|
||||
item.Result);
|
||||
}
|
||||
|
||||
RefreshGrid();
|
||||
});*/
|
||||
}
|
||||
|
||||
private async Task ExecutePreadjustmentForSelectedSlotsAsync(
|
||||
Func<int, ProcessProgress, CancellationToken, Task<PreadjustmentProcessResult>> action,
|
||||
string processName,
|
||||
CancellationToken token)
|
||||
{
|
||||
var selectedSlots =
|
||||
_mainView._batchPanel.GetSelectedGridData();
|
||||
|
||||
if (!selectedSlots.Any())
|
||||
{
|
||||
Log(processName + ": no selected slots.");
|
||||
return;
|
||||
}
|
||||
|
||||
var pp =
|
||||
CreatePreparationProgress();
|
||||
|
||||
foreach (var selectedSlot in selectedSlots)
|
||||
{
|
||||
PreadjustmentProcessResult result =
|
||||
await action(
|
||||
selectedSlot.Slot,
|
||||
pp,
|
||||
token);
|
||||
|
||||
Log(result.Success
|
||||
? processName + " completed. " + result
|
||||
: processName + " failed. " + result);
|
||||
|
||||
if (!result.Success)
|
||||
break;
|
||||
}
|
||||
|
||||
RefreshGrid();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
{
|
||||
partial class GenesisCordonelInterfaceView
|
||||
partial class SlotsComPortsRegistersActionsView
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
this.btnGetSlot = new System.Windows.Forms.Button();
|
||||
this.btnCleanAllSlots = new System.Windows.Forms.Button();
|
||||
this.btnCleanSlot = new System.Windows.Forms.Button();
|
||||
this.writeRegisterValueTypeLabel = new System.Windows.Forms.Label();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.txtLog = new System.Windows.Forms.TextBox();
|
||||
this.grpSlots.SuspendLayout();
|
||||
@ -49,6 +50,9 @@
|
||||
//
|
||||
// grpSlots
|
||||
//
|
||||
this.grpSlots.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.grpSlots.Controls.Add(this.writeRegisterNameComboBox);
|
||||
this.grpSlots.Controls.Add(this.readRegisterNameComboBox);
|
||||
this.grpSlots.Controls.Add(this.label4);
|
||||
@ -66,9 +70,10 @@
|
||||
this.grpSlots.Controls.Add(this.btnGetSlot);
|
||||
this.grpSlots.Controls.Add(this.btnCleanAllSlots);
|
||||
this.grpSlots.Controls.Add(this.btnCleanSlot);
|
||||
this.grpSlots.Controls.Add(this.writeRegisterValueTypeLabel);
|
||||
this.grpSlots.Location = new System.Drawing.Point(10, 10);
|
||||
this.grpSlots.Name = "grpSlots";
|
||||
this.grpSlots.Size = new System.Drawing.Size(689, 304);
|
||||
this.grpSlots.Size = new System.Drawing.Size(726, 304);
|
||||
this.grpSlots.TabIndex = 2;
|
||||
this.grpSlots.TabStop = false;
|
||||
this.grpSlots.Text = "Slots by selection in the table";
|
||||
@ -103,7 +108,7 @@
|
||||
//
|
||||
this.writeRegisterValueTextBox.Location = new System.Drawing.Point(555, 264);
|
||||
this.writeRegisterValueTextBox.Name = "writeRegisterValueTextBox";
|
||||
this.writeRegisterValueTextBox.Size = new System.Drawing.Size(117, 20);
|
||||
this.writeRegisterValueTextBox.Size = new System.Drawing.Size(85, 20);
|
||||
this.writeRegisterValueTextBox.TabIndex = 12;
|
||||
//
|
||||
// label3
|
||||
@ -223,6 +228,15 @@
|
||||
this.btnCleanSlot.Text = "CleanSlot(slot)";
|
||||
this.btnCleanSlot.Click += new System.EventHandler(this.btnCleanSlot_Click);
|
||||
//
|
||||
// writeRegisterValueTypeLabel
|
||||
//
|
||||
this.writeRegisterValueTypeLabel.AutoSize = true;
|
||||
this.writeRegisterValueTypeLabel.Location = new System.Drawing.Point(646, 267);
|
||||
this.writeRegisterValueTypeLabel.Name = "writeRegisterValueTypeLabel";
|
||||
this.writeRegisterValueTypeLabel.Size = new System.Drawing.Size(36, 13);
|
||||
this.writeRegisterValueTypeLabel.TabIndex = 19;
|
||||
this.writeRegisterValueTypeLabel.Text = "type: -";
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Enabled = false;
|
||||
@ -243,18 +257,18 @@
|
||||
this.txtLog.Name = "txtLog";
|
||||
this.txtLog.ReadOnly = true;
|
||||
this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.txtLog.Size = new System.Drawing.Size(689, 232);
|
||||
this.txtLog.Size = new System.Drawing.Size(726, 232);
|
||||
this.txtLog.TabIndex = 5;
|
||||
this.txtLog.WordWrap = false;
|
||||
//
|
||||
// GenesisCordonelInterfaceView
|
||||
// SlotsComPortsRegistersActionsView
|
||||
//
|
||||
this.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.Controls.Add(this.grpSlots);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.Controls.Add(this.txtLog);
|
||||
this.Name = "GenesisCordonelInterfaceView";
|
||||
this.Size = new System.Drawing.Size(719, 603);
|
||||
this.Name = "SlotsComPortsRegistersActionsView";
|
||||
this.Size = new System.Drawing.Size(756, 603);
|
||||
this.grpSlots.ResumeLayout(false);
|
||||
this.grpSlots.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
@ -275,5 +289,6 @@
|
||||
private System.Windows.Forms.ComboBox readRegisterNameComboBox;
|
||||
private System.Windows.Forms.Button btnLogin;
|
||||
private System.Windows.Forms.Button btnCleanSlot;
|
||||
private System.Windows.Forms.Label writeRegisterValueTypeLabel;
|
||||
}
|
||||
}
|
||||
@ -10,15 +10,17 @@ using GciPublicModels = GenesisCordonelInterface.API.PublicModels;
|
||||
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
{
|
||||
public partial class GenesisCordonelInterfaceView : UserControl
|
||||
public partial class SlotsComPortsRegistersActionsView : UserControl
|
||||
{
|
||||
private readonly GciBridge _bridge;
|
||||
private readonly MainView _mainView;
|
||||
private CancellationTokenSource _cts;
|
||||
private readonly Action _addSlotAction;
|
||||
private readonly Action _saveAction;
|
||||
private readonly Dictionary<string, Type> _registerTypes =
|
||||
new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public GenesisCordonelInterfaceView(
|
||||
public SlotsComPortsRegistersActionsView(
|
||||
MainView mainview,
|
||||
GciBridge bridge,
|
||||
Action addSlotAction,
|
||||
@ -33,6 +35,13 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
InitializeComponent();
|
||||
|
||||
LoadRegisterComboBoxes();
|
||||
|
||||
_mainView._batchPanel.GetMeterRegistersClicked -= LoadRegisterComboBoxes;
|
||||
_mainView._batchPanel.GetMeterRegistersClicked += LoadRegisterComboBoxes;
|
||||
writeRegisterNameComboBox.SelectedIndexChanged -= writeRegisterNameComboBox_SelectedIndexChanged;
|
||||
writeRegisterNameComboBox.SelectedIndexChanged += writeRegisterNameComboBox_SelectedIndexChanged;
|
||||
writeRegisterNameComboBox.TextChanged -= writeRegisterNameComboBox_SelectedIndexChanged;
|
||||
writeRegisterNameComboBox.TextChanged += writeRegisterNameComboBox_SelectedIndexChanged;
|
||||
}
|
||||
|
||||
private void AddSlot()
|
||||
@ -48,14 +57,14 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
private List<GciPublicModels.MeterBatchDebugStatus> GetSelectedSlots()
|
||||
{
|
||||
if (_mainView == null || _mainView._batchPanel == null)
|
||||
throw new Exception("Meter batch grid is not available.");
|
||||
{
|
||||
Log("Meter batch grid is not available.");
|
||||
|
||||
var slots = _mainView._batchPanel.GetSelectedGridData();
|
||||
return new List<GciPublicModels.MeterBatchDebugStatus>();
|
||||
}
|
||||
|
||||
if (slots.Count == 0)
|
||||
throw new Exception("No selected slots in grid.");
|
||||
|
||||
return slots;
|
||||
return _mainView._batchPanel.GetSelectedGridData()
|
||||
?? new List<GciPublicModels.MeterBatchDebugStatus>();
|
||||
}
|
||||
|
||||
private void RefreshGrid(int? removedSlot = null)
|
||||
@ -414,16 +423,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
if (string.IsNullOrWhiteSpace(valueText))
|
||||
throw new Exception("Write register value is empty.");
|
||||
|
||||
object value;
|
||||
|
||||
if (registerName == "GENESISFLOW_LedMode")
|
||||
{
|
||||
value = byte.Parse(valueText);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = valueText;
|
||||
}
|
||||
object value = ConvertTextToRegisterValue(registerName, valueText);
|
||||
|
||||
var tasks = GetSelectedSlots()
|
||||
.Select(async slot =>
|
||||
@ -530,18 +530,162 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
|
||||
private void LoadRegisterComboBoxes()
|
||||
{
|
||||
var registers = _bridge.GetAllRegisterNames();
|
||||
_registerTypes.Clear();
|
||||
|
||||
readRegisterNameComboBox.Items.Clear();
|
||||
writeRegisterNameComboBox.Items.Clear();
|
||||
|
||||
readRegisterNameComboBox.Items.AddRange(registers.ToArray());
|
||||
writeRegisterNameComboBox.Items.AddRange(registers.ToArray());
|
||||
var selectedSlots = GetSelectedSlots();
|
||||
|
||||
if (selectedSlots.Count == 0)
|
||||
{
|
||||
Log("No selected slot.");
|
||||
return;
|
||||
}
|
||||
|
||||
int slot = selectedSlots
|
||||
.OrderBy(x => x.Slot)
|
||||
.First()
|
||||
.Slot;
|
||||
|
||||
var registers = _mainView._laatzenApi.GetRegistersDicForSlot(slot);
|
||||
|
||||
var uniqueRegisters = registers
|
||||
.GroupBy(x => x.Key.GetIdent())
|
||||
.Select(g => g.First())
|
||||
.OrderBy(x => x.Key.GetIdent())
|
||||
.ToList();
|
||||
|
||||
foreach (var item in uniqueRegisters)
|
||||
{
|
||||
string registerName = item.Key.GetIdent();
|
||||
Type dataType = item.Key.DataType;
|
||||
|
||||
_registerTypes[registerName] = dataType;
|
||||
|
||||
readRegisterNameComboBox.Items.Add(registerName);
|
||||
writeRegisterNameComboBox.Items.Add(registerName);
|
||||
}
|
||||
|
||||
Log($"Loaded {uniqueRegisters.Count} unique registers from slot {slot}");
|
||||
}
|
||||
|
||||
private void grpSlots_Enter(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void writeRegisterNameComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
string registerName = Convert.ToString(writeRegisterNameComboBox.Text).Trim();
|
||||
|
||||
if (_registerTypes.TryGetValue(registerName, out var type))
|
||||
{
|
||||
writeRegisterValueTypeLabel.Text = $"type: {type.Name}";
|
||||
}
|
||||
else
|
||||
{
|
||||
writeRegisterValueTypeLabel.Text = "type: -";
|
||||
}
|
||||
}
|
||||
|
||||
private object ConvertTextToRegisterValue(
|
||||
string registerName,
|
||||
string valueText)
|
||||
{
|
||||
if (!_registerTypes.TryGetValue(
|
||||
registerName,
|
||||
out var targetType))
|
||||
{
|
||||
throw new Exception(
|
||||
$"Unknown register type for register '{registerName}'.");
|
||||
}
|
||||
|
||||
return ConvertTextToType(
|
||||
valueText,
|
||||
targetType,
|
||||
registerName);
|
||||
}
|
||||
|
||||
private object ConvertTextToType(
|
||||
string valueText,
|
||||
Type targetType,
|
||||
string registerName)
|
||||
{
|
||||
if (targetType == typeof(string))
|
||||
return valueText;
|
||||
|
||||
if (targetType.IsEnum)
|
||||
{
|
||||
return Enum.Parse(
|
||||
targetType,
|
||||
valueText,
|
||||
true);
|
||||
}
|
||||
|
||||
if (targetType == typeof(byte[]))
|
||||
{
|
||||
return ParseByteArray(valueText);
|
||||
}
|
||||
|
||||
if (targetType.Name == "Enum8")
|
||||
{
|
||||
return byte.Parse(valueText);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Convert.ChangeType(
|
||||
valueText,
|
||||
targetType,
|
||||
System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception(
|
||||
$"Value '{valueText}' cannot be converted to '{targetType.Name}' for register '{registerName}'.",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] ParseByteArray(string valueText)
|
||||
{
|
||||
valueText = valueText.Trim();
|
||||
|
||||
if (valueText.Contains("-") ||
|
||||
valueText.Contains(" "))
|
||||
{
|
||||
return valueText
|
||||
.Split(
|
||||
new[] { '-', ' ', ',', ';' },
|
||||
StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(x => x.Replace("0x", ""))
|
||||
.Select(x => Convert.ToByte(x, 16))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
valueText =
|
||||
valueText.Replace("0x", "");
|
||||
|
||||
if (valueText.Length % 2 != 0)
|
||||
{
|
||||
throw new Exception(
|
||||
"Hex string length must be even.");
|
||||
}
|
||||
|
||||
byte[] result =
|
||||
new byte[valueText.Length / 2];
|
||||
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
string hex =
|
||||
valueText.Substring(i * 2, 2);
|
||||
|
||||
result[i] =
|
||||
Convert.ToByte(hex, 16);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,10 @@
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
{
|
||||
partial class UniDataStorageReaderInterfaceView
|
||||
partial class UniDataSorageActionsView
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
private System.Windows.Forms.GroupBox grpStorage;
|
||||
private System.Windows.Forms.Label lblPcbId;
|
||||
private System.Windows.Forms.TextBox txtPcbId;
|
||||
private System.Windows.Forms.Button btnGetPasswordByPcb;
|
||||
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
@ -23,11 +21,11 @@
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.grpStorage = new System.Windows.Forms.GroupBox();
|
||||
this.lblPcbId = new System.Windows.Forms.Label();
|
||||
this.txtPcbId = new System.Windows.Forms.TextBox();
|
||||
this.btnGetPasswordByPcb = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.txtLog = new System.Windows.Forms.TextBox();
|
||||
this.lblPcbId = new System.Windows.Forms.Label();
|
||||
this.txtPcbId = new System.Windows.Forms.TextBox();
|
||||
this.grpStorage.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
@ -38,27 +36,11 @@
|
||||
this.grpStorage.Controls.Add(this.btnGetPasswordByPcb);
|
||||
this.grpStorage.Location = new System.Drawing.Point(10, 37);
|
||||
this.grpStorage.Name = "grpStorage";
|
||||
this.grpStorage.Size = new System.Drawing.Size(200, 120);
|
||||
this.grpStorage.Size = new System.Drawing.Size(200, 261);
|
||||
this.grpStorage.TabIndex = 0;
|
||||
this.grpStorage.TabStop = false;
|
||||
this.grpStorage.Text = "UniDataStorageReader for GCI";
|
||||
//
|
||||
// lblPcbId
|
||||
//
|
||||
this.lblPcbId.AutoSize = true;
|
||||
this.lblPcbId.Location = new System.Drawing.Point(10, 25);
|
||||
this.lblPcbId.Name = "lblPcbId";
|
||||
this.lblPcbId.Size = new System.Drawing.Size(45, 13);
|
||||
this.lblPcbId.TabIndex = 0;
|
||||
this.lblPcbId.Text = "PCB ID:";
|
||||
//
|
||||
// txtPcbId
|
||||
//
|
||||
this.txtPcbId.Location = new System.Drawing.Point(65, 22);
|
||||
this.txtPcbId.Name = "txtPcbId";
|
||||
this.txtPcbId.Size = new System.Drawing.Size(120, 20);
|
||||
this.txtPcbId.TabIndex = 1;
|
||||
//
|
||||
// btnGetPasswordByPcb
|
||||
//
|
||||
this.btnGetPasswordByPcb.Location = new System.Drawing.Point(10, 55);
|
||||
@ -91,12 +73,28 @@
|
||||
this.txtLog.TabIndex = 4;
|
||||
this.txtLog.WordWrap = false;
|
||||
//
|
||||
// UniDataStorageReaderInterfaceView
|
||||
// lblPcbId
|
||||
//
|
||||
this.lblPcbId.AutoSize = true;
|
||||
this.lblPcbId.Location = new System.Drawing.Point(10, 25);
|
||||
this.lblPcbId.Name = "lblPcbId";
|
||||
this.lblPcbId.Size = new System.Drawing.Size(45, 13);
|
||||
this.lblPcbId.TabIndex = 0;
|
||||
this.lblPcbId.Text = "PCB ID:";
|
||||
//
|
||||
// txtPcbId
|
||||
//
|
||||
this.txtPcbId.Location = new System.Drawing.Point(65, 22);
|
||||
this.txtPcbId.Name = "txtPcbId";
|
||||
this.txtPcbId.Size = new System.Drawing.Size(120, 20);
|
||||
this.txtPcbId.TabIndex = 1;
|
||||
//
|
||||
// UniDataSorageActionsView
|
||||
//
|
||||
this.Controls.Add(this.grpStorage);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.Controls.Add(this.txtLog);
|
||||
this.Name = "UniDataStorageReaderInterfaceView";
|
||||
this.Name = "UniDataSorageActionsView";
|
||||
this.Size = new System.Drawing.Size(740, 370);
|
||||
this.grpStorage.ResumeLayout(false);
|
||||
this.grpStorage.PerformLayout();
|
||||
@ -104,5 +102,8 @@
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Label lblPcbId;
|
||||
private System.Windows.Forms.TextBox txtPcbId;
|
||||
}
|
||||
}
|
||||
@ -5,13 +5,13 @@ using System.Windows.Forms;
|
||||
|
||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||
{
|
||||
public partial class UniDataStorageReaderInterfaceView : UserControl
|
||||
public partial class UniDataSorageActionsView : UserControl
|
||||
{
|
||||
private readonly MainView _mainView;
|
||||
private readonly GciBridge _bridge;
|
||||
private CancellationTokenSource _cts;
|
||||
|
||||
public UniDataStorageReaderInterfaceView(MainView mainView, GciBridge bridge)
|
||||
public UniDataSorageActionsView(MainView mainView, GciBridge bridge)
|
||||
{
|
||||
_mainView = mainView ?? throw new ArgumentNullException(nameof(mainView));
|
||||
_bridge = bridge ?? throw new ArgumentNullException(nameof(bridge));
|
||||
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<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" msdata:Ordinal="1" />
|
||||
</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>
|
||||
</root>
|
||||
@ -253,17 +253,23 @@
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\MainView.Designer.cs">
|
||||
<DependentUpon>MainView.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\UniDataStorageReaderInterfaceView.cs">
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\PreadjustmentActionsView.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\UniDataStorageReaderInterfaceView.Designer.cs">
|
||||
<DependentUpon>UniDataStorageReaderInterfaceView.cs</DependentUpon>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\PreadjustmentActionsView.Designer.cs">
|
||||
<DependentUpon>PreadjustmentActionsView.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\CombinedInterfaceView.cs">
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\UniDataSorageActionsView.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\CombinedInterfaceView.Designer.cs">
|
||||
<DependentUpon>CombinedInterfaceView.cs</DependentUpon>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\UniDataSorageActionsView.Designer.cs">
|
||||
<DependentUpon>UniDataSorageActionsView.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\CombinedActionsView.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\CombinedActionsView.Designer.cs">
|
||||
<DependentUpon>CombinedActionsView.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\ConfigurationView.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
@ -271,11 +277,11 @@
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\ConfigurationView.Designer.cs">
|
||||
<DependentUpon>ConfigurationView.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\GenesisCordonelInterfaceView.cs">
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\SlotsComPortsRegistersActionsView.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\GenesisCordonelInterfaceView.Designer.cs">
|
||||
<DependentUpon>GenesisCordonelInterfaceView.cs</DependentUpon>
|
||||
<Compile Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\SlotsComPortsRegistersActionsView.Designer.cs">
|
||||
<DependentUpon>SlotsComPortsRegistersActionsView.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\BuiltIn\PumpTandem\Pump.cs" />
|
||||
<Compile Include="Rig\BuiltIn\PumpTandem\PumpCfg.cs" />
|
||||
@ -3310,17 +3316,20 @@
|
||||
<EmbeddedResource Include="Rig\BridgeComponents\GciBridge\UI\MainView.resx">
|
||||
<DependentUpon>MainView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\CombinedInterfaceView.resx">
|
||||
<DependentUpon>CombinedInterfaceView.cs</DependentUpon>
|
||||
<EmbeddedResource Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\CombinedActionsView.resx">
|
||||
<DependentUpon>CombinedActionsView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\ConfigurationView.resx">
|
||||
<DependentUpon>ConfigurationView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\UniDataStorageReaderInterfaceView.resx">
|
||||
<DependentUpon>UniDataStorageReaderInterfaceView.cs</DependentUpon>
|
||||
<EmbeddedResource Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\PreadjustmentActionsView.resx">
|
||||
<DependentUpon>PreadjustmentActionsView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\GenesisCordonelInterfaceView.resx">
|
||||
<DependentUpon>GenesisCordonelInterfaceView.cs</DependentUpon>
|
||||
<EmbeddedResource Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\UniDataSorageActionsView.resx">
|
||||
<DependentUpon>UniDataSorageActionsView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\BridgeComponents\GciBridge\UI\StaraTuraAPI_GciBridge\SlotsComPortsRegistersActionsView.resx">
|
||||
<DependentUpon>SlotsComPortsRegistersActionsView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\BuiltIn\PumpTandem\PumpCfgCtrl.resx">
|
||||
<DependentUpon>PumpCfgCtrl.cs</DependentUpon>
|
||||
@ -4437,6 +4446,18 @@
|
||||
<Project>{439D0878-C76E-452B-B17D-209A89E91D36}</Project>
|
||||
<Name>Dirichlet.Numerics</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\CordonelPreadjustmentUi\CordonelPreadjustmentUi.csproj">
|
||||
<Project>{d0c8d887-ed52-40ab-a069-90bce0e801e2}</Project>
|
||||
<Name>CordonelPreadjustmentUi</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Hardware\WaterMeter\Genesis\Registers\Registers.csproj">
|
||||
<Project>{f4aaf7e6-7333-4284-b735-e32deb076c64}</Project>
|
||||
<Name>Registers</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Logic\ProductionOrderCore\ProductionOrderCore.csproj">
|
||||
<Project>{6d2777bb-7a88-466d-a49b-3266f9bf0160}</Project>
|
||||
<Name>ProductionOrderCore</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GemCard\GemCard.csproj">
|
||||
<Project>{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}</Project>
|
||||
<Name>GemCard</Name>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user