Merge branch 'develop/SLM-PT50_genesisDirectDecode' into develop/SLM-PT50_genesisDirectDecode_special
# Conflicts: # GenesisCordonelInterface/UI/LaatzenAPI_CordonelPreadjustmentUI/FrmCordonelPreadjustmentUI.cs # TBF/TBF.csproj
This commit is contained in:
@@ -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;
|
||||||
using NLog.Fluent;
|
using NLog.Fluent;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Configuration;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
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.GenesisCore;
|
||||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||||
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
|
||||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters;
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters;
|
||||||
|
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||||
using static GenesisCordonelInterface.API.PublicModels;
|
using static GenesisCordonelInterface.API.PublicModels;
|
||||||
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
|
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
|
||||||
using static Xylem.Common.Hardware.WaterMeter.Genesis.Registers.Register;
|
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 Lazy<ILogger> Logger = new Lazy<ILogger>(() => LogManager.GetLogger("GCI"));
|
||||||
private static readonly NLog.ILogger Logger = NLog.LogManager.GetLogger("GenesisCordonelInterface");
|
private static readonly NLog.ILogger Logger = NLog.LogManager.GetLogger("GenesisCordonelInterface");
|
||||||
|
|
||||||
|
//GenesisToolBox
|
||||||
private readonly MeterBatch _meterBatch = new MeterBatch();
|
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
|
// Protects all access to _meterBatch.ListOfMeters
|
||||||
private readonly object _meterBatchLock = new object();
|
private readonly object _meterBatchLock = new object();
|
||||||
private static readonly object _setupGenesisMeterLock = new object();
|
private static readonly object _setupGenesisMeterLock = new object();
|
||||||
@@ -75,16 +89,19 @@ namespace GenesisCordonelInterface.API
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================================== MeterBatch Debug ==================================
|
#region ================================== MeterBatch Debug ==================================
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
public List<MeterBatchDebugStatus> GetMeterBatchDebugStatuses()
|
public List<MeterBatchDebugStatus> GetMeterBatchDebugStatuses()
|
||||||
{
|
{
|
||||||
List<GenesisMeter> meters;
|
List<ZeroFlowGenesisMeter> meters;
|
||||||
|
|
||||||
//just snapshot of list under lock
|
//just snapshot of list under lock
|
||||||
lock (_meterBatchLock)
|
lock (_meterBatchLock)
|
||||||
{
|
{
|
||||||
meters = _meterBatch.ListOfMeters
|
meters = _meterBatch.ListOfMeters
|
||||||
.OfType<GenesisMeter>()
|
.OfType<ZeroFlowGenesisMeter>()
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +169,7 @@ namespace GenesisCordonelInterface.API
|
|||||||
lock (_meterBatchLock)
|
lock (_meterBatchLock)
|
||||||
{
|
{
|
||||||
return _meterBatch.ListOfMeters
|
return _meterBatch.ListOfMeters
|
||||||
.OfType<GenesisMeter>()
|
.OfType<ZeroFlowGenesisMeter>()
|
||||||
.FirstOrDefault(m => m.Slot == slot);
|
.FirstOrDefault(m => m.Slot == slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,7 +210,7 @@ namespace GenesisCordonelInterface.API
|
|||||||
{
|
{
|
||||||
lock (_meterBatchLock)
|
lock (_meterBatchLock)
|
||||||
{
|
{
|
||||||
foreach (var meter in _meterBatch.ListOfMeters.OfType<GenesisMeter>())
|
foreach (var meter in _meterBatch.ListOfMeters.OfType<ZeroFlowGenesisMeter>())
|
||||||
{
|
{
|
||||||
meter.DisposeMeter();
|
meter.DisposeMeter();
|
||||||
}
|
}
|
||||||
@@ -228,6 +245,16 @@ namespace GenesisCordonelInterface.API
|
|||||||
return string.IsNullOrWhiteSpace(port) ? "<empty>" : port;
|
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
|
#endregion
|
||||||
|
|
||||||
#region ================================== INIT/UPDATE ==================================
|
#region ================================== INIT/UPDATE ==================================
|
||||||
@@ -345,7 +372,7 @@ namespace GenesisCordonelInterface.API
|
|||||||
PortConfig? req,
|
PortConfig? req,
|
||||||
PortConfig? str)
|
PortConfig? str)
|
||||||
{
|
{
|
||||||
GenesisMeter meter = new GenesisMeter();
|
ZeroFlowGenesisMeter meter = new ZeroFlowGenesisMeter(0, 3, !(_meterControls is TempMeterStateControl), useForPreadjustmentUI: false);
|
||||||
|
|
||||||
meter.Slot = slot;
|
meter.Slot = slot;
|
||||||
|
|
||||||
@@ -354,7 +381,8 @@ namespace GenesisCordonelInterface.API
|
|||||||
meter.requestPortConfig = req;
|
meter.requestPortConfig = req;
|
||||||
meter.streamingPortConfig = str;
|
meter.streamingPortConfig = str;
|
||||||
|
|
||||||
//meter.SetupGenesisMeter(slot, req, str, true);
|
meter.onlineOperation = false;
|
||||||
|
|
||||||
lock (_meterBatchLock)
|
lock (_meterBatchLock)
|
||||||
{
|
{
|
||||||
_meterBatch.AddMeter2(meter);
|
_meterBatch.AddMeter2(meter);
|
||||||
@@ -942,9 +970,17 @@ namespace GenesisCordonelInterface.API
|
|||||||
|
|
||||||
var meter = GetMeterThreadSafe(slot);
|
var meter = GetMeterThreadSafe(slot);
|
||||||
|
|
||||||
meter.Logout();
|
bool logoutSuccess = meter.Logout();
|
||||||
meter.Disconnect();
|
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;
|
bool success = !meter.IsConnected && !meter.IsLoggedOn;
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
@@ -1370,5 +1406,812 @@ namespace GenesisCordonelInterface.API
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#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.Collections.Generic;
|
||||||
using System.IO.Ports;
|
using System.IO.Ports;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||||
|
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||||
using static GenesisCordonelInterface.API.PublicModels;
|
using static GenesisCordonelInterface.API.PublicModels;
|
||||||
|
|
||||||
namespace GenesisCordonelInterface.API
|
namespace GenesisCordonelInterface.API
|
||||||
@@ -22,6 +26,8 @@ namespace GenesisCordonelInterface.API
|
|||||||
_innerMeterAPI = new InterfaceGCIToLaatzen();
|
_innerMeterAPI = new InterfaceGCIToLaatzen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
#region ================================== PORT DETECTION ==================================
|
#region ================================== PORT DETECTION ==================================
|
||||||
|
|
||||||
public PortDetectionResult DetectStreamingPort(int slot)
|
public PortDetectionResult DetectStreamingPort(int slot)
|
||||||
@@ -424,7 +430,6 @@ namespace GenesisCordonelInterface.API
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================================== METER BATCH SETUP ==================================
|
#region ================================== METER BATCH SETUP ==================================
|
||||||
// ----------------------------------------------------
|
|
||||||
|
|
||||||
public void ReloadSlotSetup()
|
public void ReloadSlotSetup()
|
||||||
{
|
{
|
||||||
@@ -438,12 +443,63 @@ namespace GenesisCordonelInterface.API
|
|||||||
RaiseMeterBatchStatusChanged();
|
RaiseMeterBatchStatusChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region ================================== Register names ==================================
|
||||||
|
|
||||||
public List<string> GetAllRegisterNames()
|
public List<string> GetAllRegisterNames()
|
||||||
{
|
{
|
||||||
return _innerMeterAPI.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -440,6 +440,42 @@ namespace GenesisCordonelInterface.API
|
|||||||
Message);
|
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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,15 @@ namespace GenesisCordonelInterface.Core.Threading
|
|||||||
|
|
||||||
public static class RetryWorker
|
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>(
|
public static async Task<RetryResult<T>> RunWithRetryAsync<T>(
|
||||||
Func<Task<T>> action,
|
Func<Task<T>> action,
|
||||||
Func<T, bool> isSuccess,
|
Func<T, bool> isSuccess,
|
||||||
@@ -41,21 +50,53 @@ namespace GenesisCordonelInterface.Core.Threading
|
|||||||
|
|
||||||
for (int attempt = 1; attempt <= maxAttempts; attempt++)
|
for (int attempt = 1; attempt <= maxAttempts; attempt++)
|
||||||
{
|
{
|
||||||
var actionTask = action();
|
Task<T> actionTask = null;
|
||||||
var timeoutTask = Task.Delay(timeoutMs);
|
|
||||||
|
|
||||||
var completedTask = await Task.WhenAny(actionTask, timeoutTask);
|
try
|
||||||
|
|
||||||
if (completedTask == timeoutTask)
|
|
||||||
{
|
{
|
||||||
timedOut = true;
|
log?.Invoke($"{operationName} started. Attempt {attempt}/{maxAttempts}");
|
||||||
log?.Invoke($"{operationName} timeout attempt {attempt}/{maxAttempts}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lastResult = await actionTask;
|
|
||||||
|
|
||||||
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>
|
return new RetryResult<T>
|
||||||
{
|
{
|
||||||
@@ -63,15 +104,29 @@ namespace GenesisCordonelInterface.Core.Threading
|
|||||||
Success = true,
|
Success = true,
|
||||||
Attempts = attempt,
|
Attempts = attempt,
|
||||||
Duration = DateTime.Now - started,
|
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)
|
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>
|
return new RetryResult<T>
|
||||||
|
|||||||
+151
-9
@@ -4,21 +4,32 @@ using System.Collections.Generic;
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Xylem.Common.CommonCore.Consts;
|
using Xylem.Common.CommonCore.Consts;
|
||||||
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
|
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.Hardware.WaterMeter.WaterMeterCore;
|
||||||
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
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
|
namespace GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI
|
||||||
{
|
{
|
||||||
public partial class FrmCordonelPreadjustmentUI : Form
|
public partial class FrmCordonelPreadjustmentUI : Form
|
||||||
{
|
{
|
||||||
private PreAdjustmentControl preadjustCtl;
|
public PreAdjustmentControl preadjustCtl;//...MF
|
||||||
private PreAdjustmentSettingsContainer mainSettings = new PreAdjustmentSettingsContainer();
|
private PreAdjustmentSettingsContainer mainSettings = new PreAdjustmentSettingsContainer();
|
||||||
|
public MeterBatch _externMetersBatch;
|
||||||
|
|
||||||
public FrmCordonelPreadjustmentUI()
|
public FrmCordonelPreadjustmentUI()
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
public FrmCordonelPreadjustmentUI(MeterBatch externMetersBatch)
|
||||||
|
{
|
||||||
|
_externMetersBatch = externMetersBatch;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +37,7 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
preadjustCtl = new PreAdjustmentControl(mainSettings);
|
preadjustCtl = new PreAdjustmentControl(mainSettings, _externMetersBatch);
|
||||||
tab_ZeroFlowCal.Controls.Add(preadjustCtl);
|
tab_ZeroFlowCal.Controls.Add(preadjustCtl);
|
||||||
|
|
||||||
|
|
||||||
@@ -68,7 +79,7 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI
|
|||||||
{
|
{
|
||||||
if (e.TabPage.Name == tab_ZeroFlowCal.Name)
|
if (e.TabPage.Name == tab_ZeroFlowCal.Name)
|
||||||
{
|
{
|
||||||
try
|
/*try
|
||||||
{
|
{
|
||||||
var _serialConfigFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Genesis", ProgramConfig.SerialConfigFileName);
|
var _serialConfigFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Genesis", ProgramConfig.SerialConfigFileName);
|
||||||
|
|
||||||
@@ -96,11 +107,81 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_CordonelPreadjustmentUI
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBox.Show($"use default meters because of {ex.Message}");
|
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.NumberOfPaths = cB_SinglePath.Checked ? 1 : 3;
|
||||||
mainSettings.LowerTempLimit = (double)nUD_SettingsTempMonitorLowerValue.Value;
|
mainSettings.LowerTempLimit = (double)nUD_SettingsTempMonitorLowerValue.Value;
|
||||||
@@ -153,7 +234,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)
|
if (preadjustCtl != null)
|
||||||
{
|
{
|
||||||
@@ -174,7 +255,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 MeterBatch ThermoMeterBatch = new MeterBatch();
|
||||||
private List<MeterStateControl> TempMeterStateCtls = new List<MeterStateControl>();
|
private List<MeterStateControl> TempMeterStateCtls = new List<MeterStateControl>();
|
||||||
private void tmpStart(int slot, bool RaspiMode = false)
|
private void tmpStart(int slot, bool RaspiMode = false)
|
||||||
|
|||||||
+92
-6
@@ -1,4 +1,5 @@
|
|||||||
using CordonelPreadjustmentUi.Processes;
|
using CordonelPreadjustmentUi;
|
||||||
|
using CordonelPreadjustmentUi.Processes;
|
||||||
using CordonelPreadjustmentUi.Processes.Actions;
|
using CordonelPreadjustmentUi.Processes.Actions;
|
||||||
using CordonelPreadjustmentUi.Processes.Itinerary;
|
using CordonelPreadjustmentUi.Processes.Itinerary;
|
||||||
using System;
|
using System;
|
||||||
@@ -6,16 +7,18 @@ using System.Collections.Generic;
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
|
||||||
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
|
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
|
||||||
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||||
using Xylem.Common.Ui.CordonelPreadjustmentUi.Parameters;
|
using Xylem.Common.Ui.CordonelPreadjustmentUi.Parameters;
|
||||||
using CordonelPreadjustmentUi;
|
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
|
||||||
|
|
||||||
namespace GenesisCordonelInterface.UI
|
namespace GenesisCordonelInterface.UI
|
||||||
{
|
{
|
||||||
@@ -41,11 +44,18 @@ namespace GenesisCordonelInterface.UI
|
|||||||
private Boolean abortIndicator = false;
|
private Boolean abortIndicator = false;
|
||||||
public Boolean AbortIndicator { get { return abortIndicator; } set { abortIndicator = value; } }
|
public Boolean AbortIndicator { get { return abortIndicator; } set { abortIndicator = value; } }
|
||||||
public int TestRunNumber;
|
public int TestRunNumber;
|
||||||
public PreAdjustmentControl(PreAdjustmentSettingsContainer Settings = null)
|
public PreAdjustmentControl(PreAdjustmentSettingsContainer Settings = null, MeterBatch externalMetersBatch = null)//...MF
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
SetSettings(Settings);
|
SetSettings(Settings);
|
||||||
rTB_ZeroFlowCal.AutoSize = true;
|
rTB_ZeroFlowCal.AutoSize = true;
|
||||||
|
|
||||||
|
//...MF
|
||||||
|
// Use external batch only if supplied
|
||||||
|
if (externalMetersBatch != null)
|
||||||
|
{
|
||||||
|
GlobalMeterBatch = externalMetersBatch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public void SetSettings(PreAdjustmentSettingsContainer Settings = null)
|
public void SetSettings(PreAdjustmentSettingsContainer Settings = null)
|
||||||
{
|
{
|
||||||
@@ -120,6 +130,49 @@ namespace GenesisCordonelInterface.UI
|
|||||||
}
|
}
|
||||||
cb_Metersize.SelectedItem = setM;
|
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>();
|
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));
|
//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;
|
using log4net;
|
||||||
///
|
///
|
||||||
/// Copyright (c) 2015-2021 Sensus Slovensko a.s.
|
/// 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.Generic;
|
||||||
using TBF.Rig.Input.DataStorage.UniDataStorageReader;
|
using TBF.Rig.Input.DataStorage.UniDataStorageReader;
|
||||||
using TBF.Rig.Input.DataStorage.UniDataStorageReader.Searching.Database;
|
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 static TBF.Rig.BridgeComponents.GciBridge.Interfaces.PublicModels;
|
||||||
using GciGUIType = GenesisCordonelInterface.UI.MainView;
|
using GciGUIType = GenesisCordonelInterface.UI.MainView;
|
||||||
using GciPublicModels = GenesisCordonelInterface.API.PublicModels;
|
using GciPublicModels = GenesisCordonelInterface.API.PublicModels;
|
||||||
@@ -20,7 +26,6 @@ using GciType = GenesisCordonelInterface.API.InterfaceOutsideToGCI;
|
|||||||
using UdsReaderType = TBF.Rig.Input.DataStorage.UniDataStorageReader.Reader;
|
using UdsReaderType = TBF.Rig.Input.DataStorage.UniDataStorageReader.Reader;
|
||||||
using UDSRPublicModels = TBF.Rig.Input.DataStorage.UniDataStorageReader.Interfaces.PublicModels;
|
using UDSRPublicModels = TBF.Rig.Input.DataStorage.UniDataStorageReader.Interfaces.PublicModels;
|
||||||
using UdsWriterType = TBF.Rig.Output.DataStorage.UniDataStorageWriter.Writer;
|
using UdsWriterType = TBF.Rig.Output.DataStorage.UniDataStorageWriter.Writer;
|
||||||
using GenesisCordonelInterface.Core.Threading;
|
|
||||||
|
|
||||||
namespace TBF.Rig.BridgeComponents.GciBridge
|
namespace TBF.Rig.BridgeComponents.GciBridge
|
||||||
{
|
{
|
||||||
@@ -47,8 +52,8 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
|||||||
Form gciGuiHostForm;
|
Form gciGuiHostForm;
|
||||||
|
|
||||||
//diag GUI for GciBridge
|
//diag GUI for GciBridge
|
||||||
public UserControl gciBridgeGUI;
|
public UserControl gciBridgeGUIUserControl;
|
||||||
public MainForm gciBridgeGuiForm;
|
public UI.MainForm gciBridgeGuiForm;
|
||||||
|
|
||||||
public GciType gciExternalInterface;
|
public GciType gciExternalInterface;
|
||||||
|
|
||||||
@@ -119,7 +124,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
|||||||
if (gciBridgeGuiForm != null && !gciBridgeGuiForm.IsDisposed)
|
if (gciBridgeGuiForm != null && !gciBridgeGuiForm.IsDisposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gciBridgeGuiForm = new MainForm(this);
|
gciBridgeGuiForm = new UI.MainForm(this);
|
||||||
gciBridgeGuiForm.Text = "Gci Bridge GUI";
|
gciBridgeGuiForm.Text = "Gci Bridge GUI";
|
||||||
gciBridgeGuiForm.Width = 1300;
|
gciBridgeGuiForm.Width = 1300;
|
||||||
gciBridgeGuiForm.Height = 600;
|
gciBridgeGuiForm.Height = 600;
|
||||||
@@ -1453,6 +1458,334 @@ namespace TBF.Rig.BridgeComponents.GciBridge
|
|||||||
|
|
||||||
#endregion
|
#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 =======================================
|
#region ======================================= Helpers =======================================
|
||||||
private UDSRPublicModels.DataQuery CreatePasswordQuery(string pcbId)
|
private UDSRPublicModels.DataQuery CreatePasswordQuery(string pcbId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug
|
|||||||
private MainForm _mainform;
|
private MainForm _mainform;
|
||||||
private MainView _mainView;
|
private MainView _mainView;
|
||||||
public Grid.MeterGridManager _gridManager;
|
public Grid.MeterGridManager _gridManager;
|
||||||
|
public event Action GetMeterRegistersClicked;
|
||||||
|
|
||||||
private bool isRefreshing;
|
private bool isRefreshing;
|
||||||
private List<string> comPorts = new List<string>();
|
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
|
_mainView._gciApi.MeterBatchStatusChanged += Api_MeterBatchStatusChanged; //global event of table
|
||||||
|
|
||||||
|
grid.CellContentClick += grid_CellContentClick;
|
||||||
|
|
||||||
|
|
||||||
UpdateGrid(_api.GetMeterBatchDebugStatuses());
|
UpdateGrid(_api.GetMeterBatchDebugStatuses());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,8 +271,16 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug
|
|||||||
|
|
||||||
if (columnName == "Selected")
|
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);
|
_api.SetSlotSelected(slot, selected);
|
||||||
|
|
||||||
|
//SelectedSlotsChanged?.Invoke();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,13 +314,14 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.Debug
|
|||||||
|
|
||||||
if (columnName == "DetectRequest")
|
if (columnName == "DetectRequest")
|
||||||
{
|
{
|
||||||
await DetectRequestPortAsync(slot);
|
//await DetectRequestPortAsync(slot);
|
||||||
|
GetMeterRegistersClicked?.Invoke();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (columnName == "DetectStreaming")
|
if (columnName == "DetectStreaming")
|
||||||
{
|
{
|
||||||
await DetectStreamingPortAsync(slot);
|
//await DetectStreamingPortAsync(slot);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Common;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|||||||
+60
-36
@@ -25,7 +25,7 @@
|
|||||||
private System.Windows.Forms.Button btnRegisterStore;
|
private System.Windows.Forms.Button btnRegisterStore;
|
||||||
private System.Windows.Forms.Button btnPulseSetup;
|
private System.Windows.Forms.Button btnPulseSetup;
|
||||||
private System.Windows.Forms.Button preadjustmentButton;
|
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.SplitContainer splitWorkArea;
|
||||||
private System.Windows.Forms.Panel pnlGciViewHost;
|
private System.Windows.Forms.Panel pnlGciViewHost;
|
||||||
|
|
||||||
@@ -43,9 +43,11 @@
|
|||||||
this.btnRegisterStore = new System.Windows.Forms.Button();
|
this.btnRegisterStore = new System.Windows.Forms.Button();
|
||||||
this.tabPage2 = new System.Windows.Forms.TabPage();
|
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||||
this.groupBox5 = new System.Windows.Forms.GroupBox();
|
this.groupBox5 = new System.Windows.Forms.GroupBox();
|
||||||
this.btnMetersAction = new System.Windows.Forms.Button();
|
this.ScenariousViewButton = new System.Windows.Forms.Button();
|
||||||
this.storageActionButton = new System.Windows.Forms.Button();
|
this.preadjustmenActionsViewButton = new System.Windows.Forms.Button();
|
||||||
this.combinedActionButton = 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.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||||
this.btnDiagTablesConfigurationButton = new System.Windows.Forms.Button();
|
this.btnDiagTablesConfigurationButton = new System.Windows.Forms.Button();
|
||||||
this.pnlMain = new System.Windows.Forms.Panel();
|
this.pnlMain = new System.Windows.Forms.Panel();
|
||||||
@@ -104,7 +106,6 @@
|
|||||||
//
|
//
|
||||||
this.tabPage1.Controls.Add(this.groupBox2);
|
this.tabPage1.Controls.Add(this.groupBox2);
|
||||||
this.tabPage1.Controls.Add(this.groupBox1);
|
this.tabPage1.Controls.Add(this.groupBox1);
|
||||||
this.tabPage1.Enabled = false;
|
|
||||||
this.tabPage1.Location = new System.Drawing.Point(4, 22);
|
this.tabPage1.Location = new System.Drawing.Point(4, 22);
|
||||||
this.tabPage1.Name = "tabPage1";
|
this.tabPage1.Name = "tabPage1";
|
||||||
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
||||||
@@ -189,45 +190,66 @@
|
|||||||
//
|
//
|
||||||
// groupBox5
|
// groupBox5
|
||||||
//
|
//
|
||||||
this.groupBox5.Controls.Add(this.btnMetersAction);
|
this.groupBox5.Controls.Add(this.ScenariousViewButton);
|
||||||
this.groupBox5.Controls.Add(this.storageActionButton);
|
this.groupBox5.Controls.Add(this.preadjustmenActionsViewButton);
|
||||||
this.groupBox5.Controls.Add(this.combinedActionButton);
|
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.Location = new System.Drawing.Point(6, 85);
|
||||||
this.groupBox5.Name = "groupBox5";
|
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.TabIndex = 3;
|
||||||
this.groupBox5.TabStop = false;
|
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.ScenariousViewButton.Location = new System.Drawing.Point(6, 163);
|
||||||
this.btnMetersAction.Name = "btnMetersAction";
|
this.ScenariousViewButton.Name = "ScenariousViewButton";
|
||||||
this.btnMetersAction.Size = new System.Drawing.Size(150, 30);
|
this.ScenariousViewButton.Size = new System.Drawing.Size(150, 30);
|
||||||
this.btnMetersAction.TabIndex = 1;
|
this.ScenariousViewButton.TabIndex = 3;
|
||||||
this.btnMetersAction.Text = "GenesisCordonelInterface";
|
this.ScenariousViewButton.Text = "Scenarious";
|
||||||
this.btnMetersAction.UseVisualStyleBackColor = true;
|
this.ScenariousViewButton.UseVisualStyleBackColor = true;
|
||||||
this.btnMetersAction.Click += new System.EventHandler(this.btnMetersAction_Click);
|
|
||||||
//
|
//
|
||||||
// storageActionButton
|
// preadjustmenActionsViewButton
|
||||||
//
|
//
|
||||||
this.storageActionButton.Location = new System.Drawing.Point(6, 55);
|
this.preadjustmenActionsViewButton.Location = new System.Drawing.Point(6, 127);
|
||||||
this.storageActionButton.Name = "storageActionButton";
|
this.preadjustmenActionsViewButton.Name = "preadjustmenActionsViewButton";
|
||||||
this.storageActionButton.Size = new System.Drawing.Size(150, 30);
|
this.preadjustmenActionsViewButton.Size = new System.Drawing.Size(150, 30);
|
||||||
this.storageActionButton.TabIndex = 0;
|
this.preadjustmenActionsViewButton.TabIndex = 2;
|
||||||
this.storageActionButton.Text = "UniDataStorageReader";
|
this.preadjustmenActionsViewButton.Text = "Preadjustment";
|
||||||
this.storageActionButton.UseVisualStyleBackColor = true;
|
this.preadjustmenActionsViewButton.UseVisualStyleBackColor = true;
|
||||||
this.storageActionButton.Click += new System.EventHandler(this.button1_Click_1);
|
this.preadjustmenActionsViewButton.Click += new System.EventHandler(this.preadjustmenActionsViewButton_Click);
|
||||||
//
|
//
|
||||||
// combinedActionButton
|
// slotsComPortsRegistersActionsViewButton
|
||||||
//
|
//
|
||||||
this.combinedActionButton.Location = new System.Drawing.Point(6, 91);
|
this.slotsComPortsRegistersActionsViewButton.Location = new System.Drawing.Point(6, 19);
|
||||||
this.combinedActionButton.Name = "combinedActionButton";
|
this.slotsComPortsRegistersActionsViewButton.Name = "slotsComPortsRegistersActionsViewButton";
|
||||||
this.combinedActionButton.Size = new System.Drawing.Size(150, 30);
|
this.slotsComPortsRegistersActionsViewButton.Size = new System.Drawing.Size(150, 30);
|
||||||
this.combinedActionButton.TabIndex = 0;
|
this.slotsComPortsRegistersActionsViewButton.TabIndex = 1;
|
||||||
this.combinedActionButton.Text = "Combined Action";
|
this.slotsComPortsRegistersActionsViewButton.Text = "Slots, ComPorts, Registers";
|
||||||
this.combinedActionButton.UseVisualStyleBackColor = true;
|
this.slotsComPortsRegistersActionsViewButton.UseVisualStyleBackColor = true;
|
||||||
this.combinedActionButton.Click += new System.EventHandler(this.button2_Click);
|
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
|
// groupBox3
|
||||||
//
|
//
|
||||||
@@ -386,9 +408,11 @@
|
|||||||
this.ResumeLayout(false);
|
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.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 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.Interval = 250;
|
||||||
_uiLogFlushTimer.Tick += UiLogFlushTimer_Tick;
|
_uiLogFlushTimer.Tick += UiLogFlushTimer_Tick;
|
||||||
_uiLogFlushTimer.Start();
|
_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)
|
private void UiLogFlushTimer_Tick(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@@ -277,153 +230,6 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI
|
|||||||
base.Dispose(disposing);
|
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
|
#region GLOBAL LOGGING to memo in this view
|
||||||
|
|
||||||
@@ -545,11 +351,164 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI
|
|||||||
|
|
||||||
#endregion
|
#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)
|
private void btnMeterInit_Click_1(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
SwitchGciView(
|
SwitchGciView(
|
||||||
"ConfigurationView",
|
"ConfigurationView",
|
||||||
new ConfigurationView(this));
|
new ConfigurationView(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void preadjustmenActionsViewButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SwitchGciView(
|
||||||
|
"PreadjustmenActionsView",
|
||||||
|
new PreadjustmentActionsView(this, _bridge, AddSlotRow, SaveSlots));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||||
{
|
{
|
||||||
partial class CombinedInterfaceView
|
partial class CombinedActionsView
|
||||||
{
|
{
|
||||||
private System.ComponentModel.IContainer components = null;
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
+2
-2
@@ -10,7 +10,7 @@ using TBF.Rig.BridgeComponents.GciBridge.Interfaces;
|
|||||||
|
|
||||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||||
{
|
{
|
||||||
public partial class CombinedInterfaceView : UserControl
|
public partial class CombinedActionsView : UserControl
|
||||||
{
|
{
|
||||||
private readonly MainView _mainView;
|
private readonly MainView _mainView;
|
||||||
private readonly GciBridge _bridge;
|
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> _pcbBySlot = new Dictionary<int, string>();
|
||||||
private readonly Dictionary<int, string> _passwordBySlot = 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));
|
_mainView = mainView ?? throw new ArgumentNullException(nameof(mainView));
|
||||||
_bridge = bridge ?? throw new ArgumentNullException(nameof(bridge));
|
_bridge = bridge ?? throw new ArgumentNullException(nameof(bridge));
|
||||||
Generated
+250
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
+405
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
-7
@@ -1,6 +1,6 @@
|
|||||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||||
{
|
{
|
||||||
partial class GenesisCordonelInterfaceView
|
partial class SlotsComPortsRegistersActionsView
|
||||||
{
|
{
|
||||||
private System.ComponentModel.IContainer components = null;
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
@@ -42,6 +42,7 @@
|
|||||||
this.btnGetSlot = new System.Windows.Forms.Button();
|
this.btnGetSlot = new System.Windows.Forms.Button();
|
||||||
this.btnCleanAllSlots = new System.Windows.Forms.Button();
|
this.btnCleanAllSlots = new System.Windows.Forms.Button();
|
||||||
this.btnCleanSlot = 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.btnCancel = new System.Windows.Forms.Button();
|
||||||
this.txtLog = new System.Windows.Forms.TextBox();
|
this.txtLog = new System.Windows.Forms.TextBox();
|
||||||
this.grpSlots.SuspendLayout();
|
this.grpSlots.SuspendLayout();
|
||||||
@@ -49,6 +50,9 @@
|
|||||||
//
|
//
|
||||||
// grpSlots
|
// 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.writeRegisterNameComboBox);
|
||||||
this.grpSlots.Controls.Add(this.readRegisterNameComboBox);
|
this.grpSlots.Controls.Add(this.readRegisterNameComboBox);
|
||||||
this.grpSlots.Controls.Add(this.label4);
|
this.grpSlots.Controls.Add(this.label4);
|
||||||
@@ -66,9 +70,10 @@
|
|||||||
this.grpSlots.Controls.Add(this.btnGetSlot);
|
this.grpSlots.Controls.Add(this.btnGetSlot);
|
||||||
this.grpSlots.Controls.Add(this.btnCleanAllSlots);
|
this.grpSlots.Controls.Add(this.btnCleanAllSlots);
|
||||||
this.grpSlots.Controls.Add(this.btnCleanSlot);
|
this.grpSlots.Controls.Add(this.btnCleanSlot);
|
||||||
|
this.grpSlots.Controls.Add(this.writeRegisterValueTypeLabel);
|
||||||
this.grpSlots.Location = new System.Drawing.Point(10, 10);
|
this.grpSlots.Location = new System.Drawing.Point(10, 10);
|
||||||
this.grpSlots.Name = "grpSlots";
|
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.TabIndex = 2;
|
||||||
this.grpSlots.TabStop = false;
|
this.grpSlots.TabStop = false;
|
||||||
this.grpSlots.Text = "Slots by selection in the table";
|
this.grpSlots.Text = "Slots by selection in the table";
|
||||||
@@ -103,7 +108,7 @@
|
|||||||
//
|
//
|
||||||
this.writeRegisterValueTextBox.Location = new System.Drawing.Point(555, 264);
|
this.writeRegisterValueTextBox.Location = new System.Drawing.Point(555, 264);
|
||||||
this.writeRegisterValueTextBox.Name = "writeRegisterValueTextBox";
|
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;
|
this.writeRegisterValueTextBox.TabIndex = 12;
|
||||||
//
|
//
|
||||||
// label3
|
// label3
|
||||||
@@ -223,6 +228,15 @@
|
|||||||
this.btnCleanSlot.Text = "CleanSlot(slot)";
|
this.btnCleanSlot.Text = "CleanSlot(slot)";
|
||||||
this.btnCleanSlot.Click += new System.EventHandler(this.btnCleanSlot_Click);
|
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
|
// btnCancel
|
||||||
//
|
//
|
||||||
this.btnCancel.Enabled = false;
|
this.btnCancel.Enabled = false;
|
||||||
@@ -243,18 +257,18 @@
|
|||||||
this.txtLog.Name = "txtLog";
|
this.txtLog.Name = "txtLog";
|
||||||
this.txtLog.ReadOnly = true;
|
this.txtLog.ReadOnly = true;
|
||||||
this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
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.TabIndex = 5;
|
||||||
this.txtLog.WordWrap = false;
|
this.txtLog.WordWrap = false;
|
||||||
//
|
//
|
||||||
// GenesisCordonelInterfaceView
|
// SlotsComPortsRegistersActionsView
|
||||||
//
|
//
|
||||||
this.BackColor = System.Drawing.SystemColors.Control;
|
this.BackColor = System.Drawing.SystemColors.Control;
|
||||||
this.Controls.Add(this.grpSlots);
|
this.Controls.Add(this.grpSlots);
|
||||||
this.Controls.Add(this.btnCancel);
|
this.Controls.Add(this.btnCancel);
|
||||||
this.Controls.Add(this.txtLog);
|
this.Controls.Add(this.txtLog);
|
||||||
this.Name = "GenesisCordonelInterfaceView";
|
this.Name = "SlotsComPortsRegistersActionsView";
|
||||||
this.Size = new System.Drawing.Size(719, 603);
|
this.Size = new System.Drawing.Size(756, 603);
|
||||||
this.grpSlots.ResumeLayout(false);
|
this.grpSlots.ResumeLayout(false);
|
||||||
this.grpSlots.PerformLayout();
|
this.grpSlots.PerformLayout();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
@@ -275,5 +289,6 @@
|
|||||||
private System.Windows.Forms.ComboBox readRegisterNameComboBox;
|
private System.Windows.Forms.ComboBox readRegisterNameComboBox;
|
||||||
private System.Windows.Forms.Button btnLogin;
|
private System.Windows.Forms.Button btnLogin;
|
||||||
private System.Windows.Forms.Button btnCleanSlot;
|
private System.Windows.Forms.Button btnCleanSlot;
|
||||||
|
private System.Windows.Forms.Label writeRegisterValueTypeLabel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+165
-21
@@ -10,15 +10,17 @@ using GciPublicModels = GenesisCordonelInterface.API.PublicModels;
|
|||||||
|
|
||||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||||
{
|
{
|
||||||
public partial class GenesisCordonelInterfaceView : UserControl
|
public partial class SlotsComPortsRegistersActionsView : UserControl
|
||||||
{
|
{
|
||||||
private readonly GciBridge _bridge;
|
private readonly GciBridge _bridge;
|
||||||
private readonly MainView _mainView;
|
private readonly MainView _mainView;
|
||||||
private CancellationTokenSource _cts;
|
private CancellationTokenSource _cts;
|
||||||
private readonly Action _addSlotAction;
|
private readonly Action _addSlotAction;
|
||||||
private readonly Action _saveAction;
|
private readonly Action _saveAction;
|
||||||
|
private readonly Dictionary<string, Type> _registerTypes =
|
||||||
|
new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public GenesisCordonelInterfaceView(
|
public SlotsComPortsRegistersActionsView(
|
||||||
MainView mainview,
|
MainView mainview,
|
||||||
GciBridge bridge,
|
GciBridge bridge,
|
||||||
Action addSlotAction,
|
Action addSlotAction,
|
||||||
@@ -33,6 +35,13 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
LoadRegisterComboBoxes();
|
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()
|
private void AddSlot()
|
||||||
@@ -48,14 +57,14 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
|||||||
private List<GciPublicModels.MeterBatchDebugStatus> GetSelectedSlots()
|
private List<GciPublicModels.MeterBatchDebugStatus> GetSelectedSlots()
|
||||||
{
|
{
|
||||||
if (_mainView == null || _mainView._batchPanel == null)
|
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)
|
return _mainView._batchPanel.GetSelectedGridData()
|
||||||
throw new Exception("No selected slots in grid.");
|
?? new List<GciPublicModels.MeterBatchDebugStatus>();
|
||||||
|
|
||||||
return slots;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshGrid(int? removedSlot = null)
|
private void RefreshGrid(int? removedSlot = null)
|
||||||
@@ -414,16 +423,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
|||||||
if (string.IsNullOrWhiteSpace(valueText))
|
if (string.IsNullOrWhiteSpace(valueText))
|
||||||
throw new Exception("Write register value is empty.");
|
throw new Exception("Write register value is empty.");
|
||||||
|
|
||||||
object value;
|
object value = ConvertTextToRegisterValue(registerName, valueText);
|
||||||
|
|
||||||
if (registerName == "GENESISFLOW_LedMode")
|
|
||||||
{
|
|
||||||
value = byte.Parse(valueText);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value = valueText;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tasks = GetSelectedSlots()
|
var tasks = GetSelectedSlots()
|
||||||
.Select(async slot =>
|
.Select(async slot =>
|
||||||
@@ -530,18 +530,162 @@ namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
|||||||
|
|
||||||
private void LoadRegisterComboBoxes()
|
private void LoadRegisterComboBoxes()
|
||||||
{
|
{
|
||||||
var registers = _bridge.GetAllRegisterNames();
|
_registerTypes.Clear();
|
||||||
|
|
||||||
readRegisterNameComboBox.Items.Clear();
|
readRegisterNameComboBox.Items.Clear();
|
||||||
writeRegisterNameComboBox.Items.Clear();
|
writeRegisterNameComboBox.Items.Clear();
|
||||||
|
|
||||||
readRegisterNameComboBox.Items.AddRange(registers.ToArray());
|
var selectedSlots = GetSelectedSlots();
|
||||||
writeRegisterNameComboBox.Items.AddRange(registers.ToArray());
|
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+25
-24
@@ -1,12 +1,10 @@
|
|||||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||||
{
|
{
|
||||||
partial class UniDataStorageReaderInterfaceView
|
partial class UniDataSorageActionsView
|
||||||
{
|
{
|
||||||
private System.ComponentModel.IContainer components = null;
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
private System.Windows.Forms.GroupBox grpStorage;
|
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 btnGetPasswordByPcb;
|
||||||
|
|
||||||
private System.Windows.Forms.Button btnCancel;
|
private System.Windows.Forms.Button btnCancel;
|
||||||
@@ -23,11 +21,11 @@
|
|||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
this.grpStorage = new System.Windows.Forms.GroupBox();
|
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.btnGetPasswordByPcb = new System.Windows.Forms.Button();
|
||||||
this.btnCancel = new System.Windows.Forms.Button();
|
this.btnCancel = new System.Windows.Forms.Button();
|
||||||
this.txtLog = new System.Windows.Forms.TextBox();
|
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.grpStorage.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
@@ -38,27 +36,11 @@
|
|||||||
this.grpStorage.Controls.Add(this.btnGetPasswordByPcb);
|
this.grpStorage.Controls.Add(this.btnGetPasswordByPcb);
|
||||||
this.grpStorage.Location = new System.Drawing.Point(10, 37);
|
this.grpStorage.Location = new System.Drawing.Point(10, 37);
|
||||||
this.grpStorage.Name = "grpStorage";
|
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.TabIndex = 0;
|
||||||
this.grpStorage.TabStop = false;
|
this.grpStorage.TabStop = false;
|
||||||
this.grpStorage.Text = "UniDataStorageReader for GCI";
|
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
|
// btnGetPasswordByPcb
|
||||||
//
|
//
|
||||||
this.btnGetPasswordByPcb.Location = new System.Drawing.Point(10, 55);
|
this.btnGetPasswordByPcb.Location = new System.Drawing.Point(10, 55);
|
||||||
@@ -91,12 +73,28 @@
|
|||||||
this.txtLog.TabIndex = 4;
|
this.txtLog.TabIndex = 4;
|
||||||
this.txtLog.WordWrap = false;
|
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.grpStorage);
|
||||||
this.Controls.Add(this.btnCancel);
|
this.Controls.Add(this.btnCancel);
|
||||||
this.Controls.Add(this.txtLog);
|
this.Controls.Add(this.txtLog);
|
||||||
this.Name = "UniDataStorageReaderInterfaceView";
|
this.Name = "UniDataSorageActionsView";
|
||||||
this.Size = new System.Drawing.Size(740, 370);
|
this.Size = new System.Drawing.Size(740, 370);
|
||||||
this.grpStorage.ResumeLayout(false);
|
this.grpStorage.ResumeLayout(false);
|
||||||
this.grpStorage.PerformLayout();
|
this.grpStorage.PerformLayout();
|
||||||
@@ -104,5 +102,8 @@
|
|||||||
this.PerformLayout();
|
this.PerformLayout();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private System.Windows.Forms.Label lblPcbId;
|
||||||
|
private System.Windows.Forms.TextBox txtPcbId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -5,13 +5,13 @@ using System.Windows.Forms;
|
|||||||
|
|
||||||
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
|
||||||
{
|
{
|
||||||
public partial class UniDataStorageReaderInterfaceView : UserControl
|
public partial class UniDataSorageActionsView : UserControl
|
||||||
{
|
{
|
||||||
private readonly MainView _mainView;
|
private readonly MainView _mainView;
|
||||||
private readonly GciBridge _bridge;
|
private readonly GciBridge _bridge;
|
||||||
private CancellationTokenSource _cts;
|
private CancellationTokenSource _cts;
|
||||||
|
|
||||||
public UniDataStorageReaderInterfaceView(MainView mainView, GciBridge bridge)
|
public UniDataSorageActionsView(MainView mainView, GciBridge bridge)
|
||||||
{
|
{
|
||||||
_mainView = mainView ?? throw new ArgumentNullException(nameof(mainView));
|
_mainView = mainView ?? throw new ArgumentNullException(nameof(mainView));
|
||||||
_bridge = bridge ?? throw new ArgumentNullException(nameof(bridge));
|
_bridge = bridge ?? throw new ArgumentNullException(nameof(bridge));
|
||||||
+120
@@ -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>
|
||||||
Reference in New Issue
Block a user