Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c79688dc0c | ||
|
|
74bcbaf12d | ||
|
|
a3821d722b | ||
|
|
9339683a0e | ||
|
|
7170da4a70 | ||
|
|
842f009b42 | ||
|
|
7f30ca0cd1 | ||
|
|
93e207c211 | ||
|
|
64cafc088a | ||
|
|
8a0da27a07 | ||
|
|
5a8478e782 | ||
|
|
368cd95114 | ||
|
|
3376ac41b4 | ||
|
|
f9181fee74 | ||
|
|
ff5954d85b | ||
|
|
c09e266b2c |
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("3.9.3056.1")]
|
||||
[assembly: AssemblyFileVersion("3.9.3056.1")]
|
||||
[assembly: AssemblyVersion("3.9.3058.1")]
|
||||
[assembly: AssemblyFileVersion("3.9.3058.1")]
|
||||
|
||||
@@ -175,8 +175,8 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
double reqFlowLo = (0.7 * qFrom) + (0.3 * reqFlowAve); /// Move the lower limit 15% of the range up
|
||||
double reqFlowHi = (0.7 * qTo) + (0.3 * reqFlowAve); /// Move the upper limit 15% of the range down
|
||||
///
|
||||
uniCB.SetFlow(false, regV.Idx1, 2000.0 * reqFlowLo / flowMeter.NominalFlow,
|
||||
2000.0 * reqFlowHi / flowMeter.NominalFlow);
|
||||
uniCB.SetFlow(false, regV.Idx1, flowMeter.NominalFreq * reqFlowLo / flowMeter.NominalFlow,
|
||||
flowMeter.NominalFreq * reqFlowHi / flowMeter.NominalFlow);
|
||||
if (readDivTransition)
|
||||
{
|
||||
/// Schedule reading diverter transition data
|
||||
|
||||
@@ -803,12 +803,60 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
/// </summary>
|
||||
public void SetFlow(bool isFromUI, int regVId, double freqLo, double freqHi, int regulationMinStep = 0)
|
||||
{
|
||||
if (IsUIBlocked && isFromUI) return;
|
||||
LiveLogDiag.Log1("----------------------------------------");
|
||||
LiveLogDiag.Log1(
|
||||
"SetFlow() >> ENTER isFromUI={0} regVId={1} freqLo={2} freqHi={3} regulationMinStep={4} IsUIBlocked={5}",
|
||||
isFromUI, regVId, freqLo, freqHi, regulationMinStep, IsUIBlocked);
|
||||
|
||||
actionQueue.Enqueue(Action.SetFlow(isFromUI, regVId, freqLo, freqHi, Convert.ToInt32(Math.Round(Devices.PidCoef)), 200, regulationMinStep));
|
||||
log.InfoFormat("Enqueue( SetFlow(rv={0}, fLo={1}, fHi={2}, pid={3}) )", regVId, freqLo, freqHi, Convert.ToInt32(Math.Round(Devices.PidCoef)));
|
||||
if (IsUIBlocked && isFromUI)
|
||||
{
|
||||
LiveLogDiag.Log1(
|
||||
"SetFlow() >> EXIT (UI BLOCKED) isFromUI={0}",
|
||||
isFromUI);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
|
||||
int pid = Convert.ToInt32(Math.Round(Devices.PidCoef));
|
||||
int fixedParam = 200;
|
||||
|
||||
LiveLogDiag.Log1(
|
||||
"SetFlow() >> PREPARE pid={0} fixedParam={1} regulationMinStep={2}",
|
||||
pid, fixedParam, regulationMinStep);
|
||||
|
||||
var action = Action.SetFlow(
|
||||
isFromUI,
|
||||
regVId,
|
||||
freqLo,
|
||||
freqHi,
|
||||
pid,
|
||||
fixedParam,
|
||||
regulationMinStep);
|
||||
|
||||
LiveLogDiag.Log1(
|
||||
"SetFlow() >> ACTION CREATED: rv={0} fLo={1} fHi={2} pid={3} p6={4} minStep={5}",
|
||||
regVId, freqLo, freqHi, pid, fixedParam, regulationMinStep);
|
||||
|
||||
actionQueue.Enqueue(action);
|
||||
|
||||
LiveLogDiag.Log1(
|
||||
"SetFlow() >> ENQUEUED actionQueue.Count={0}",
|
||||
actionQueue.Count);
|
||||
|
||||
log.InfoFormat(
|
||||
"Enqueue( SetFlow(rv={0}, fLo={1}, fHi={2}, pid={3}) )",
|
||||
regVId, freqLo, freqHi, pid);
|
||||
|
||||
int i = 0;
|
||||
foreach (var a in actionQueue)
|
||||
{
|
||||
LiveLogDiag.Log1(
|
||||
"SetFlow() >> QUEUE[{0}] = {1}",
|
||||
i++, a);
|
||||
log.DebugFormat(" {0}", a);
|
||||
}
|
||||
|
||||
LiveLogDiag.Log1("SetFlow() >> EXIT");
|
||||
LiveLogDiag.Log1("----------------------------------------");
|
||||
}
|
||||
|
||||
public void StartTest(bool isFromUI, int flowMId, int divId, int divThreshold,
|
||||
@@ -981,5 +1029,18 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
{
|
||||
/// TODO
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logging
|
||||
/// For activation use compilation condition: LIVELOGDIAG_FlowMeter_cs
|
||||
/// </summary>
|
||||
static class LiveLogDiag
|
||||
{
|
||||
[Conditional("LIVELOGDIAG_UniCB_cs")]
|
||||
public static void Log1(string format, params object[] args)
|
||||
{
|
||||
LiveLogCache.Instance.AddLog("UniCB.cs LOG>> " + string.Format(format, args));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,8 +633,31 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
public double TimestampSecEndCh1 => NoSamples ? 0 : GetCachedTime(_recalculatedStartEndByChannel, 0, 1);
|
||||
public double TimestampSecEndCh2 => NoSamples ? 0 : GetCachedTime(_recalculatedStartEndByChannel, 1, 1);
|
||||
public double TimestampSecEndCh3 => NoSamples ? 0 : GetCachedTime(_recalculatedStartEndByChannel, 2, 1);
|
||||
public double VolumeLtrStartRaw => NoSamples ? 0 : AverageCachedVolume(_rawStartEndByChannel, 0);
|
||||
public double VolumeLtrEndRaw => NoSamples ? 0 : AverageCachedVolume(_rawStartEndByChannel, 1);
|
||||
|
||||
|
||||
public double VolumeLtrStartAverage => NoSamples ? 0 : AverageCachedVolume(_recalculatedStartEndByChannel, 0);
|
||||
public double VolumeLtrEndAwerage => NoSamples ? 0 : AverageCachedVolume(_recalculatedStartEndByChannel, 1);
|
||||
|
||||
public double VolumeLtrStartRawRaw => NoSamples ? 0 : AverageCachedVolume(_rawStartEndByChannel, 0);
|
||||
public double VolumeLtrEndRawRaw => NoSamples ? 0 : AverageCachedVolume(_rawStartEndByChannel, 1);
|
||||
|
||||
|
||||
|
||||
public double VolumeLtrStartRawCh1 => NoSamples ? 0 : GetCachedVolume(_rawStartEndByChannel, 0, 0);
|
||||
public double VolumeLtrStartRawCh2 => NoSamples ? 0 : GetCachedVolume(_rawStartEndByChannel, 1, 0);
|
||||
public double VolumeLtrStartRawCh3 => NoSamples ? 0 : GetCachedVolume(_rawStartEndByChannel, 2, 0);
|
||||
|
||||
public double VolumeLtrEndRawCh1 => NoSamples ? 0 : GetCachedVolume(_rawStartEndByChannel, 0, 1);
|
||||
public double VolumeLtrEndRawCh2 => NoSamples ? 0 : GetCachedVolume(_rawStartEndByChannel, 1, 1);
|
||||
public double VolumeLtrEndRawCh3 => NoSamples ? 0 : GetCachedVolume(_rawStartEndByChannel, 2, 1);
|
||||
|
||||
public double TimestampSecStartRawCh1 => NoSamples ? 0 : GetCachedTime(_rawStartEndByChannel, 0, 0);
|
||||
public double TimestampSecStartRawCh2 => NoSamples ? 0 : GetCachedTime(_rawStartEndByChannel, 1, 0);
|
||||
public double TimestampSecStartRawCh3 => NoSamples ? 0 : GetCachedTime(_rawStartEndByChannel, 2, 0);
|
||||
|
||||
public double TimestampSecEndRawCh1 => NoSamples ? 0 : GetCachedTime(_rawStartEndByChannel, 0, 1);
|
||||
public double TimestampSecEndRawCh2 => NoSamples ? 0 : GetCachedTime(_rawStartEndByChannel, 1, 1);
|
||||
public double TimestampSecEndRawCh3 => NoSamples ? 0 : GetCachedTime(_rawStartEndByChannel, 2, 1);
|
||||
|
||||
|
||||
|
||||
@@ -643,7 +666,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
{
|
||||
get
|
||||
{
|
||||
return VolumeLtrStartRaw;
|
||||
return VolumeLtrStartAverage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -652,7 +675,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
{
|
||||
get
|
||||
{
|
||||
return VolumeLtrEndRaw;
|
||||
return VolumeLtrEndAwerage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1302,7 +1325,8 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
try
|
||||
{
|
||||
log.DebugFormat("DataStreamPostProcessing() - harcoded call GetQ3Calibration(200.0, 120.0, 15625.0);");
|
||||
GetQ3Calibration(200.0, 120.0, 15625.0);
|
||||
SetQ3Calibration(new double[]{15625.0,15625.0,15625.0 });
|
||||
CalculateQ3Calibration(200.0, 120.0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -3885,20 +3909,61 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
private bool isQ3CalibValid = false;
|
||||
private double q3Calib = 0;
|
||||
private double[] q3CalibInitial = {Double.NaN,Double.NaN,Double.NaN};
|
||||
private bool[] isChQ3CalibValid = { false,false,false};
|
||||
private double[] q3CalibCh = {Double.NaN,Double.NaN,Double.NaN};
|
||||
|
||||
public bool Q3CalibValid { get => isQ3CalibValid; }
|
||||
public double Q3CalibValue { get => q3Calib; }
|
||||
|
||||
public bool Q3CalibValid
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var b in isChQ3CalibValid)
|
||||
{
|
||||
if (!b)
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GetQ3Calibration(double refVolume, double refTime, double initCalibFactor)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public double[] Q3CalibValue { get => q3CalibInitial; }
|
||||
|
||||
public bool Q3Calib_Ch1Valid { get => isChQ3CalibValid[0]; }
|
||||
public bool Q3Calib_Ch2Valid { get => isChQ3CalibValid[1]; }
|
||||
public bool Q3Calib_Ch3Valid { get => isChQ3CalibValid[2]; }
|
||||
public double Q3Calib_Ch1Value { get => q3CalibCh[0]; }
|
||||
public double Q3Calib_Ch2Value { get => q3CalibCh[1]; }
|
||||
public double Q3Calib_Ch3Value { get => q3CalibCh[2]; }
|
||||
|
||||
void SetQ3Calibration(double[] q3CalibInitial) { this.q3CalibInitial = q3CalibInitial; }
|
||||
|
||||
public void CalculateQ3Calibration(double refVolume, double refTime)
|
||||
{
|
||||
GetQ3Calibration(refVolume, refTime, q3CalibInitial, ref isChQ3CalibValid, ref q3CalibCh);
|
||||
}
|
||||
|
||||
public void GetQ3Calibration(double refVolume, double refTime, double[] initCalibFactor, ref bool[] isChQ3CalibValid, ref double[] q3CalibCh)
|
||||
{
|
||||
log.Debug("=== Q3 CALIBRATION START ===");
|
||||
|
||||
isQ3CalibValid = false;
|
||||
q3Calib = 0.0;
|
||||
//initialisation
|
||||
for (int iChannel = 0; iChannel < ChannelCount; iChannel++)
|
||||
{
|
||||
q3CalibCh[iChannel] = 0.0;
|
||||
isChQ3CalibValid[iChannel] = false;
|
||||
}
|
||||
|
||||
foreach (var init in initCalibFactor)
|
||||
{
|
||||
if (Double.IsNaN(init))
|
||||
{
|
||||
log.Error("Q3 Calibration: Initial calibration value is NaN");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug($"Inputs: refVolume={refVolume}, refTime={refTime}, initCalibFactor={initCalibFactor}");
|
||||
|
||||
@@ -3914,7 +3979,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
return;
|
||||
}
|
||||
|
||||
if (refVolume <= 0 || refTime <= 0 || initCalibFactor <= 0)
|
||||
if (refVolume <= 0 || refTime <= 0)
|
||||
{
|
||||
log.Debug("EXIT: Invalid input values (<= 0)");
|
||||
return;
|
||||
@@ -3931,6 +3996,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
|
||||
for (int iChannel = 0; iChannel < ChannelCount; iChannel++)
|
||||
{
|
||||
|
||||
var channelData = _rawStartEndByChannel[iChannel];
|
||||
|
||||
if (channelData == null || channelData.Length < 2)
|
||||
@@ -3938,7 +4004,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
log.Debug($"Channel {iChannel}: SKIPPED (no data)");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
var start = channelData[0];
|
||||
var end = channelData[1];
|
||||
|
||||
@@ -3962,10 +4028,11 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
log.Debug($" End: T={end.TimestampExt}, V={end.VolumeRawExt}");
|
||||
log.Debug($" Delta: dT={deltaTime}, dV={deltaVolume}");
|
||||
|
||||
double recalculatedDeltaVolume = 0.0f;
|
||||
if (deltaTime > 0)
|
||||
{
|
||||
double timeCoef = refTime / deltaTime;
|
||||
double recalculatedDeltaVolume = deltaVolume * timeCoef;
|
||||
double timeCoef = refTime / deltaTime; //?
|
||||
recalculatedDeltaVolume = deltaVolume * timeCoef;
|
||||
|
||||
recalculatedVariablesByChannel[iChannel][1].VolumeRawExt =
|
||||
recalculatedVariablesByChannel[iChannel][0].VolumeRawExt + recalculatedDeltaVolume;
|
||||
@@ -3979,52 +4046,18 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
|
||||
recalculatedVariablesByChannel[iChannel][0].TimestampExt = 0;
|
||||
recalculatedVariablesByChannel[iChannel][1].TimestampExt = refTime;
|
||||
}
|
||||
|
||||
double scaling = 15625.0;
|
||||
log.Debug($"Scaling={scaling}");
|
||||
|
||||
if (scaling <= 0)
|
||||
{
|
||||
log.Debug("EXIT: scaling <= 0");
|
||||
return;
|
||||
}
|
||||
|
||||
double avgRawVolume = AverageCachedVolume(recalculatedVariablesByChannel, 0);
|
||||
log.Debug($"AverageCachedVolume={avgRawVolume}");
|
||||
|
||||
if (avgRawVolume <= 0)
|
||||
{
|
||||
log.Debug("EXIT: avgRawVolume <= 0");
|
||||
return;
|
||||
}
|
||||
|
||||
double measuredVolume = avgRawVolume / scaling;
|
||||
log.Debug($"MeasuredVolume={measuredVolume}");
|
||||
|
||||
if (measuredVolume <= 0)
|
||||
{
|
||||
log.Debug("EXIT: measuredVolume <= 0");
|
||||
return;
|
||||
}
|
||||
|
||||
q3Calib = (refVolume / measuredVolume) * initCalibFactor;
|
||||
|
||||
log.Debug($"Q3Calib (raw)={q3Calib}");
|
||||
|
||||
double diffPercent =
|
||||
Math.Abs((q3Calib - initCalibFactor) / initCalibFactor) * 100.0;
|
||||
|
||||
log.Debug($"DiffPercent={diffPercent}%");
|
||||
|
||||
isQ3CalibValid = diffPercent <= 5.0;
|
||||
|
||||
log.Debug($"Validation: {(isQ3CalibValid ? "VALID" : "INVALID")}");
|
||||
|
||||
if (!isQ3CalibValid)
|
||||
{
|
||||
q3Calib = 0.0;
|
||||
log.Debug("Q3Calib reset to 0 due to invalid result");
|
||||
|
||||
if (Math.Abs(recalculatedDeltaVolume) <= Double.Epsilon)
|
||||
{
|
||||
log.Debug($"Channel {iChannel}: recalculatedDeltaVolume is zero");
|
||||
continue;
|
||||
}
|
||||
|
||||
q3CalibCh[iChannel] = (refVolume / recalculatedDeltaVolume) * initCalibFactor[iChannel];
|
||||
double diffPercent = Math.Abs((initCalibFactor[iChannel] - q3CalibCh[iChannel] ) / initCalibFactor[iChannel]) * 100.0;
|
||||
isChQ3CalibValid[iChannel] = diffPercent <= 5.0;
|
||||
log.Debug($"Calculated Q3Calib Ch[{iChannel}] ={q3CalibCh[iChannel]} DiffPercent={diffPercent}% isValid[{isChQ3CalibValid[iChannel]}] IninitCalibFactor={initCalibFactor}");
|
||||
|
||||
}
|
||||
|
||||
log.Debug("=== Q3 CALIBRATION END ===");
|
||||
|
||||
@@ -13,46 +13,29 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
public class CliRunner
|
||||
{
|
||||
//static readonly ILog log = LogManager.GetLogger(typeof(CliRunner));
|
||||
private readonly ILog log;
|
||||
private List<Task> taskPool = new List<Task>();
|
||||
private long startTime;
|
||||
private long incommingTime;
|
||||
|
||||
public List<Task> TaskPool { get { return taskPool; } }
|
||||
public void AddTask(Task task) { taskPool.Add(task); }
|
||||
public void WaitAll() { Task.WaitAll(taskPool.ToArray()); }
|
||||
public void Clear() { taskPool.Clear(); }
|
||||
public void CancelAll() { Task.WhenAll(taskPool).ContinueWith(t => { }); }
|
||||
private readonly List<CliTaskInfo> taskPool = new List<CliTaskInfo>();
|
||||
private long startTimeMs;
|
||||
private long incommingTimeMs;
|
||||
|
||||
public void StartAll()
|
||||
public List<CliTaskInfo> TaskPool
|
||||
{
|
||||
taskPool.ForEach(t => t.Start());
|
||||
}
|
||||
|
||||
public bool AreTasksDone()
|
||||
{
|
||||
return taskPool.All(task => task.IsCompleted);
|
||||
get { return taskPool; }
|
||||
}
|
||||
|
||||
public long StartTime
|
||||
{
|
||||
get => startTime;
|
||||
get { return startTimeMs; }
|
||||
}
|
||||
|
||||
public long IncommingTime
|
||||
{
|
||||
get => incommingTime;
|
||||
get { return incommingTimeMs; }
|
||||
}
|
||||
|
||||
public bool TimeOutReceived(long timeout)
|
||||
{
|
||||
return (DateTime.Now.Ticks - startTime) > timeout;
|
||||
}
|
||||
|
||||
public CliRunner(bool isCliLogging)
|
||||
{
|
||||
startTime = DateTime.Now.Ticks;
|
||||
ResetStartTime();
|
||||
|
||||
if (isCliLogging)
|
||||
{
|
||||
@@ -60,88 +43,180 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
log = new ScopedLoggerFactory().CreateLogger<CliRunner>(
|
||||
@"C:\TBF\Logs\CliRunner.txt",
|
||||
10, // maxFileSizeMB
|
||||
7, // maxBackups
|
||||
10,
|
||||
7,
|
||||
log4net.Core.Level.Debug,
|
||||
true, // zipRolledFiles
|
||||
true, // singleZipPerDay
|
||||
TimeSpan.FromMinutes(2) // zipScanInterval
|
||||
true,
|
||||
true,
|
||||
TimeSpan.FromMinutes(2)
|
||||
);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Fallback to console or handle gracefully
|
||||
Console.WriteLine($"Failed to initialize logger: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public void AddSendAsync(SerialPortData data, SerialPortData.EMeterArg eMeterArg)
|
||||
public void ResetStartTime()
|
||||
{
|
||||
var task = SendAsync(data.SerialPortCmdClientPath, data.DefaultArgSettings(eMeterArg));
|
||||
taskPool.Add(task);
|
||||
startTimeMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
}
|
||||
|
||||
public void AddSendAsync(string fileName, string args)
|
||||
{
|
||||
var task = SendAsync(fileName, args);
|
||||
taskPool.Add(task);
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> SendAsync(string fileName, string args, CancellationToken ct = default)
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = args,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
using var process = new Process { StartInfo = psi, EnableRaisingEvents = true };
|
||||
process.Start();
|
||||
|
||||
Task<string> stdOutTask = process.StandardOutput.ReadToEndAsync();
|
||||
Task<string> stdErrTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
try
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var item in taskPool)
|
||||
{
|
||||
await Task.WhenAll(stdOutTask, stdErrTask, process.WaitForExitAsync(ct));
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
if (!process.HasExited)
|
||||
try
|
||||
{
|
||||
item?.Cts?.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
process.Kill();
|
||||
}
|
||||
|
||||
throw;
|
||||
try
|
||||
{
|
||||
if (item?.Process != null)
|
||||
{
|
||||
item.Process.Dispose();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//comming answer from serial port - good place for time stamp
|
||||
incommingTime = DateTime.Now.Ticks;
|
||||
string allOutput = (stdOutTask.Result ?? "") + (stdErrTask.Result ?? "");
|
||||
log?.Debug(allOutput);
|
||||
return allOutput;
|
||||
taskPool.Clear();
|
||||
}
|
||||
|
||||
|
||||
public void AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg) where T : new()
|
||||
public void WaitAll()
|
||||
{
|
||||
var task = RunAndCaptureJsonAsync<T>(data.SerialPortCmdClientPath, data.DefaultArgSettings(eMeterArg));
|
||||
taskPool.Add(task);
|
||||
var tasks = taskPool
|
||||
.Where(t => t != null && t.Task != null)
|
||||
.Select(t => t.Task)
|
||||
.ToArray();
|
||||
|
||||
if (tasks.Length == 0)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Task.WaitAll(tasks);
|
||||
}
|
||||
catch (AggregateException)
|
||||
{
|
||||
RefreshTaskStates();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args, CancellationToken ct = default) where T : new()
|
||||
|
||||
public bool AreTasksDone()
|
||||
{
|
||||
RefreshTaskStates();
|
||||
return taskPool.Count > 0 && taskPool.All(t => t.State != CliTaskState.Running);
|
||||
}
|
||||
|
||||
public bool TimeOutReceived(long timeoutMs)
|
||||
{
|
||||
long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
return (nowMs - startTimeMs) > timeoutMs;
|
||||
}
|
||||
|
||||
public void RefreshTaskStates()
|
||||
{
|
||||
foreach (var item in taskPool)
|
||||
{
|
||||
if (item == null || item.Task == null)
|
||||
continue;
|
||||
|
||||
if (item.State == CliTaskState.TimedOut)
|
||||
continue;
|
||||
|
||||
if (!item.Task.IsCompleted)
|
||||
{
|
||||
item.State = CliTaskState.Running;
|
||||
}
|
||||
else if (item.Task.IsCanceled)
|
||||
{
|
||||
item.State = CliTaskState.Canceled;
|
||||
}
|
||||
else if (item.Task.IsFaulted)
|
||||
{
|
||||
item.State = CliTaskState.Faulted;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.State = CliTaskState.Completed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelUndoneTasksAsTimedOut()
|
||||
{
|
||||
foreach (var item in taskPool)
|
||||
{
|
||||
if (item == null || item.Task == null)
|
||||
continue;
|
||||
|
||||
if (item.Task.IsCompleted)
|
||||
{
|
||||
if (item.Task.IsCanceled)
|
||||
item.State = CliTaskState.Canceled;
|
||||
else if (item.Task.IsFaulted)
|
||||
item.State = CliTaskState.Faulted;
|
||||
else
|
||||
item.State = CliTaskState.Completed;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
item.State = CliTaskState.TimedOut;
|
||||
|
||||
try
|
||||
{
|
||||
item.Cts?.Cancel();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log?.Warn("Cancel token failed", ex);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (item.Process != null && !item.Process.HasExited)
|
||||
{
|
||||
item.Process.Kill();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log?.Warn("Kill process failed", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddSendAsync(SerialPortData data, SerialPortData.EMeterArg eMeterArg)
|
||||
{
|
||||
AddSendAsync(data.SerialPortCmdClientPath, data.DefaultArgSettings(eMeterArg));
|
||||
}
|
||||
|
||||
public void AddSendAsync(string fileName, string args)
|
||||
{
|
||||
ResetStartTime();
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
var info = new CliTaskInfo
|
||||
{
|
||||
Cts = cts,
|
||||
Name = "SendAsync"
|
||||
};
|
||||
|
||||
var task = SendAsync(fileName, args, info, cts.Token);
|
||||
info.Task = task;
|
||||
taskPool.Add(info);
|
||||
}
|
||||
|
||||
public async Task<string> SendAsync(string fileName, string args, CliTaskInfo info, CancellationToken ct = default)
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
@@ -153,80 +228,210 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
using var process = new Process { StartInfo = psi, EnableRaisingEvents = true };
|
||||
process.Start();
|
||||
using (var process = new Process { StartInfo = psi, EnableRaisingEvents = true })
|
||||
{
|
||||
info.Process = process;
|
||||
|
||||
var stdoutTask = process.StandardOutput.ReadToEndAsync();
|
||||
var stderrTask = process.StandardError.ReadToEndAsync();
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
|
||||
await Task.WhenAll(stdoutTask, stderrTask, process.WaitForExitAsync(ct));
|
||||
Task<string> stdOutTask = process.StandardOutput.ReadToEndAsync();
|
||||
Task<string> stdErrTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
string allOutput = (stdoutTask.Result ?? "") + (stderrTask.Result ?? "");
|
||||
log?.Debug(allOutput);
|
||||
try
|
||||
{
|
||||
await Task.WhenAll(stdOutTask, stdErrTask, process.WaitForExitAsync(ct));
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
if (info.State != CliTaskState.TimedOut)
|
||||
info.State = CliTaskState.Canceled;
|
||||
|
||||
string json = ExtractJson(allOutput);
|
||||
if (TryJsonStringDeserialize(json, out T result)) return result;
|
||||
return default;
|
||||
if (!process.HasExited)
|
||||
{
|
||||
process.Kill();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
incommingTimeMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
|
||||
string allOutput = (stdOutTask.Result ?? "") + (stdErrTask.Result ?? "");
|
||||
log?.Debug(allOutput);
|
||||
|
||||
info.State = CliTaskState.Completed;
|
||||
return allOutput;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.State = CliTaskState.Faulted;
|
||||
log?.Error("SendAsync failed", ex);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
info.Process = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryJsonStringDeserialize<T>(string json, out T runAndCaptureJsonAsync) where T : new()
|
||||
public void AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg) where T : new()
|
||||
{
|
||||
AddRunAndCaptureJsonAsync<T>(
|
||||
data.SerialPortCmdClientPath,
|
||||
data.DefaultArgSettings(eMeterArg));
|
||||
}
|
||||
|
||||
public void AddRunAndCaptureJsonAsync<T>(string fileName, string args) where T : new()
|
||||
{
|
||||
ResetStartTime();
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
var info = new CliTaskInfo
|
||||
{
|
||||
Cts = cts,
|
||||
Name = $"RunAndCaptureJsonAsync<{typeof(T).Name}>"
|
||||
};
|
||||
|
||||
var task = RunAndCaptureJsonAsync<T>(fileName, args, info, cts.Token);
|
||||
|
||||
info.Task = task;
|
||||
taskPool.Add(info);
|
||||
}
|
||||
|
||||
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args, CliTaskInfo info, CancellationToken ct = default) where T : new()
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = args,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
using (var process = new Process { StartInfo = psi, EnableRaisingEvents = true })
|
||||
{
|
||||
info.Process = process;
|
||||
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
|
||||
var stdoutTask = process.StandardOutput.ReadToEndAsync();
|
||||
var stderrTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
try
|
||||
{
|
||||
await Task.WhenAll(stdoutTask, stderrTask, process.WaitForExitAsync(ct));
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
if (info.State != CliTaskState.TimedOut)
|
||||
info.State = CliTaskState.Canceled;
|
||||
|
||||
if (!process.HasExited)
|
||||
{
|
||||
process.Kill();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
incommingTimeMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
|
||||
string allOutput = (stdoutTask.Result ?? "") + (stderrTask.Result ?? "");
|
||||
log?.Debug(allOutput);
|
||||
|
||||
string json = ExtractJson(allOutput);
|
||||
T result;
|
||||
if (TryJsonStringDeserialize(json, out result))
|
||||
{
|
||||
info.State = CliTaskState.Completed;
|
||||
return result;
|
||||
}
|
||||
|
||||
info.State = CliTaskState.Completed;
|
||||
return default(T);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.State = CliTaskState.Faulted;
|
||||
log?.Error("RunAndCaptureJsonAsync failed", ex);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
info.Process = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryJsonStringDeserialize<T>(string json, out T value) where T : new()
|
||||
{
|
||||
if (json != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
runAndCaptureJsonAsync = JsonConvert.DeserializeObject<T>(json);
|
||||
value = JsonConvert.DeserializeObject<T>(json);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Debug(ex.Message);
|
||||
runAndCaptureJsonAsync = TryConvert<T>(json);
|
||||
log?.Debug(ex.Message);
|
||||
value = TryConvert<T>(json);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
runAndCaptureJsonAsync = default;
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static T TryConvert<T>(string json) where T : new()
|
||||
{
|
||||
|
||||
T obj = new T();
|
||||
T obj = new T();
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
JObject jObject = JObject.Parse(json);
|
||||
|
||||
foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
JObject jObject = JObject.Parse(json);
|
||||
if (!prop.CanWrite)
|
||||
continue;
|
||||
|
||||
foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
JToken token;
|
||||
if (jObject.TryGetValue(prop.Name, StringComparison.OrdinalIgnoreCase, out token))
|
||||
{
|
||||
if (!prop.CanWrite) continue;
|
||||
|
||||
JToken token;
|
||||
if (jObject.TryGetValue(prop.Name, StringComparison.OrdinalIgnoreCase, out token))
|
||||
try
|
||||
{
|
||||
object value = token.ToObject(prop.PropertyType);
|
||||
prop.SetValue(obj, value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
object value = token.ToObject(prop.PropertyType);
|
||||
prop.SetValue(obj, value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// leave default if conversion fails
|
||||
}
|
||||
}
|
||||
// else → keep default value
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"TryConvert failed: {ex.Message}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"TryConvert failed: {ex.Message}");
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public string ExtractJson(string text)
|
||||
@@ -241,6 +446,20 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
internal void AddTaskForTest(Task task, string name = "TestTask", CancellationTokenSource cts = null)
|
||||
{
|
||||
taskPool.Add(new CliTaskInfo
|
||||
{
|
||||
Task = task,
|
||||
Cts = cts,
|
||||
Name = name,
|
||||
State = task.IsCompleted
|
||||
? (task.IsCanceled ? CliTaskState.Canceled :
|
||||
task.IsFaulted ? CliTaskState.Faulted :
|
||||
CliTaskState.Completed)
|
||||
: CliTaskState.Running
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
public class CliTaskInfo
|
||||
{
|
||||
public Task Task { get; set; }
|
||||
public CancellationTokenSource Cts { get; set; }
|
||||
public Process Process { get; set; }
|
||||
public CliTaskState State { get; set; } = CliTaskState.Running;
|
||||
public string Name { get; set; }
|
||||
|
||||
public bool UseResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return State == CliTaskState.Completed
|
||||
&& Task != null
|
||||
&& Task.Status == TaskStatus.RanToCompletion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
public enum CliTaskState
|
||||
{
|
||||
Running,
|
||||
Completed,
|
||||
TimedOut,
|
||||
Canceled,
|
||||
Faulted
|
||||
}
|
||||
|
||||
}
|
||||
@@ -336,10 +336,12 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
/// for debug purposes what time will consume answer
|
||||
/// </summary>
|
||||
private long startTimeInMilis = -1, fullTimeInMilis = -1;
|
||||
/// 30 seconds
|
||||
private static long SafetyTimeOut = 30 * 1000;
|
||||
private long incommingTime = -1;
|
||||
private bool _lastOpTimedOut;
|
||||
|
||||
|
||||
/// 30 seconds
|
||||
|
||||
public long DeltaTime { get{return fullTimeInMilis;}}
|
||||
public long IncommingTime { get{return incommingTime;}}
|
||||
@@ -356,108 +358,146 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|
||||
if (_currentOp == CurrentPoseidonOp.SendStartDataStream)
|
||||
{
|
||||
CliRunner.Clear();
|
||||
_lastOpTimedOut = false;
|
||||
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
return Event.Busy;
|
||||
_currentOp = CurrentPoseidonOp.SendStartDataStream_Runing;
|
||||
return Event.Busy;
|
||||
}
|
||||
else if (_currentOp == CurrentPoseidonOp.SendStartDataStream_Runing)
|
||||
{
|
||||
if (CliRunner.AreTasksDone()
|
||||
|| CliRunner.TimeOutReceived(SafetyTimeOut))
|
||||
if (CliRunner.AreTasksDone())
|
||||
{
|
||||
_currentOp = CurrentPoseidonOp.SendStartDataStream_Done;
|
||||
}
|
||||
return Event.Busy;
|
||||
else if (CliRunner.TimeOutReceived(SafetyTimeOut))
|
||||
{
|
||||
_lastOpTimedOut = true;
|
||||
CliRunner.CancelUndoneTasksAsTimedOut();
|
||||
_currentOp = CurrentPoseidonOp.SendStartDataStream_Done;
|
||||
}
|
||||
|
||||
return Event.Busy;
|
||||
}
|
||||
else if (_currentOp == CurrentPoseidonOp.SendStartDataStream_Done)
|
||||
{
|
||||
var firstTask = CliRunner.TaskPool.FindLast(t => t is Task<string>);
|
||||
var firstTaskInfo = CliRunner.TaskPool
|
||||
.FindLast(t => t.Task is Task<string> && t.UseResult);
|
||||
|
||||
|
||||
if (firstTask != null && firstTask is Task<string>)
|
||||
if (firstTaskInfo != null)
|
||||
{
|
||||
string data = null;
|
||||
data = (firstTask as Task<string>).Result;
|
||||
var task = (Task<string>)firstTaskInfo.Task;
|
||||
string data = task.Result;
|
||||
|
||||
if (data != null && TryGetDeviceId(data, out wmSerialNr))
|
||||
if (!string.IsNullOrEmpty(data))
|
||||
{
|
||||
|
||||
TryGetDeviceId(data, out wmSerialNr);
|
||||
}
|
||||
}
|
||||
else if (_lastOpTimedOut)
|
||||
{
|
||||
log.Warn(
|
||||
$"PoseidonReader {Name}: SendStartDataStream timed out, no completed result will be used.");
|
||||
}
|
||||
|
||||
_currentOp = CurrentPoseidonOp.Done;
|
||||
CliRunner.Clear();
|
||||
_currentOp = _lastOpTimedOut ? CurrentPoseidonOp.Error : CurrentPoseidonOp.Done;
|
||||
return Event.Done;
|
||||
}
|
||||
else if (_currentOp == CurrentPoseidonOp.ReadDataStream_Start
|
||||
else if (_currentOp == CurrentPoseidonOp.ReadDataStream_Start
|
||||
|| _currentOp == CurrentPoseidonOp.ReadDataStream_End)
|
||||
{
|
||||
startTimeInMilis = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
startTimeInMilis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
incommingTime = -1;
|
||||
_isReadingStart = (_currentOp == CurrentPoseidonOp.ReadDataStream_Start);
|
||||
CliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
|
||||
CliRunner.Clear();
|
||||
_lastOpTimedOut = false;
|
||||
CliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort,
|
||||
SerialPortData.EMeterArg.AllParams);
|
||||
_currentOp = CurrentPoseidonOp.ReadDatastream_Running;
|
||||
return Event.Busy;
|
||||
}else if (_currentOp == CurrentPoseidonOp.ReadDatastream_Running)
|
||||
}
|
||||
else if (_currentOp == CurrentPoseidonOp.ReadDatastream_Running)
|
||||
{
|
||||
if (CliRunner.AreTasksDone()
|
||||
|| CliRunner.TimeOutReceived(SafetyTimeOut))
|
||||
if (CliRunner.AreTasksDone())
|
||||
{
|
||||
_currentOp = CurrentPoseidonOp.ReadDatastream_Done;
|
||||
//set time stamp - end of reading
|
||||
incommingTime = CliRunner.IncommingTime;
|
||||
}
|
||||
else if (CliRunner.TimeOutReceived(SafetyTimeOut))
|
||||
{
|
||||
_lastOpTimedOut = true;
|
||||
CliRunner.CancelUndoneTasksAsTimedOut();
|
||||
_currentOp = CurrentPoseidonOp.ReadDatastream_Done;
|
||||
incommingTime = CliRunner.IncommingTime;
|
||||
}
|
||||
|
||||
return Event.Busy;
|
||||
}
|
||||
else if (_currentOp == CurrentPoseidonOp.ReadDatastream_Done)
|
||||
{
|
||||
fullTimeInMilis = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - startTimeInMilis;
|
||||
log.Debug($"PoseidonReader.Run() Name= {Cfg.Name} fullTimeInMilis = {fullTimeInMilis} ");
|
||||
JsonDataFromPoseidon data = null;
|
||||
var first = CliRunner.TaskPool.FindLast(t => t is Task<JsonDataFromPoseidon>);
|
||||
if (first != null && first is Task<JsonDataFromPoseidon>)
|
||||
{
|
||||
data = (first as Task<JsonDataFromPoseidon>).Result;
|
||||
fullTimeInMilis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - startTimeInMilis;
|
||||
log.Debug($"PoseidonReader.Run() Name= {Cfg.Name} fullTimeInMilis = {fullTimeInMilis}");
|
||||
|
||||
//GET serial number
|
||||
JsonDataFromPoseidon data = null;
|
||||
|
||||
var firstTaskInfo = CliRunner.TaskPool
|
||||
.FindLast(t => t.Task is Task<JsonDataFromPoseidon> && t.UseResult);
|
||||
|
||||
if (firstTaskInfo != null)
|
||||
{
|
||||
var task = (Task<JsonDataFromPoseidon>)firstTaskInfo.Task;
|
||||
data = task.Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_lastOpTimedOut)
|
||||
{
|
||||
log.Warn($"PoseidonReader {Name}: ReadDatastream timed out, no completed result available.");
|
||||
}
|
||||
else
|
||||
{
|
||||
log.Warn("No completed JsonDataFromPoseidon task available.");
|
||||
}
|
||||
}
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(wmSerialNr))
|
||||
{
|
||||
try
|
||||
{
|
||||
wmSerialNr = data?.DeviceId ?? wmSerialNr;
|
||||
wmSerialNr = data.DeviceId ?? wmSerialNr;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error("Serial Nr - parse error!");
|
||||
log.Error("Serial Nr - parse error!", e);
|
||||
}
|
||||
}
|
||||
|
||||
//GET volume
|
||||
if (data != null && Double.TryParse(data.Reading, out double Volume))
|
||||
double volume;
|
||||
if (Double.TryParse(data.Reading, out volume))
|
||||
{
|
||||
double VolumeLi = Units.ConvertFrom(Unit.USgal, Volume);
|
||||
//double VolumeM3 = Units.ConvertTo(Unit.m3, VolumeLi);
|
||||
if (_isReadingStart)
|
||||
{
|
||||
//volume
|
||||
beginWMState = VolumeLi;
|
||||
}
|
||||
else
|
||||
{
|
||||
//volume
|
||||
endWMState = VolumeLi;
|
||||
}
|
||||
}
|
||||
double volumeLi = Units.ConvertFrom(Unit.USgal, volume);
|
||||
|
||||
if (_isReadingStart)
|
||||
beginWMState = volumeLi;
|
||||
else
|
||||
endWMState = volumeLi;
|
||||
}
|
||||
}
|
||||
|
||||
//Finish reading and loop
|
||||
_currentOp = CurrentPoseidonOp.Done;
|
||||
|
||||
CliRunner.Clear();
|
||||
_currentOp = _lastOpTimedOut ? CurrentPoseidonOp.Error : CurrentPoseidonOp.Done;
|
||||
return Event.Done;
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ using log4net;
|
||||
using log4net.Repository.Hierarchy;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.TestMethods.GenesisFullCommunication;
|
||||
|
||||
namespace TBF.Rig
|
||||
{
|
||||
@@ -192,7 +193,8 @@ namespace TBF.Rig
|
||||
new TestMethods.FlyingStartFirstRepetWithMassColl.HeatMeters.Factory(),
|
||||
new TestMethods.FlyingStartTankCollection.Single.Factory(),
|
||||
new TestMethods.FlyingStartTankCollection.Compound.Factory(),
|
||||
new TestMethods.GenesisCommunication.GenesisHead.Factory(),
|
||||
new TestMethods.GenesisCommunication.GenesisHead.Factory(), // german implementation of the Genesis communication protocol
|
||||
new Factory(),
|
||||
new TestMethods.GrabImage.Factory(),
|
||||
new TestMethods.iPerlCommunication.TestMethodFactory(), /// iPerlCommunication
|
||||
new TestMethods.LeakTest.Factory(),
|
||||
|
||||
@@ -1396,18 +1396,18 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
|
||||
chanelXMeterRslt?.CopyContentFrom(meterRslt);
|
||||
if (iCH == 0)
|
||||
{
|
||||
CalculateMeterResults(chanelXMeterRslt, genesisSmart, tstRslt, genesisSmart.TimestampSecStartCh1,
|
||||
genesisSmart.TimestampSecEndCh1, genesisSmart.VolumeLtrStartCh1, genesisSmart.VolumeLtrEndCh1);
|
||||
CalculateMeterResults(chanelXMeterRslt, genesisSmart, tstRslt, genesisSmart.TimestampSecStartRawCh1,
|
||||
genesisSmart.TimestampSecEndRawCh1, genesisSmart.VolumeLtrStartRawCh1, genesisSmart.VolumeLtrEndRawCh1);
|
||||
}
|
||||
else if (iCH == 1)
|
||||
{
|
||||
CalculateMeterResults(chanelXMeterRslt, genesisSmart, tstRslt, genesisSmart.TimestampSecStartCh2,
|
||||
genesisSmart.TimestampSecEndCh2, genesisSmart.VolumeLtrStartCh2, genesisSmart.VolumeLtrEndCh2);
|
||||
CalculateMeterResults(chanelXMeterRslt, genesisSmart, tstRslt, genesisSmart.TimestampSecStartRawCh2,
|
||||
genesisSmart.TimestampSecEndRawCh2, genesisSmart.VolumeLtrStartRawCh2, genesisSmart.VolumeLtrEndRawCh2);
|
||||
}
|
||||
else if (iCH == 2)
|
||||
{
|
||||
CalculateMeterResults(chanelXMeterRslt, genesisSmart, tstRslt, genesisSmart.TimestampSecStartCh3,
|
||||
genesisSmart.TimestampSecEndCh3, genesisSmart.VolumeLtrStartCh3, genesisSmart.VolumeLtrEndCh3);
|
||||
CalculateMeterResults(chanelXMeterRslt, genesisSmart, tstRslt, genesisSmart.TimestampSecStartRawCh3,
|
||||
genesisSmart.TimestampSecEndRawCh3, genesisSmart.VolumeLtrStartRawCh3, genesisSmart.VolumeLtrEndRawCh3);
|
||||
}
|
||||
|
||||
if (!genesisSmart.EnableShowChanels)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2016 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.TestMethods.GenesisCommunication;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisFullCommunication
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return GetType().Namespace.Substring(8); } }
|
||||
|
||||
public IComponent DummyComponent() { return new TestMethod(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new TestMethod(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new TestMethodCfg(this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(TestMethodCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2022 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.TestMethods.iPerlCommunication;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisFullCommunication
|
||||
{
|
||||
public class GenesisCommunicationParams : TestParamsBase, IParamsProvider, ITestParams
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(GenesisCommunicationParams) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public string Activity
|
||||
{
|
||||
get { return base.Activity; }
|
||||
set { base.Activity = value; }
|
||||
}
|
||||
|
||||
/// Communication activity
|
||||
public bool SimultWithPrevious;
|
||||
public bool SimultWithNext;
|
||||
|
||||
public override void InitializeAll()
|
||||
{
|
||||
Activity = iPerlCommunicationForm.ReadConfigurationStr;
|
||||
SimultWithPrevious = false;
|
||||
SimultWithNext = false;
|
||||
}
|
||||
|
||||
|
||||
string[] paramNames = new string[]
|
||||
{
|
||||
Strings.Activity,
|
||||
Strings.Simultaneous_with_previous_step,
|
||||
Strings.Simultaneous_with_next_step,
|
||||
};
|
||||
public override string ParamName(int i) { return paramNames[i]; }
|
||||
public override int ParamsCount() { return paramNames.Length; }
|
||||
|
||||
public override ICollection<string> ParamValues(int i)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
var retVal = new List<string>();
|
||||
retVal.Add(iPerlCommunicationForm.ReadConfigurationStr);
|
||||
retVal.Add(iPerlCommunicationForm.ReadSerialNrStr);
|
||||
retVal.Add(string.Format("{0} A0", iPerlCommunicationForm.SetTestModeStr));
|
||||
retVal.Add(string.Format("{0} A4", iPerlCommunicationForm.SetTestModeStr));
|
||||
retVal.Add(iPerlCommunicationForm.ReadCalibrationStr);
|
||||
retVal.Add(iPerlCommunicationForm.ReadCalibrationV4Str);
|
||||
retVal.Add(iPerlCommunicationForm.NormalizeCalibrationFactorStr);
|
||||
retVal.Add(iPerlCommunicationForm.NormalizeCalibrationV4FactorsStr);
|
||||
retVal.Add(iPerlCommunicationForm.GetDefaultQ2CorrectionsStr);
|
||||
retVal.Add(iPerlCommunicationForm.ReadQ2CorrectionStr);
|
||||
retVal.Add(iPerlCommunicationForm.ResetQ2CorrectionStr);
|
||||
retVal.Add(iPerlCommunicationForm.WriteDefaultQ2CorrectionsStr);
|
||||
retVal.Add(iPerlCommunicationForm.InitOrReadQ2CorrectionsStr);
|
||||
retVal.Add(iPerlCommunicationForm.WriteCalibrationFactorStr);
|
||||
retVal.Add(iPerlCommunicationForm.WriteCalibrationV4FactorsStr);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionStr);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionAltStr);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionGreeceStr);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionRLStr);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionLRStr);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionIncl05Str);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionAltIncl05Str);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionPlusIncl05Str);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionPlusAltIncl05Str);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionGreeceIncl05Str);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionRLIncl05Str);
|
||||
retVal.Add(iPerlCommunicationForm.WriteQ2CorrectionLRIncl05Str);
|
||||
retVal.Add(iPerlCommunicationSeq.Q2correctedFromCmd + "Qx");
|
||||
retVal.Add(iPerlCommunicationSeq.StrictQ2ErrorCheckStr + "Qx");
|
||||
retVal.Add(iPerlCommunicationSeq.Q2correctionCheckCmd);
|
||||
retVal.Add(iPerlCommunicationSeq.IperlCheckCmd);
|
||||
retVal.Add(iPerlCommunicationForm.UpdateBothQ2FactorsTestRLOnlyStr);
|
||||
retVal.Add(iPerlCommunicationForm.UpdateBothQ2FactorsTestLROnlyStr);
|
||||
retVal.Add(iPerlCommunicationForm.UpdateQ2CorrectionsStr);
|
||||
retVal.Add(iPerlCommunicationForm.ConditnlUpdateQ2CorrectionsStr);
|
||||
retVal.Add(iPerlCommunicationForm.ConditnlUpdateQ2CorrRLStr);
|
||||
retVal.Add(iPerlCommunicationForm.ConditnlUpdateQ2CorrLRStr);
|
||||
retVal.Add("Q2 corrected from Q2adj");
|
||||
retVal.Add("Q2 correction check Q2bc Q2ac");
|
||||
retVal.Add(iPerlCommunicationForm.SetActiveModeStr);
|
||||
retVal.Add(iPerlCommunicationForm.SetIdleModeStr);
|
||||
retVal.Add("---");
|
||||
retVal.Add(iPerlCommunicationForm.Reset2HzCorrectionStr);
|
||||
retVal.Add(iPerlCommunicationForm.Write2HzCorrectionStr);
|
||||
retVal.Add(iPerlCommunicationForm.DewaReworkRLStr);
|
||||
retVal.Add(iPerlCommunicationForm.DewaReworkLRStr);
|
||||
retVal.Add(iPerlCommunicationForm.StartTestingSealedMetersStr);
|
||||
retVal.Add(iPerlCommunicationForm.EndTestingSealedMetersStr);
|
||||
retVal.Add(string.Format("{0} if enabled", iPerlCommunicationForm.ReadConfigurationStr));
|
||||
retVal.Add(string.Format("{0} 80", iPerlCommunicationForm.SetTestModeStr));
|
||||
retVal.Add("iPerl_check prevWorkStep direction q2factors");
|
||||
for (iPerlCommunication.ConditionID id = iPerlCommunication.ConditionID.A; id < iPerlCommunication.ConditionID.Count; id++)
|
||||
{
|
||||
retVal.Add(string.Format(iPerlCommunication.SequenceConditionOp.ConditionNameFmt, id));
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new string[] { Strings.yes, Strings.no };
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: return Activity;
|
||||
case 1: return (SimultWithPrevious ? Strings.yes : Strings.no);
|
||||
case 2: return (SimultWithNext ? Strings.yes : Strings.no);
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateParam(int i, string strValue)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: Activity = strValue; return CfgUpdateFlags.None;
|
||||
case 1: SimultWithPrevious = strValue.ToLower().Equals(Strings.yes.ToLower()); return CfgUpdateFlags.None;
|
||||
case 2: SimultWithNext = strValue.ToLower().Equals(Strings.yes.ToLower()); return CfgUpdateFlags.None;
|
||||
default: return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidateParam(int i, string strValue, out string message)
|
||||
{
|
||||
message = string.Empty;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return true;
|
||||
case 1:
|
||||
case 2:
|
||||
if (strValue.Equals(Strings.yes) || strValue.Equals(Strings.no)) return true;
|
||||
break;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
}
|
||||
|
||||
message = ParamName(i) + " is invalid";
|
||||
return false;
|
||||
}
|
||||
|
||||
void CopyContentTo(GenesisCommunicationParams prms)
|
||||
{
|
||||
prms.Activity = this.Activity;
|
||||
prms.SimultWithPrevious = this.SimultWithPrevious;
|
||||
prms.SimultWithNext = this.SimultWithNext;
|
||||
}
|
||||
|
||||
public IParamsProvider Clone()
|
||||
{
|
||||
GenesisCommunicationParams pars = new GenesisCommunicationParams();
|
||||
CopyContentTo(pars);
|
||||
return pars;
|
||||
}
|
||||
|
||||
public override void UpdateFromDbEntity(ComponentTest dbEntity)
|
||||
{
|
||||
if (dbEntity == null) return;
|
||||
try
|
||||
{
|
||||
GenesisCommunicationParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as GenesisCommunicationParams;
|
||||
|
||||
testParamsEntity = dbEntity;
|
||||
componentName = dbEntity.CmpntName;
|
||||
test = dbEntity.Test;
|
||||
|
||||
if (tmp != null) tmp.CopyContentTo(this);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameterless constructor initializes the parameters
|
||||
/// </summary>
|
||||
public GenesisCommunicationParams()
|
||||
{
|
||||
}
|
||||
|
||||
public GenesisCommunicationParams(bool initialize)
|
||||
{
|
||||
if (initialize) InitializeAll();
|
||||
}
|
||||
|
||||
public GenesisCommunicationParams(ComponentTest testParamsEntity, string componentName, Test test)
|
||||
{
|
||||
this.testParamsEntity = testParamsEntity;
|
||||
this.componentName = componentName;
|
||||
this.test = test;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,962 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
using RestClient;
|
||||
using Results.Entities;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.TestMethods.iPerlCommunication;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
using TBF.UiBridge;
|
||||
|
||||
/// Point definition
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisFullCommunication
|
||||
{
|
||||
public class GenesisCommunicationSeq : SequenceBase
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(GenesisCommunicationSeq));
|
||||
|
||||
public const string Q2correctedFromCmd = "Q2 corrected from ";
|
||||
public const string StrictQ2ErrorCheckStr = "Strict Q2 error check ";
|
||||
public const string Q2correctionCheckCmd = "Q2 correction check ";
|
||||
public const string IperlCheckCmd = "iPERL_check ";
|
||||
public const string SimulateCmd = "simulate ";
|
||||
|
||||
|
||||
System.Windows.Forms.Form modelessDlg;
|
||||
///
|
||||
delegate void IPerlCommFormDlgt(GenesisCommunicationSeq myRef, TestMethod method, Test test, GenesisCommunicationParams testParams);
|
||||
///
|
||||
void OpenIPerlCommForm(GenesisCommunicationSeq myRef, TestMethod method, Test test, GenesisCommunicationParams testParams)
|
||||
{
|
||||
|
||||
//TODO solve this wia SmartCommunicationForm
|
||||
|
||||
myRef.modelessDlg = new SmartCommunicationForm(method, test, testParams);
|
||||
myRef.modelessDlg.Show();
|
||||
//myRef.modelessDlg = new iPerlCommunicationForm(method, test, testParams);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CloseIPerlCommForm()
|
||||
{
|
||||
UiBridge.Bridge.OnCloseModelessForm(this, null);
|
||||
modelessDlg = null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Flying start mass collection method sequence
|
||||
/// </summary>
|
||||
/// <param name="test">Test entity</param>
|
||||
/// <returns>
|
||||
/// Event.Done . . . . . . . OK
|
||||
/// Event.UiCmdStop . . . . Stopped by the user using the on-screen button STOP
|
||||
/// Event.OpArgumentError . Target flow is out of range
|
||||
/// Event.Error . . . . . . Unspecified error
|
||||
/// </returns>
|
||||
public IList<Event> Execute(Test test, int repetitionNr, TestMethod method, ITestParams testParams)
|
||||
{
|
||||
TestMethodCfg cfg = method.Cfg as TestMethodCfg;
|
||||
|
||||
IList<Event> e; /// Events from currently running operations
|
||||
checkUiOp = new Operations.CheckUIOp(true); /// Runs in more then one state
|
||||
modelessDlg = null;
|
||||
|
||||
processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, false);
|
||||
|
||||
string cmd;
|
||||
if (testParams.Activity.ToLower().Equals(cmd = iPerlCommunicationForm.GetDefaultQ2CorrectionsStr.ToLower()))
|
||||
{
|
||||
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
|
||||
|
||||
/// Get 'wmType' from IperlHead procedure parameters
|
||||
int wmType = 0;
|
||||
#if IPERL
|
||||
/*foreach (var wm in ProcessData.BatchRslts.Batch.WaterMeters)
|
||||
{
|
||||
if (wm != null && !wm.Disabled && wm.WMTypeId() > 0)
|
||||
{
|
||||
wmType = wm.WMTypeId();
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
|
||||
if (cfg.UseWebService)
|
||||
{
|
||||
IsQ2PreCorrectionCalculated = GetQ2PreCorrectionsOrBackups(cfg, wmType, out CalculatedQ2PreCorrectionLR, out CalculatedQ2PreCorrectionRL);
|
||||
}
|
||||
|
||||
/// Generate test results
|
||||
Results.Entities.TestRslt tstRslt = BatchRslts.GetTestRslt(test.Name, 0);
|
||||
if (tstRslt != null)
|
||||
{
|
||||
tstRslt.StartTime = DateTime.Now;
|
||||
tstRslt.TestDone = true;
|
||||
foreach (var wm in BatchRslts.Batch.WaterMeters)
|
||||
{
|
||||
if (!wm.Disabled)
|
||||
{
|
||||
foreach(var mtr in wm.MeterTestRslts)
|
||||
{
|
||||
if (mtr.TestRslt == tstRslt)
|
||||
{
|
||||
mtr.Passed = !cfg.UseWebService || IsQ2PreCorrectionCalculated;
|
||||
mtr.TestDone = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
|
||||
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0)));
|
||||
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
|
||||
|
||||
return new List<Event> { Event.Done };
|
||||
}
|
||||
else if (testParams.Activity.ToLower().Contains(cmd = Q2correctedFromCmd.ToLower()))
|
||||
{
|
||||
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
|
||||
|
||||
string[] args = testParams.Activity.Substring(cmd.Length).Split(new char[] { ' ' });
|
||||
string fromTestName = (args.Length >= 1) ? args[0] : string.Empty;
|
||||
bool isPlus = (args.Length >= 2) ? args[1].ToLower().Contains("plus") : false;
|
||||
MakeQ2CorrectedFrom(test.Name, fromTestName, isPlus);
|
||||
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
|
||||
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0)));
|
||||
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
|
||||
|
||||
return new List<Event> { Event.Done };
|
||||
}
|
||||
else if (testParams.Activity.ToLower().Contains(cmd = StrictQ2ErrorCheckStr.ToLower()))
|
||||
{
|
||||
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
|
||||
|
||||
string fromTestName = testParams.Activity.Substring(cmd.Length);
|
||||
|
||||
StrictQ2ErrorCheck(test.Name, fromTestName);
|
||||
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
|
||||
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0)));
|
||||
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
|
||||
|
||||
return new List<Event> { Event.Done };
|
||||
}
|
||||
else if (testParams.Activity.ToLower().Contains(cmd = Q2correctionCheckCmd.ToLower()))
|
||||
{
|
||||
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
|
||||
|
||||
string[] testNames = testParams.Activity.Substring(cmd.Length).Split(new char[] { ' ' });
|
||||
|
||||
if (testNames.Length >= 2)
|
||||
{
|
||||
CheckQ2Correction(test.Name, testNames[0], testNames[1]);
|
||||
}
|
||||
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
|
||||
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0)));
|
||||
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
|
||||
|
||||
return new List<Event> { Event.Done };
|
||||
}
|
||||
else if (testParams.Activity.ToLower().Contains(cmd = IperlCheckCmd.ToLower()))
|
||||
{
|
||||
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
|
||||
|
||||
string[] args = testParams.Activity.Substring(cmd.Length).Split(new char[] { ' ' });
|
||||
|
||||
//int maxTestIndex = (ProcessData.BenchInfo is TBF.Rig.DataContainer.BenchInfo.Component)
|
||||
// ? (ProcessData.BenchInfo as TBF.Rig.DataContainer.BenchInfo.Component).MaxTestIndex
|
||||
// : int.MaxValue;
|
||||
|
||||
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(test.Name, 0);
|
||||
|
||||
if (tstRslt != null)
|
||||
{
|
||||
tstRslt.StartTime = DateTime.Now;
|
||||
|
||||
int wrongMetersCount = 0;
|
||||
string message = string.Empty;
|
||||
|
||||
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
|
||||
{
|
||||
Results.Entities.WaterMeter wm = BatchRslts.Batch.WaterMeters[i];
|
||||
Results.Entities.MeterTestRslt mtr = ProcessData.BatchRslts.GetMeterTestRslt(test.Name, i, CompoundMeterId.Single);
|
||||
|
||||
///// Reference to iPerl water meter or null:
|
||||
//TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerlHead = ((sensPath.RegisterReaders != null) && (i < sensPath.RegisterReaders.Length))
|
||||
// ? (sensPath.RegisterReaders[i] as TestMethods.iPerlCommunication.iPerlHead.IperlHead)
|
||||
// : null;
|
||||
|
||||
if ((wm != null) && (mtr != null))
|
||||
{
|
||||
int errorIndicators = 0;
|
||||
bool anyErrorOfThisMeter = false;
|
||||
foreach (var arg in args)
|
||||
{
|
||||
#if TURA_SPECIAL
|
||||
if (arg.ToLower() == "q2factors")
|
||||
{
|
||||
if ((wm.ProdQ2CorrRL != wm.Q2CorrRL) || (wm.ProdQ2CorrLR != wm.Q2CorrLR))
|
||||
{
|
||||
anyErrorOfThisMeter = true;
|
||||
message += string.Format("Q2 korekčné faktory vodomera {0} nesedia{1}", wm.WMPosition, Environment.NewLine);
|
||||
errorIndicators |= (int)ErrorFlagMask.E26; /// Q2 correction factors not valid
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (arg.ToLower() == "direction")
|
||||
{
|
||||
//if (wm.Pruefindex > maxTestIndex)
|
||||
//{
|
||||
// anyErrorOfThisMeter = true;
|
||||
// message += string.Format("Príliš veľa opakovaní testu vodomera {0}{1}", wm.WMPosition, Environment.NewLine);
|
||||
// errorIndicators |= (int)ErrorFlagMask.E27; /// Wrong direction (positive/negative counting)
|
||||
//}
|
||||
}
|
||||
|
||||
if (arg.ToLower() == "prevworkstep")
|
||||
{
|
||||
if (wm.LastRecordIsNok)
|
||||
{
|
||||
wm.ErrorFlags |= (int)ErrorFlagMask.E28; /// Set E28
|
||||
}
|
||||
|
||||
if ((wm.ErrorFlags & (int)ErrorFlagMask.E28) != 0)
|
||||
{
|
||||
anyErrorOfThisMeter = true;
|
||||
message += string.Format("iPerl{0} : Predchádzajúci krok nebol zaznamenaný{1}", wm.WMPosition, Environment.NewLine);
|
||||
errorIndicators |= (int)ErrorFlagMask.E28; /// Previous workstep missing or NOK (production tracing)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mtr.TestDone = true;
|
||||
mtr.ErrorIndicators = errorIndicators;
|
||||
///
|
||||
if (anyErrorOfThisMeter)
|
||||
{
|
||||
/// This iPerl check did not pass
|
||||
mtr.Passed = false;
|
||||
wrongMetersCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Check passed OK
|
||||
mtr.Passed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tstRslt.EndTime = DateTime.Now;
|
||||
tstRslt.TestDone = true;
|
||||
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
|
||||
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, tstRslt));
|
||||
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
|
||||
|
||||
if (wrongMetersCount >= cfg.IperlCheckErrorsToStop)
|
||||
{
|
||||
State.Create("iPerlCommunicationSeq : Show check result")
|
||||
.AddOperation(new Operations.LargeMessageBoxOp(message))
|
||||
.EnterState();
|
||||
do
|
||||
{
|
||||
e = StateMachine.WaitRunDevsRunOps();
|
||||
}
|
||||
while (!e.Contains(Event.Continue) && !e.Contains(Event.Abort));
|
||||
|
||||
if (e.Contains(Event.Abort))
|
||||
{
|
||||
Bridge.OnError(this, string.Format("Niečo nie je v poriadku !"));
|
||||
return new List<Event> { Event.UiCmdStop };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new List<Event> { Event.Done };
|
||||
}
|
||||
else if (testParams.Activity.ToLower().Contains(cmd = SimulateCmd))
|
||||
{
|
||||
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting));
|
||||
|
||||
if (testParams.Activity.ToLower().Contains("q3")) MakeSimulated(test, 1, 0, -0.5f);
|
||||
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "q2") MakeSimulated(test, 1, 0, 0.5f);
|
||||
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "q1") MakeSimulated(test, 1, 0, -5.1f);
|
||||
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound ok") MakeSimulatedCompound(test, 1, 0, 0.7f, 1.0f);
|
||||
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound nok") MakeSimulatedCompound(test, 1, 0, 4.7f, 0.9f);
|
||||
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound rise") MakeSimulatedCompound(test, 1, 0, 0.7f, 0.0f);
|
||||
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound fall") MakeSimulatedCompound(test, 1, 0, 0.7f, 0.9f);
|
||||
else if (testParams.Activity.Substring(cmd.Length).ToLower() == "iperls")
|
||||
{
|
||||
string[] pcbNrs = new string[] { "831232435539", "831232435562", "831232435587",
|
||||
"831232432141", "831232432497", "831232763641" };
|
||||
|
||||
TestRslt tstRslt = BatchRslts.GetTestRslt(test.Name, test.Part);
|
||||
if (tstRslt != null)
|
||||
{
|
||||
Results.Utils.GetCounterStates(tstRslt, Program.LocalSettings.Counters);
|
||||
|
||||
/// Auxiliary results ... not required
|
||||
|
||||
/// Main results
|
||||
tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName;
|
||||
tstRslt.TestDone = true;
|
||||
tstRslt.StartTime = tstRslt.Batch.StartTime;
|
||||
tstRslt.EndTime = DateTime.Now;
|
||||
tstRslt.FlowSetTime = 0;
|
||||
tstRslt.MassOfEvapWater = 0;
|
||||
tstRslt.TestTime = 1;
|
||||
|
||||
for (int i = 0; i < BatchRslts.Batch.WaterMeters.Count; i++)
|
||||
{
|
||||
MeterTestRslt meterRslt =
|
||||
BatchRslts.GetMeterTestRslt(test.Name, i, CompoundMeterId.Single);
|
||||
|
||||
if (meterRslt != null)
|
||||
{
|
||||
meterRslt.WaterMeter.SerialNr = pcbNrs[i % pcbNrs.Length];
|
||||
meterRslt.Passed = true;
|
||||
meterRslt.TestDone = true;
|
||||
}
|
||||
//if (iperlHeads[i] != null)
|
||||
//{
|
||||
// iperlHeads[i].CommFailed = iperlHeads[i].Disabled = false;
|
||||
// iperlHeads[i].SerialNr = pcbNrs[i % pcbNrs.Length];
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
|
||||
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(Common.Utils.GetTestName(test.Name, 1, 1), 0)));
|
||||
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
|
||||
|
||||
//------------------------------------------------
|
||||
Bridge.OnActivity(this, testParams.Activity);
|
||||
//------------------------------------------------
|
||||
|
||||
State.Create(string.Format("iPerlCommunicationSeq : {0}", testParams.Activity))
|
||||
.AddOperation(checkUiOp)
|
||||
.EnterState();
|
||||
e = StateMachine.WaitRunDevsRunOps();
|
||||
|
||||
if (TestAndLogUiCmdStop(test, e))
|
||||
{
|
||||
return new List<Event> { Event.UiCmdStop };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
///
|
||||
/// Show the modeless dialog with error indication
|
||||
///
|
||||
Program.MainWnd.Invoke(new IPerlCommFormDlgt(OpenIPerlCommForm), new object[] { this, method, test, testParams });
|
||||
|
||||
//------------------------------------------------
|
||||
Bridge.OnActivity(this, Strings.iPerl_Communication_in_progress);
|
||||
//------------------------------------------------
|
||||
|
||||
bool stopPressed = false; /// true when STOP button pressed
|
||||
bool completed = false;
|
||||
|
||||
State.Create("iPerlCommunicationSeq : Wait until the entry form is closed")
|
||||
.AddOperation(checkUiOp)
|
||||
.EnterState();
|
||||
do {
|
||||
e = StateMachine.WaitRunDevsRunOps();
|
||||
stopPressed = TestAndLogUiCmdStop(test, e);
|
||||
completed = (modelessDlg is GenericDevices.IHasCompleted)
|
||||
&& (modelessDlg as GenericDevices.IHasCompleted).Completed;
|
||||
}
|
||||
while (!stopPressed && !completed);
|
||||
|
||||
if (stopPressed)
|
||||
{
|
||||
CloseIPerlCommForm();
|
||||
return new List<Event> { Event.UiCmdStop };
|
||||
}
|
||||
else
|
||||
{
|
||||
TBF.UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(test.Name, Progress.Completed));
|
||||
}
|
||||
|
||||
/// Test 'Quit'
|
||||
modelessDlg = null; /// Modeless dialog is closed now
|
||||
}
|
||||
|
||||
return new List<Event> { Event.Done };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read default Q2 correction factors from a REST service (= Web service).
|
||||
/// </summary>
|
||||
/// <param name="cfg">iPerlCommunication component configuration</param>
|
||||
/// <param name="wmType">Water meter type (WZ Typ)</param>
|
||||
/// <param name="q2PreCorrectionLR">Default Q2 correction LR</param>
|
||||
/// <param name="q2PreCorrectionRL">Default Q2 correction RL</param>
|
||||
/// <returns>true when successful</returns>
|
||||
static bool ReadCorrectionsFromWebService(TestMethodCfg cfg, int wmType, out int q2PreCorrectionLR, out int q2PreCorrectionRL)
|
||||
{
|
||||
if (wmType == 0)
|
||||
{
|
||||
/// No REST service call when wmType == 0, factors are 0
|
||||
q2PreCorrectionLR = 0;
|
||||
q2PreCorrectionRL = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
GetQ2PreCorrectionClient client = new GetQ2PreCorrectionClient(cfg.BaseUrl);
|
||||
client.GetToken("ReadUser", "sensus", "https://deluh1web03.world.fluidtechnology.net/SensusCore/api/v1/Locations/1/Login2").Wait();
|
||||
Q2PreCorrection response = client.GetQ2Correction(string.Format(cfg.RelativeUrl, wmType)).Result;
|
||||
if (response != null && response.AreDataCalculated)
|
||||
{
|
||||
q2PreCorrectionLR = response.CorrLR;
|
||||
q2PreCorrectionRL = response.CorrRL;
|
||||
log.WarnFormat("Q2 corrections from a REST client for WM Type = {0} are: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.ErrorFormat("Failed to obtain Q2 corrections from a REST client for WM Type = {0}", wmType);
|
||||
q2PreCorrectionLR = 0;
|
||||
q2PreCorrectionRL = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Failed to obtain Q2 corrections from a REST client for WM Type = {0}: {1}", wmType, exc.Message);
|
||||
q2PreCorrectionLR = 0;
|
||||
q2PreCorrectionRL = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Obtain Q2 correction factors from a REST service or from local settings (stored backup values)
|
||||
/// </summary>
|
||||
/// <param name="cfg">iPerlCommunication component configuration</param>
|
||||
/// <param name="wmType">Water meter type (WZ Typ)</param>
|
||||
/// <param name="q2PreCorrectionLR">Default Q2 correction LR</param>
|
||||
/// <param name="q2PreCorrectionRL">Default Q2 correction RL</param>
|
||||
/// <returns>true when successful</returns>
|
||||
public static bool GetQ2PreCorrectionsOrBackups(TestMethodCfg cfg, int wmType, out int q2PreCorrectionLR, out int q2PreCorrectionRL)
|
||||
{
|
||||
/// Get Q2 pre-correction values from REST service
|
||||
bool restOK = ReadCorrectionsFromWebService(cfg, wmType, out q2PreCorrectionLR, out q2PreCorrectionRL);
|
||||
|
||||
/// Store / load Q2 pre-correction values
|
||||
Point storedValue;
|
||||
if (restOK)
|
||||
{
|
||||
/// Q2 pre-correction values were successfully obtained from a REST service for the specified wmType
|
||||
if (!Program.LocalSettings.Q2PreCorrections.TryGetValue(wmType, out storedValue))
|
||||
{
|
||||
/// No Q2 pre-correction values in the dictionary for the specified wmType => save them
|
||||
Program.LocalSettings.Q2PreCorrections.Add(wmType, new Point(q2PreCorrectionLR, q2PreCorrectionRL));
|
||||
log.WarnFormat("Q2 corrections added to dictionary for WM Type = {0}: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
|
||||
}
|
||||
else if (storedValue.X != q2PreCorrectionLR || storedValue.Y != q2PreCorrectionRL)
|
||||
{
|
||||
/// Different Q2 pre-correction values in the dictionary for the specified wmType => overwrite them with ones from the REST service
|
||||
Program.LocalSettings.Q2PreCorrections[wmType] = new Point(q2PreCorrectionLR, q2PreCorrectionRL);
|
||||
log.WarnFormat("Q2 corrections modified in dictionary for WM Type = {0}: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Q2 pre-correction values in the dictionary are the same and were not changed
|
||||
log.WarnFormat("Q2 corrections in dictionary for WM Type = {0} are the same and were not changed", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/// No Q2 pre-correction values from a REST service => read the dictionary
|
||||
if (Program.LocalSettings.Q2PreCorrections.TryGetValue(wmType, out storedValue))
|
||||
{
|
||||
/// Q2 pre-correction values successfully read from the dictionary
|
||||
q2PreCorrectionLR = storedValue.X;
|
||||
q2PreCorrectionRL = storedValue.Y;
|
||||
log.WarnFormat("Q2 corrections loaded from dictionary for WM Type = {0}: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Q2 pre-correction values not found in the dictionary => use zeros
|
||||
q2PreCorrectionLR = 0;
|
||||
q2PreCorrectionRL = 0;
|
||||
log.ErrorFormat("Q2 corrections not found in the dictionary for WM Type = {0}, using zeros", wmType, q2PreCorrectionLR, q2PreCorrectionRL);
|
||||
|
||||
/// Everything failed => using zero values
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Q2 pre-corections were obtained from REST service or stored backup values were used
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Virtually apply Q2 correction to a test used for the correction calculation.
|
||||
/// </summary>
|
||||
/// <param name="testName">This test name</param>
|
||||
/// <param name="oriTestRslt">Name of Q2 test done before Q2 correction (Q2adj)</param>
|
||||
/// <remarks>Assuming this test does not have multiple parts (part = 0)</remarks>
|
||||
void MakeQ2CorrectedFrom(string testName, string oriTestName, bool isPlus = false)
|
||||
{
|
||||
Results.Entities.TestRslt oriTestRslt = ProcessData.BatchRslts.GetTestRslt(oriTestName, 0);
|
||||
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(testName, 0);
|
||||
|
||||
if (oriTestRslt == null || tstRslt == null) return;
|
||||
|
||||
tstRslt.Components = oriTestRslt.Components;
|
||||
|
||||
/// Auxiliary results, as in SequenceBase.UpdateTemoPressDensAmb()
|
||||
tstRslt.AmbTempMean = oriTestRslt.AmbTempMean;
|
||||
tstRslt.AmbTempStart = oriTestRslt.AmbTempStart;
|
||||
tstRslt.AmbTempEnd = oriTestRslt.AmbTempEnd;
|
||||
tstRslt.AmbTempMin = oriTestRslt.AmbTempMin;
|
||||
tstRslt.AmbTempMax = oriTestRslt.AmbTempMax;
|
||||
tstRslt.AmbPressMean = oriTestRslt.AmbPressMean;
|
||||
tstRslt.AmbPressStart = oriTestRslt.AmbPressStart;
|
||||
tstRslt.AmbPressEnd = oriTestRslt.AmbPressEnd;
|
||||
tstRslt.AmbPressMin = oriTestRslt.AmbPressMin;
|
||||
tstRslt.AmbPressMax = oriTestRslt.AmbPressMax;
|
||||
tstRslt.AmbHumiMean = oriTestRslt.AmbHumiMean;
|
||||
tstRslt.AmbHumiStart = oriTestRslt.AmbHumiStart;
|
||||
tstRslt.AmbHumiEnd = oriTestRslt.AmbHumiEnd;
|
||||
tstRslt.AmbHumiMin = oriTestRslt.AmbHumiMin;
|
||||
tstRslt.AmbHumiMax = oriTestRslt.AmbHumiMax;
|
||||
tstRslt.PressUpMean = oriTestRslt.PressUpMean;
|
||||
tstRslt.PressUpStart = oriTestRslt.PressUpStart;
|
||||
tstRslt.PressUpEnd = oriTestRslt.PressUpEnd;
|
||||
tstRslt.PressUpMin = oriTestRslt.PressUpMin;
|
||||
tstRslt.PressUpMax = oriTestRslt.PressUpMax;
|
||||
tstRslt.PressDownMean = oriTestRslt.PressDownMean;
|
||||
tstRslt.PressDownStart = oriTestRslt.PressDownStart;
|
||||
tstRslt.PressDownEnd = oriTestRslt.PressDownEnd;
|
||||
tstRslt.PressDownMin = oriTestRslt.PressDownMin;
|
||||
tstRslt.PressDownMax = oriTestRslt.PressDownMax;
|
||||
tstRslt.PressDeltaMean = oriTestRslt.PressDeltaMean;
|
||||
tstRslt.PressDeltaStart = oriTestRslt.PressDeltaStart;
|
||||
tstRslt.PressDeltaEnd = oriTestRslt.PressDeltaEnd;
|
||||
tstRslt.PressDeltaMin = oriTestRslt.PressDeltaMin;
|
||||
tstRslt.PressDeltaMax = oriTestRslt.PressDeltaMax;
|
||||
tstRslt.ConductMean = oriTestRslt.ConductMean;
|
||||
tstRslt.ConductStart = oriTestRslt.ConductStart;
|
||||
tstRslt.ConductEnd = oriTestRslt.ConductEnd;
|
||||
tstRslt.ConductMin = oriTestRslt.ConductMin;
|
||||
tstRslt.ConductMax = oriTestRslt.ConductMax;
|
||||
tstRslt.TempUpMean = oriTestRslt.TempUpMean;
|
||||
tstRslt.TempUpStart = oriTestRslt.TempUpStart;
|
||||
tstRslt.TempUpEnd = oriTestRslt.TempUpEnd;
|
||||
tstRslt.TempUpMin = oriTestRslt.TempUpMin;
|
||||
tstRslt.TempUpMax = oriTestRslt.TempUpMax;
|
||||
tstRslt.TempDownMean = oriTestRslt.TempDownMean;
|
||||
tstRslt.TempDownStart = oriTestRslt.TempDownStart;
|
||||
tstRslt.TempDownEnd = oriTestRslt.TempDownEnd;
|
||||
tstRslt.TempDownMin = oriTestRslt.TempDownMin;
|
||||
tstRslt.TempDownMax = oriTestRslt.TempDownMax;
|
||||
tstRslt.TempDivMean = oriTestRslt.TempDivMean;
|
||||
tstRslt.TempDivStart = oriTestRslt.TempDivStart;
|
||||
tstRslt.TempDivEnd = oriTestRslt.TempDivEnd;
|
||||
tstRslt.TempDivMin = oriTestRslt.TempDivMin;
|
||||
tstRslt.TempDivMax = oriTestRslt.TempDivMax;
|
||||
tstRslt.DensityIn = oriTestRslt.DensityIn;
|
||||
tstRslt.DensityLine = oriTestRslt.DensityLine;
|
||||
tstRslt.DensityDiv = oriTestRslt.DensityDiv;
|
||||
|
||||
tstRslt.StartTime = oriTestRslt.StartTime;
|
||||
tstRslt.EndTime = oriTestRslt.EndTime;
|
||||
tstRslt.FlowSetTime = oriTestRslt.FlowSetTime;
|
||||
tstRslt.TestTime = oriTestRslt.TestTime;
|
||||
tstRslt.PulsesMaster = oriTestRslt.PulsesMaster;
|
||||
tstRslt.ConstMasterRaw = oriTestRslt.ConstMasterRaw;
|
||||
tstRslt.ConstMaster = oriTestRslt.ConstMaster;
|
||||
tstRslt.MassStartRaw = oriTestRslt.MassStartRaw;
|
||||
tstRslt.MassStart = oriTestRslt.MassStart;
|
||||
tstRslt.MassEndRaw = oriTestRslt.MassEndRaw;
|
||||
tstRslt.MassEnd = oriTestRslt.MassEnd;
|
||||
tstRslt.MassOfEvapWater = oriTestRslt.MassOfEvapWater;
|
||||
//tstRslt.FlowMass = oriTestRslt.FlowMass;
|
||||
//tstRslt.FlowVolume = oriTestRslt.FlowVolume;
|
||||
tstRslt.VolumeCTV = oriTestRslt.VolumeCTV;
|
||||
tstRslt.VolumeMaster = oriTestRslt.VolumeMaster;
|
||||
tstRslt.ErrorMaster = oriTestRslt.ErrorMaster;
|
||||
|
||||
tstRslt.FlowMean = oriTestRslt.FlowMean;
|
||||
tstRslt.FlowMin = oriTestRslt.FlowMin;
|
||||
tstRslt.FlowMax = oriTestRslt.FlowMax;
|
||||
|
||||
tstRslt.Custom1 = oriTestRslt.Custom1;
|
||||
tstRslt.Custom2 = oriTestRslt.Custom2;
|
||||
tstRslt.Custom3 = oriTestRslt.Custom3;
|
||||
tstRslt.Custom4 = oriTestRslt.Custom4;
|
||||
tstRslt.Custom5 = oriTestRslt.Custom5;
|
||||
tstRslt.Custom6 = oriTestRslt.Custom6;
|
||||
tstRslt.Custom7 = oriTestRslt.Custom7;
|
||||
tstRslt.Custom8 = oriTestRslt.Custom8;
|
||||
|
||||
for (int i = 0; i < ProcessData.BatchRslts.WMPositionsCount; i++)
|
||||
{
|
||||
// Fix for CS7036: Added the missing 'meterId' argument to the GetMeterTestRslt method call.
|
||||
var q3mtr = ProcessData.BatchRslts.GetMeterTestRslt("Q3", i, CompoundMeterId.SingleOrCompound);
|
||||
double q3error = (q3mtr != null) ? q3mtr.Error : 0;
|
||||
|
||||
Results.Entities.MeterTestRslt oriMeterRslt = ProcessData.BatchRslts.GetMeterTestRslt(oriTestName, i, CompoundMeterId.SingleOrCompound);
|
||||
Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(testName, i, CompoundMeterId.SingleOrCompound);
|
||||
|
||||
/// Reference to iPerl water meter or null:
|
||||
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = ((sensPath != null) && (sensPath.RegisterReaders != null) && (i < sensPath.RegisterReaders.Length))
|
||||
? (sensPath.RegisterReaders[i] as TestMethods.iPerlCommunication.iPerlHead.IperlHead)
|
||||
: null;
|
||||
|
||||
if (iPerl != null && meterRslt != null && oriMeterRslt != null)
|
||||
{
|
||||
#if ORACLE_DB
|
||||
meterRslt.ErrorBC = oriMeterRslt.Error;
|
||||
#endif
|
||||
meterRslt.PulsesMeter = oriMeterRslt.PulsesMeter;
|
||||
meterRslt.PulsesMaster = oriMeterRslt.PulsesMaster;
|
||||
meterRslt.PulsesPerLiter = oriMeterRslt.PulsesPerLiter;
|
||||
meterRslt.VolumeRef = oriMeterRslt.VolumeRef;
|
||||
meterRslt.TestTime = oriMeterRslt.TestTime;
|
||||
|
||||
if (q3error * oriMeterRslt.Error < 0)
|
||||
{
|
||||
/// iPerl with Q2 correction => generate an artificial error equal to +1/10 of the original one (relative to Q2 target error)
|
||||
meterRslt.Error = 0.1 * oriMeterRslt.Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// iPerl with Q2 correction => generate an artificial error equal to -1/10 of the original one (relative to Q2 target error)
|
||||
meterRslt.Error = - 0.1 * oriMeterRslt.Error;
|
||||
}
|
||||
|
||||
meterRslt.VolumeMeter = meterRslt.VolumeRef * (100.0 + meterRslt.Error) / 100.0;
|
||||
double signature = (oriMeterRslt.VolumeEnd > oriMeterRslt.VolumeStart) ? (+1) : (-1);
|
||||
meterRslt.VolumeStart = oriMeterRslt.VolumeStart;
|
||||
meterRslt.VolumeEnd = meterRslt.VolumeStart + signature * meterRslt.VolumeMeter;
|
||||
|
||||
meterRslt.Passed = (meterRslt.Error >= tstRslt.ErrLimLo() + tstRslt.ErrLimMargin()
|
||||
&& meterRslt.Error <= tstRslt.ErrLimHi() - tstRslt.ErrLimMargin());
|
||||
meterRslt.TestDone = true;
|
||||
tstRslt.TestDone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluate a given Q2 test result agains stricter error limits when Oruefindex == 1.
|
||||
/// </summary>
|
||||
/// <param name="testName">This test name</param>
|
||||
/// <param name="oriTestRslt">Name of Q2 test done before Q2 correction (Q2adj)</param>
|
||||
/// <remarks>Assuming this test does not have multiple parts (part = 0)</remarks>
|
||||
void StrictQ2ErrorCheck(string testName, string oriTestName)
|
||||
{
|
||||
Results.Entities.TestRslt oriTestRslt = ProcessData.BatchRslts.GetTestRslt(oriTestName, 0);
|
||||
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(testName, 0);
|
||||
|
||||
if (oriTestRslt == null || tstRslt == null) return;
|
||||
|
||||
tstRslt.Components = oriTestRslt.Components;
|
||||
|
||||
/// Auxiliary results, as in SequenceBase.UpdateTemoPressDensAmb()
|
||||
tstRslt.AmbTempMean = oriTestRslt.AmbTempMean;
|
||||
tstRslt.AmbTempStart = oriTestRslt.AmbTempStart;
|
||||
tstRslt.AmbTempEnd = oriTestRslt.AmbTempEnd;
|
||||
tstRslt.AmbTempMin = oriTestRslt.AmbTempMin;
|
||||
tstRslt.AmbTempMax = oriTestRslt.AmbTempMax;
|
||||
tstRslt.AmbPressMean = oriTestRslt.AmbPressMean;
|
||||
tstRslt.AmbPressStart = oriTestRslt.AmbPressStart;
|
||||
tstRslt.AmbPressEnd = oriTestRslt.AmbPressEnd;
|
||||
tstRslt.AmbPressMin = oriTestRslt.AmbPressMin;
|
||||
tstRslt.AmbPressMax = oriTestRslt.AmbPressMax;
|
||||
tstRslt.AmbHumiMean = oriTestRslt.AmbHumiMean;
|
||||
tstRslt.AmbHumiStart = oriTestRslt.AmbHumiStart;
|
||||
tstRslt.AmbHumiEnd = oriTestRslt.AmbHumiEnd;
|
||||
tstRslt.AmbHumiMin = oriTestRslt.AmbHumiMin;
|
||||
tstRslt.AmbHumiMax = oriTestRslt.AmbHumiMax;
|
||||
tstRslt.PressUpMean = oriTestRslt.PressUpMean;
|
||||
tstRslt.PressUpStart = oriTestRslt.PressUpStart;
|
||||
tstRslt.PressUpEnd = oriTestRslt.PressUpEnd;
|
||||
tstRslt.PressUpMin = oriTestRslt.PressUpMin;
|
||||
tstRslt.PressUpMax = oriTestRslt.PressUpMax;
|
||||
tstRslt.PressDownMean = oriTestRslt.PressDownMean;
|
||||
tstRslt.PressDownStart = oriTestRslt.PressDownStart;
|
||||
tstRslt.PressDownEnd = oriTestRslt.PressDownEnd;
|
||||
tstRslt.PressDownMin = oriTestRslt.PressDownMin;
|
||||
tstRslt.PressDownMax = oriTestRslt.PressDownMax;
|
||||
tstRslt.PressDeltaMean = oriTestRslt.PressDeltaMean;
|
||||
tstRslt.PressDeltaStart = oriTestRslt.PressDeltaStart;
|
||||
tstRslt.PressDeltaEnd = oriTestRslt.PressDeltaEnd;
|
||||
tstRslt.PressDeltaMin = oriTestRslt.PressDeltaMin;
|
||||
tstRslt.PressDeltaMax = oriTestRslt.PressDeltaMax;
|
||||
tstRslt.ConductMean = oriTestRslt.ConductMean;
|
||||
tstRslt.ConductStart = oriTestRslt.ConductStart;
|
||||
tstRslt.ConductEnd = oriTestRslt.ConductEnd;
|
||||
tstRslt.ConductMin = oriTestRslt.ConductMin;
|
||||
tstRslt.ConductMax = oriTestRslt.ConductMax;
|
||||
tstRslt.TempUpMean = oriTestRslt.TempUpMean;
|
||||
tstRslt.TempUpStart = oriTestRslt.TempUpStart;
|
||||
tstRslt.TempUpEnd = oriTestRslt.TempUpEnd;
|
||||
tstRslt.TempUpMin = oriTestRslt.TempUpMin;
|
||||
tstRslt.TempUpMax = oriTestRslt.TempUpMax;
|
||||
tstRslt.TempDownMean = oriTestRslt.TempDownMean;
|
||||
tstRslt.TempDownStart = oriTestRslt.TempDownStart;
|
||||
tstRslt.TempDownEnd = oriTestRslt.TempDownEnd;
|
||||
tstRslt.TempDownMin = oriTestRslt.TempDownMin;
|
||||
tstRslt.TempDownMax = oriTestRslt.TempDownMax;
|
||||
tstRslt.TempDivMean = oriTestRslt.TempDivMean;
|
||||
tstRslt.TempDivStart = oriTestRslt.TempDivStart;
|
||||
tstRslt.TempDivEnd = oriTestRslt.TempDivEnd;
|
||||
tstRslt.TempDivMin = oriTestRslt.TempDivMin;
|
||||
tstRslt.TempDivMax = oriTestRslt.TempDivMax;
|
||||
tstRslt.DensityIn = oriTestRslt.DensityIn;
|
||||
tstRslt.DensityLine = oriTestRslt.DensityLine;
|
||||
tstRslt.DensityDiv = oriTestRslt.DensityDiv;
|
||||
|
||||
tstRslt.StartTime = oriTestRslt.StartTime;
|
||||
tstRslt.EndTime = oriTestRslt.EndTime;
|
||||
tstRslt.FlowSetTime = oriTestRslt.FlowSetTime;
|
||||
tstRslt.TestTime = oriTestRslt.TestTime;
|
||||
tstRslt.PulsesMaster = oriTestRslt.PulsesMaster;
|
||||
tstRslt.ConstMasterRaw = oriTestRslt.ConstMasterRaw;
|
||||
tstRslt.ConstMaster = oriTestRslt.ConstMaster;
|
||||
tstRslt.MassStartRaw = oriTestRslt.MassStartRaw;
|
||||
tstRslt.MassStart = oriTestRslt.MassStart;
|
||||
tstRslt.MassEndRaw = oriTestRslt.MassEndRaw;
|
||||
tstRslt.MassEnd = oriTestRslt.MassEnd;
|
||||
tstRslt.MassOfEvapWater = oriTestRslt.MassOfEvapWater;
|
||||
//tstRslt.FlowMass = oriTestRslt.FlowMass;
|
||||
//tstRslt.FlowVolume = oriTestRslt.FlowVolume;
|
||||
tstRslt.VolumeCTV = oriTestRslt.VolumeCTV;
|
||||
tstRslt.VolumeMaster = oriTestRslt.VolumeMaster;
|
||||
tstRslt.ErrorMaster = oriTestRslt.ErrorMaster;
|
||||
|
||||
tstRslt.FlowMean = oriTestRslt.FlowMean;
|
||||
tstRslt.FlowMin = oriTestRslt.FlowMin;
|
||||
tstRslt.FlowMax = oriTestRslt.FlowMax;
|
||||
|
||||
tstRslt.Custom1 = oriTestRslt.Custom1;
|
||||
tstRslt.Custom2 = oriTestRslt.Custom2;
|
||||
tstRslt.Custom3 = oriTestRslt.Custom3;
|
||||
tstRslt.Custom4 = oriTestRslt.Custom4;
|
||||
tstRslt.Custom5 = oriTestRslt.Custom5;
|
||||
tstRslt.Custom6 = oriTestRslt.Custom6;
|
||||
tstRslt.Custom7 = oriTestRslt.Custom7;
|
||||
tstRslt.Custom8 = oriTestRslt.Custom8;
|
||||
|
||||
for (int i = 0; i < ProcessData.BatchRslts.WMPositionsCount; i++)
|
||||
{
|
||||
Results.Entities.MeterTestRslt oriMeterRslt = ProcessData.BatchRslts.GetMeterTestRslt(oriTestName, i, CompoundMeterId.Single);
|
||||
Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(testName, i, CompoundMeterId.Single);
|
||||
|
||||
/// Reference to iPerl water meter or null:
|
||||
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = ((sensPath != null) && (sensPath.RegisterReaders != null) && (i < sensPath.RegisterReaders.Length))
|
||||
? (sensPath.RegisterReaders[i] as TestMethods.iPerlCommunication.iPerlHead.IperlHead)
|
||||
: null;
|
||||
|
||||
if (meterRslt != null && oriMeterRslt != null)
|
||||
{
|
||||
#if ORACLE_DB
|
||||
meterRslt.ErrorBC = oriMeterRslt.Error;
|
||||
#endif
|
||||
meterRslt.PulsesMeter = oriMeterRslt.PulsesMeter;
|
||||
meterRslt.PulsesMaster = oriMeterRslt.PulsesMaster;
|
||||
meterRslt.PulsesPerLiter = oriMeterRslt.PulsesPerLiter;
|
||||
meterRslt.VolumeRef = oriMeterRslt.VolumeRef;
|
||||
meterRslt.TestTime = oriMeterRslt.TestTime;
|
||||
|
||||
if (iPerl != null && ProcessData.BatchRslts.Batch.WaterMeters[i] != null &&
|
||||
!ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled)
|
||||
{
|
||||
/// Either no iPerl head or no Q2 correction
|
||||
meterRslt.Error = oriMeterRslt.Error;
|
||||
meterRslt.VolumeMeter = oriMeterRslt.VolumeMeter;
|
||||
meterRslt.VolumeStart = oriMeterRslt.VolumeStart;
|
||||
meterRslt.VolumeEnd = oriMeterRslt.VolumeEnd;
|
||||
#if ORACLE_DB
|
||||
if ((ProcessData.BatchRslts.Batch.WaterMeters[i].Pruefindex % 100) == 1)
|
||||
{
|
||||
meterRslt.Passed = (oriMeterRslt.Error >= tstRslt.ErrLimLo() + tstRslt.ErrLimMargin()
|
||||
&& oriMeterRslt.Error <= tstRslt.ErrLimHi() - tstRslt.ErrLimMargin());
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
meterRslt.Passed = oriMeterRslt.Passed;
|
||||
}
|
||||
meterRslt.TestDone = true;
|
||||
tstRslt.TestDone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check results of 2 tests: before Q2 correction and after Q2 correction.
|
||||
/// Evaluate whether Q2 correction works OK.
|
||||
/// </summary>
|
||||
/// <param name="testName">This test name</param>
|
||||
/// <param name="testNameQ2bc">Name of Q2 test done before correction</param>
|
||||
/// <param name="testNameQ2ac">Name of Q2 test done after correction</param>
|
||||
/// <remarks>Assuming these tests do not have multiple parts (part = 0)</remarks>
|
||||
void CheckQ2Correction(string testName, string testNameQ2bc, string testNameQ2ac)
|
||||
{
|
||||
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(testName, 0);
|
||||
Results.Entities.TestRslt testRsltQ2bc = ProcessData.BatchRslts.GetTestRslt(testNameQ2bc, 0);
|
||||
Results.Entities.TestRslt testRsltQ2ac = ProcessData.BatchRslts.GetTestRslt(testNameQ2ac, 0);
|
||||
|
||||
if ((tstRslt == null) || (testRsltQ2bc == null) || (testRsltQ2ac == null)) return;
|
||||
|
||||
tstRslt.Components = testRsltQ2ac.Components;
|
||||
|
||||
/// Auxiliary results, as in SequenceBase.UpdateTemoPressDensAmb()
|
||||
tstRslt.AmbTempMean = testRsltQ2ac.AmbTempMean;
|
||||
tstRslt.AmbTempStart = testRsltQ2ac.AmbTempStart;
|
||||
tstRslt.AmbTempEnd = testRsltQ2ac.AmbTempEnd;
|
||||
tstRslt.AmbTempMin = testRsltQ2ac.AmbTempMin;
|
||||
tstRslt.AmbTempMax = testRsltQ2ac.AmbTempMax;
|
||||
tstRslt.AmbPressMean = testRsltQ2ac.AmbPressMean;
|
||||
tstRslt.AmbPressStart = testRsltQ2ac.AmbPressStart;
|
||||
tstRslt.AmbPressEnd = testRsltQ2ac.AmbPressEnd;
|
||||
tstRslt.AmbPressMin = testRsltQ2ac.AmbPressMin;
|
||||
tstRslt.AmbPressMax = testRsltQ2ac.AmbPressMax;
|
||||
tstRslt.AmbHumiMean = testRsltQ2ac.AmbHumiMean;
|
||||
tstRslt.AmbHumiStart = testRsltQ2ac.AmbHumiStart;
|
||||
tstRslt.AmbHumiEnd = testRsltQ2ac.AmbHumiEnd;
|
||||
tstRslt.AmbHumiMin = testRsltQ2ac.AmbHumiMin;
|
||||
tstRslt.AmbHumiMax = testRsltQ2ac.AmbHumiMax;
|
||||
tstRslt.PressUpMean = testRsltQ2ac.PressUpMean;
|
||||
tstRslt.PressUpStart = testRsltQ2ac.PressUpStart;
|
||||
tstRslt.PressUpEnd = testRsltQ2ac.PressUpEnd;
|
||||
tstRslt.PressUpMin = testRsltQ2ac.PressUpMin;
|
||||
tstRslt.PressUpMax = testRsltQ2ac.PressUpMax;
|
||||
tstRslt.PressDownMean = testRsltQ2ac.PressDownMean;
|
||||
tstRslt.PressDownStart = testRsltQ2ac.PressDownStart;
|
||||
tstRslt.PressDownEnd = testRsltQ2ac.PressDownEnd;
|
||||
tstRslt.PressDownMin = testRsltQ2ac.PressDownMin;
|
||||
tstRslt.PressDownMax = testRsltQ2ac.PressDownMax;
|
||||
tstRslt.PressDeltaMean = testRsltQ2ac.PressDeltaMean;
|
||||
tstRslt.PressDeltaStart = testRsltQ2ac.PressDeltaStart;
|
||||
tstRslt.PressDeltaEnd = testRsltQ2ac.PressDeltaEnd;
|
||||
tstRslt.PressDeltaMin = testRsltQ2ac.PressDeltaMin;
|
||||
tstRslt.PressDeltaMax = testRsltQ2ac.PressDeltaMax;
|
||||
tstRslt.ConductMean = testRsltQ2ac.ConductMean;
|
||||
tstRslt.ConductStart = testRsltQ2ac.ConductStart;
|
||||
tstRslt.ConductEnd = testRsltQ2ac.ConductEnd;
|
||||
tstRslt.ConductMin = testRsltQ2ac.ConductMin;
|
||||
tstRslt.ConductMax = testRsltQ2ac.ConductMax;
|
||||
tstRslt.TempUpMean = testRsltQ2ac.TempUpMean;
|
||||
tstRslt.TempUpStart = testRsltQ2ac.TempUpStart;
|
||||
tstRslt.TempUpEnd = testRsltQ2ac.TempUpEnd;
|
||||
tstRslt.TempUpMin = testRsltQ2ac.TempUpMin;
|
||||
tstRslt.TempUpMax = testRsltQ2ac.TempUpMax;
|
||||
tstRslt.TempDownMean = testRsltQ2ac.TempDownMean;
|
||||
tstRslt.TempDownStart = testRsltQ2ac.TempDownStart;
|
||||
tstRslt.TempDownEnd = testRsltQ2ac.TempDownEnd;
|
||||
tstRslt.TempDownMin = testRsltQ2ac.TempDownMin;
|
||||
tstRslt.TempDownMax = testRsltQ2ac.TempDownMax;
|
||||
tstRslt.TempDivMean = testRsltQ2ac.TempDivMean;
|
||||
tstRslt.TempDivStart = testRsltQ2ac.TempDivStart;
|
||||
tstRslt.TempDivEnd = testRsltQ2ac.TempDivEnd;
|
||||
tstRslt.TempDivMin = testRsltQ2ac.TempDivMin;
|
||||
tstRslt.TempDivMax = testRsltQ2ac.TempDivMax;
|
||||
tstRslt.DensityIn = testRsltQ2ac.DensityIn;
|
||||
tstRslt.DensityLine = testRsltQ2ac.DensityLine;
|
||||
tstRslt.DensityDiv = testRsltQ2ac.DensityDiv;
|
||||
|
||||
tstRslt.StartTime = testRsltQ2ac.StartTime;
|
||||
tstRslt.EndTime = testRsltQ2ac.EndTime;
|
||||
tstRslt.FlowSetTime = testRsltQ2ac.FlowSetTime;
|
||||
tstRslt.TestTime = testRsltQ2ac.TestTime;
|
||||
tstRslt.PulsesMaster = testRsltQ2ac.PulsesMaster;
|
||||
tstRslt.ConstMasterRaw = testRsltQ2ac.ConstMasterRaw;
|
||||
tstRslt.ConstMaster = testRsltQ2ac.ConstMaster;
|
||||
tstRslt.MassStartRaw = testRsltQ2ac.MassStartRaw;
|
||||
tstRslt.MassStart = testRsltQ2ac.MassStart;
|
||||
tstRslt.MassEndRaw = testRsltQ2ac.MassEndRaw;
|
||||
tstRslt.MassEnd = testRsltQ2ac.MassEnd;
|
||||
tstRslt.MassOfEvapWater = testRsltQ2ac.MassOfEvapWater;
|
||||
//tstRslt.FlowMass = testRsltQ2ac.FlowMass;
|
||||
//tstRslt.FlowVolume = testRsltQ2ac.FlowVolume;
|
||||
tstRslt.VolumeCTV = testRsltQ2ac.VolumeCTV;
|
||||
tstRslt.VolumeMaster = testRsltQ2ac.VolumeMaster;
|
||||
tstRslt.ErrorMaster = testRsltQ2ac.ErrorMaster;
|
||||
|
||||
tstRslt.FlowMean = testRsltQ2ac.FlowMean;
|
||||
tstRslt.FlowMin = testRsltQ2ac.FlowMin;
|
||||
tstRslt.FlowMax = testRsltQ2ac.FlowMax;
|
||||
|
||||
tstRslt.Custom1 = testRsltQ2ac.Custom1;
|
||||
tstRslt.Custom2 = testRsltQ2ac.Custom2;
|
||||
tstRslt.Custom3 = testRsltQ2ac.Custom3;
|
||||
tstRslt.Custom4 = testRsltQ2ac.Custom4;
|
||||
tstRslt.Custom5 = testRsltQ2ac.Custom5;
|
||||
tstRslt.Custom6 = testRsltQ2ac.Custom6;
|
||||
tstRslt.Custom7 = testRsltQ2ac.Custom7;
|
||||
tstRslt.Custom8 = testRsltQ2ac.Custom8;
|
||||
|
||||
for (int i = 0; i < ProcessData.BatchRslts.WMPositionsCount; i++)
|
||||
{
|
||||
Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(testName, i, CompoundMeterId.Single);
|
||||
Results.Entities.MeterTestRslt meterRsltQ2bc = ProcessData.BatchRslts.GetMeterTestRslt(testNameQ2bc, i, CompoundMeterId.Single);
|
||||
Results.Entities.MeterTestRslt meterRsltQ2ac = ProcessData.BatchRslts.GetMeterTestRslt(testNameQ2ac, i, CompoundMeterId.Single);
|
||||
|
||||
if ((meterRslt != null) && (meterRsltQ2bc != null) && (meterRsltQ2ac != null))
|
||||
{
|
||||
meterRslt.PulsesMeter = meterRsltQ2ac.PulsesMeter;
|
||||
meterRslt.PulsesMaster = meterRsltQ2ac.PulsesMaster;
|
||||
meterRslt.PulsesPerLiter = meterRsltQ2ac.PulsesPerLiter;
|
||||
meterRslt.VolumeRef = meterRsltQ2ac.VolumeRef;
|
||||
meterRslt.TestTime = meterRsltQ2ac.TestTime;
|
||||
meterRslt.VolumeStart = meterRsltQ2ac.VolumeStart;
|
||||
meterRslt.VolumeEnd = meterRsltQ2ac.VolumeEnd;
|
||||
meterRslt.VolumeMeter = meterRsltQ2ac.VolumeMeter;
|
||||
meterRslt.Error = meterRsltQ2ac.Error;
|
||||
meterRslt.TestDone = meterRsltQ2ac.TestDone;
|
||||
tstRslt.TestDone = true;
|
||||
|
||||
if (((meterRsltQ2bc.Error < -0.51) && (meterRsltQ2ac.Error < meterRsltQ2bc.Error)) ||
|
||||
((meterRsltQ2bc.Error > +0.51) && (meterRsltQ2ac.Error > meterRsltQ2bc.Error)))
|
||||
{
|
||||
meterRslt.Passed = false; /// Q2 correction check failed
|
||||
}
|
||||
else
|
||||
{
|
||||
meterRslt.Passed = true; /// Q2 correction check passed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
///
|
||||
/// Copyright (c) 2022 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisFullCommunication
|
||||
{
|
||||
public enum ConditionID
|
||||
{
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
Count,
|
||||
}
|
||||
|
||||
public class SequenceConditionOp : IOperation
|
||||
{
|
||||
public const string ConditionNameFmt = "iPERL communication milestone {0}";
|
||||
|
||||
ConditionID id;
|
||||
TestMethod testMethodComponent;
|
||||
|
||||
public SequenceConditionOp(TestMethod testMethodComponent, ConditionID id)
|
||||
{
|
||||
this.testMethodComponent = testMethodComponent;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void Start() { }
|
||||
|
||||
public Event Run()
|
||||
{
|
||||
bool conditionMet = testMethodComponent.IperlCommMilestone[(int)id];
|
||||
return conditionMet ? Event.ConditionMet : Event.ConditionNotMet;
|
||||
}
|
||||
|
||||
public void Stop() { }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(ConditionNameFmt, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2022 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
using TBF.UiBridge;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisFullCommunication
|
||||
{
|
||||
public class TestMethod : SmartComponentBase, ISimultTestMethod, ISequenceCondition, ISessionDataMngmnt, ITestMethodSmart
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(TestMethod));
|
||||
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||
|
||||
public FlowType MethodFlowType => FlowType.volume;
|
||||
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
public bool CanTest(MetersKind meters) { return meters == MetersKind.Single; }
|
||||
public bool DoTransitions() { return false; }
|
||||
|
||||
public bool SimultWithPrevious { get { return testMethodCfg.TestParams.SimultWithPrevious; } }
|
||||
public bool SimultWithNext { get { return testMethodCfg.TestParams.SimultWithNext; } }
|
||||
|
||||
#region Configuration Change Handling
|
||||
|
||||
public static void OnCfgChange(object sender, CfgChangeArgs args)
|
||||
{
|
||||
if (CfgChangeHandler == null) return;
|
||||
try { CfgChangeHandler(sender, args); }
|
||||
catch (Exception e) { log.Error("CfgChangeHandler(...) failed", e); }
|
||||
}
|
||||
|
||||
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
|
||||
|
||||
public override void StartChangeHandler()
|
||||
{
|
||||
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
|
||||
{
|
||||
TestMethodCfg tmpCfg = args.Cfg as TestMethodCfg;
|
||||
if (tmpCfg != null && tmpCfg.Name.Equals(Name))
|
||||
{
|
||||
if (args.Command == CfgChangeCmd.CfgChange)
|
||||
{
|
||||
testMethodCfg.CommTimeout = tmpCfg.CommTimeout;
|
||||
testMethodCfg.DelayBetweenRetries = tmpCfg.DelayBetweenRetries;
|
||||
testMethodCfg.MaxCommRetries = tmpCfg.MaxCommRetries;
|
||||
testMethodCfg.IperlCheckErrorsToStop = tmpCfg.IperlCheckErrorsToStop;
|
||||
testMethodCfg.UseWebService = tmpCfg.UseWebService;
|
||||
testMethodCfg.BaseUrl = tmpCfg.BaseUrl;
|
||||
testMethodCfg.RelativeUrl = tmpCfg.RelativeUrl;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endregion Configuration Change Handling
|
||||
|
||||
|
||||
readonly TestMethodCfg testMethodCfg;
|
||||
|
||||
public bool[] IperlCommMilestone;
|
||||
IList<IOperation> sequenceConditionOps;
|
||||
|
||||
public TestMethod()
|
||||
{
|
||||
CreateMilestonesAndConditions();
|
||||
}
|
||||
|
||||
public TestMethod(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
testMethodCfg = cfg as TestMethodCfg;
|
||||
CreateMilestonesAndConditions();
|
||||
}
|
||||
|
||||
void CreateMilestonesAndConditions()
|
||||
{
|
||||
IperlCommMilestone = new bool[(int)ConditionID.Count];
|
||||
|
||||
sequenceConditionOps = new List<IOperation>();
|
||||
for (ConditionID id = ConditionID.A; id < ConditionID.Count; id++)
|
||||
{
|
||||
sequenceConditionOps.Add(new SequenceConditionOp(this, id));
|
||||
}
|
||||
}
|
||||
|
||||
/// IDevice interface - only Initialize() is used
|
||||
public override void Initialize()
|
||||
{
|
||||
if (DebugLevel == DebugMode.Normal)
|
||||
{
|
||||
rfidDataLogger.Fatal("------------------------------------------------------------------------");
|
||||
rfidDataLogger.FatalFormat("Test Bench Framework ver. {0}", Program.Version);
|
||||
|
||||
log.FatalFormat("{0} initialized: {1}", Name, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.FatalFormat("{0} simulated: {1}", Name, this);
|
||||
}
|
||||
}
|
||||
|
||||
public IList<Event> Execute(Test test, int repetNr, bool isLastRepetition)
|
||||
{
|
||||
if (DebugLevel == DebugMode.Normal)
|
||||
{
|
||||
return (new GenesisCommunicationSeq()).Execute(test, repetNr, this, testMethodCfg.TestParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// DebugLevel == DebugMode.Simulate
|
||||
(new GenesisCommunicationSeq()).MakeSimulatedTrivial(test, repetNr, test.Part);
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, 1, Progress.Completed));
|
||||
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(Common.Utils.GetTestName(test.Name, 1, 1), 0)));
|
||||
return new List<Event> { Event.Done };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int ConditionsCount { get { return (int)ConditionID.Count; } }
|
||||
|
||||
public string ConditionName(int i)
|
||||
{
|
||||
return (i >= 0 && i < (int)ConditionID.Count) ? ConditionOp(i).ToString() : string.Empty;
|
||||
}
|
||||
|
||||
public IOperation ConditionOp(int i)
|
||||
{
|
||||
return (i >= 0 && i < (int)ConditionID.Count) ? sequenceConditionOps[i] : null;
|
||||
}
|
||||
|
||||
|
||||
public void StartSession()
|
||||
{
|
||||
/// Clear milestones
|
||||
if (IperlCommMilestone != null)
|
||||
{
|
||||
for (int i = 0; i < IperlCommMilestone.Length; i++)
|
||||
{
|
||||
IperlCommMilestone[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveMark(object o)
|
||||
{
|
||||
/// No marks
|
||||
}
|
||||
|
||||
public void EndSession()
|
||||
{
|
||||
/// Nothing at the end of session
|
||||
}
|
||||
|
||||
public bool CheckDeviceCaps(Test test, OutputPath devices, out string message)
|
||||
{
|
||||
// Implement the method to satisfy the ITestMethod interface.
|
||||
// For now, provide a basic implementation.
|
||||
message = "Device capabilities check not implemented.";
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void MeterCommMilestone(int iItem, bool bValue)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool IsMeterCommMilestone(int iItem)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl;
|
||||
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisFullCommunication
|
||||
{
|
||||
[XmlRoot("TestMethodCfg")] // Add this attribute to match the XML root
|
||||
public class TestMethodCfg : ComponentCfgBase, ITestMethodCfg/*IComponentCfg*/
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TestMethodCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new TestMethodCfgCtrl(); }
|
||||
|
||||
//
|
||||
public override IParamsProvider GetRuntimeTestParamsProvider() { return TestParams; }
|
||||
public override IParamsProvider CreateTestParamsProvider() { return new GenesisCommunicationParams(true); }
|
||||
public override IParamsProvider GetUITestParamsProvider(Test test)
|
||||
{
|
||||
return (test.Method == Name) ? base.GetUITestParamsProvider(test) : null;
|
||||
}
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
TestMethodCfg()
|
||||
{
|
||||
Name = "GenesisFullCommunication";
|
||||
ParentName = string.Empty;
|
||||
CommTimeout = 1800; /// ms
|
||||
MaxCommRetries = 4;
|
||||
WaitTimeAfterFailure = 2200;
|
||||
PassThroughWaitTime = 1500;
|
||||
NrThreads = 2; /// 1, 2 or 4 threads
|
||||
IperlCheckErrorsToStop = 10;
|
||||
MciTimeoutMs = 4000; // ms, NFC interface
|
||||
BaudRate = 57600; // NFC Interface
|
||||
DataBits = 8; // NFC Interface
|
||||
ParityBit = Parity.None; // NFC Interface
|
||||
StopBits = StopBits.Two; // NFC Interface
|
||||
|
||||
TestParams = CreateTestParamsProvider() as GenesisCommunicationParams;
|
||||
}
|
||||
|
||||
public TestMethodCfg(IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
this.Factory = factory;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return string.Format("Name={0}, CommTimeout={1}, MaxRetries={2}, NrThreads={3}", Name, CommTimeout, MaxCommRetries, NrThreads);
|
||||
}
|
||||
|
||||
|
||||
public int DelayBetweenRetries { get; set; }
|
||||
public int MaxCommRetries { get; set; }
|
||||
public int WaitTimeAfterFailure { get; set; }
|
||||
public int PassThroughWaitTime { get; set; }
|
||||
public int NrThreads { get; set; }
|
||||
public int CommTimeout { get; set; }
|
||||
public int IperlCheckErrorsToStop { get; set; }
|
||||
public int MciTimeoutMs { get; set; }
|
||||
public int BaudRate { get; set; }
|
||||
public int DataBits { get; set; }
|
||||
public Parity ParityBit { get; set; }
|
||||
public StopBits StopBits { get; set; }
|
||||
public int DfltQ2c_15_rl { get; set; }
|
||||
public int DfltQ2c_15_lr { get; set; }
|
||||
public int DfltQ2c_20_rl { get; set; }
|
||||
public int DfltQ2c_20_lr { get; set; }
|
||||
public int DfltQ2c_25_63_rl { get; set; }
|
||||
public int DfltQ2c_25_63_lr { get; set; }
|
||||
public int DfltQ2c_25_10_rl { get; set; }
|
||||
public int DfltQ2c_25_10_lr { get; set; }
|
||||
public int DfltQ2c_32_rl { get; set; }
|
||||
public int DfltQ2c_32_lr { get; set; }
|
||||
public int DfltQ2c_40_rl { get; set; }
|
||||
public int DfltQ2c_40_lr { get; set; }
|
||||
public bool UseWebService { get; set; }
|
||||
public string BaseUrl { get; set; }
|
||||
public string RelativeUrl { get; set; }
|
||||
|
||||
///Remember to Ignore in XmlSerializer !!
|
||||
[XmlIgnore]
|
||||
public ITestParams TestParams { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisFullCommunication
|
||||
{
|
||||
public partial class TestMethodCfgCtrl : Configs.ConfigCtrlUtils, IComponentCfgCtrl
|
||||
{
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
TestMethodCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as TestMethodCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public TestMethodCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void EntryFormCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
Redraw();
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
nameTextBox.Text = config.Name;
|
||||
commTimeoutTextBox.Text = config.CommTimeout.ToString();
|
||||
maxCommRetriesTextBox.Text = config.MaxCommRetries.ToString();
|
||||
delayBetweenRetriesTextBox.Text = config.DelayBetweenRetries.ToString();
|
||||
nrThreadsTextBox.Text = config.NrThreads.ToString();
|
||||
iperlCheckErrorsToStopTextBox.Text = config.IperlCheckErrorsToStop.ToString();
|
||||
|
||||
textBox15rl.Text = config.DfltQ2c_15_rl.ToString();
|
||||
textBox15lr.Text = config.DfltQ2c_15_lr.ToString();
|
||||
textBox20rl.Text = config.DfltQ2c_20_rl.ToString();
|
||||
textBox20lr.Text = config.DfltQ2c_20_lr.ToString();
|
||||
textBox25_63rl.Text = config.DfltQ2c_25_63_rl.ToString();
|
||||
textBox25_63lr.Text = config.DfltQ2c_25_63_lr.ToString();
|
||||
textBox25_10rl.Text = config.DfltQ2c_25_10_rl.ToString();
|
||||
textBox25_10lr.Text = config.DfltQ2c_25_10_lr.ToString();
|
||||
textBox32rl.Text = config.DfltQ2c_32_rl.ToString();
|
||||
textBox32lr.Text = config.DfltQ2c_32_lr.ToString();
|
||||
textBox40rl.Text = config.DfltQ2c_40_rl.ToString();
|
||||
textBox40lr.Text = config.DfltQ2c_40_lr.ToString();
|
||||
|
||||
useWebServiceCheckBox.Checked = config.UseWebService;
|
||||
baseUrlTextBox.Text = config.BaseUrl;
|
||||
relativeUrlTextBox.Text = config.RelativeUrl;
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
commTimeoutTextBox.Enabled = true;
|
||||
maxCommRetriesTextBox.Enabled = true;
|
||||
delayBetweenRetriesTextBox.Enabled = true;
|
||||
nrThreadsTextBox.Enabled = true;
|
||||
iperlCheckErrorsToStopTextBox.Enabled = true;
|
||||
|
||||
textBox15rl.Enabled = true;
|
||||
textBox15lr.Enabled = true;
|
||||
textBox20rl.Enabled = true;
|
||||
textBox20lr.Enabled = true;
|
||||
textBox25_63rl.Enabled = true;
|
||||
textBox25_63lr.Enabled = true;
|
||||
textBox25_10rl.Enabled = true;
|
||||
textBox25_10lr.Enabled = true;
|
||||
textBox32rl.Enabled = true;
|
||||
textBox32lr.Enabled = true;
|
||||
textBox40rl.Enabled = true;
|
||||
textBox40lr.Enabled = true;
|
||||
|
||||
useWebServiceCheckBox.Enabled = true;
|
||||
ManageCheckGroupBox(useWebServiceCheckBox, useWebServiceGroupBox);
|
||||
baseUrlTextBox.Enabled = useWebServiceCheckBox.Enabled;
|
||||
relativeUrlTextBox.Enabled = useWebServiceCheckBox.Enabled;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
int dummy;
|
||||
if (!int.TryParse(commTimeoutTextBox.Text, out dummy) || dummy < 500 || dummy > 5000)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Comm. timeout' should be in range 500 .. 5000";
|
||||
}
|
||||
if (!int.TryParse(maxCommRetriesTextBox.Text, out dummy) || dummy < 1 || dummy > 10)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Max. retries' should be in range 1 .. 10";
|
||||
}
|
||||
if (!int.TryParse(delayBetweenRetriesTextBox.Text, out dummy) || dummy < 0 || dummy > 5000)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Comm. timeout' should be in range 0 .. 5000";
|
||||
}
|
||||
if (!int.TryParse(nrThreadsTextBox.Text, out dummy) || (dummy != 1 && dummy != 2 && dummy != 4))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Nr. threads' should be 1, 2 or 4";
|
||||
}
|
||||
if (!int.TryParse(iperlCheckErrorsToStopTextBox.Text, out dummy) || ((dummy < 1) && (dummy > 40)))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, iperlCheckErrorsToStopLabel.Text);
|
||||
}
|
||||
|
||||
if (!int.TryParse(textBox15rl.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN15 RL should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox15lr.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN15 LR should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox20rl.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN20 RL should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox20lr.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN20 LR should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox25_63rl.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN25 Q3 6.3 RL should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox25_63lr.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN25 Q3 6.3 LR should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox25_10rl.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN25 Q3 10 RL should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox25_10lr.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN25 Q3 10 LR should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox32rl.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN32 RL should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox32lr.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN32 LR should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox40rl.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN40 RL should be in range -50 .. 50";
|
||||
}
|
||||
if (!int.TryParse(textBox40lr.Text, out dummy) || dummy < -50 || dummy > 50)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Default Q2 correction factor DN40 LR should be in range -50 .. 50";
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
|
||||
if (config.Name != nameTextBox.Text)
|
||||
{
|
||||
config.Name = nameTextBox.Text;
|
||||
flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
}
|
||||
|
||||
var CommTimeout = config.CommTimeout;;
|
||||
var MaxCommRetries = config.MaxCommRetries;
|
||||
var DelayBetweenRetries = config.DelayBetweenRetries;
|
||||
var NrThreads = config.NrThreads;
|
||||
var IperlCheckErrorsToStop = config.IperlCheckErrorsToStop;
|
||||
var DfltQ2c_15_rl = config.DfltQ2c_15_rl;
|
||||
var DfltQ2c_15_lr = config.DfltQ2c_15_lr;
|
||||
var DfltQ2c_20_rl = config.DfltQ2c_20_rl;
|
||||
var DfltQ2c_20_lr = config.DfltQ2c_20_lr;
|
||||
var DfltQ2c_25_63_rl = config.DfltQ2c_25_63_rl;
|
||||
var DfltQ2c_25_63_lr = config.DfltQ2c_25_63_lr;
|
||||
var DfltQ2c_25_10_rl = config.DfltQ2c_25_10_rl;
|
||||
var DfltQ2c_25_10_lr = config.DfltQ2c_25_10_lr;
|
||||
var DfltQ2c_32_rl = config.DfltQ2c_32_rl;
|
||||
var DfltQ2c_32_lr = config.DfltQ2c_32_lr;
|
||||
var DfltQ2c_40_rl = config.DfltQ2c_40_rl;
|
||||
var DfltQ2c_40_lr = config.DfltQ2c_40_lr;
|
||||
var UseWebService = config.UseWebService;
|
||||
var BaseUrl = config.BaseUrl;
|
||||
var RelativeUrl = config.RelativeUrl;
|
||||
|
||||
flags |= UpdateDifferent(ref CommTimeout, commTimeoutTextBox.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref MaxCommRetries, maxCommRetriesTextBox.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DelayBetweenRetries, delayBetweenRetriesTextBox.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref NrThreads, nrThreadsTextBox.Text, CfgUpdateFlags.RestartRqrd | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref IperlCheckErrorsToStop, iperlCheckErrorsToStopTextBox.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
|
||||
flags |= UpdateDifferent(ref DfltQ2c_15_rl, textBox15rl.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_15_lr, textBox15lr.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_20_rl, textBox20rl.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_20_lr, textBox20lr.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_25_63_rl, textBox25_63rl.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_25_63_lr, textBox25_63lr.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_25_10_rl, textBox25_10rl.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_25_10_lr, textBox25_10lr.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_32_rl, textBox32rl.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_32_lr, textBox32lr.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_40_rl, textBox40rl.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref DfltQ2c_40_lr, textBox40lr.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
|
||||
flags |= UpdateDifferent(ref UseWebService, useWebServiceCheckBox.Checked, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref BaseUrl, baseUrlTextBox.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
flags |= UpdateDifferent(ref RelativeUrl, relativeUrlTextBox.Text, CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.AnyChange);
|
||||
|
||||
|
||||
config.CommTimeout = CommTimeout;
|
||||
config.MaxCommRetries = MaxCommRetries;
|
||||
config.DelayBetweenRetries = DelayBetweenRetries;
|
||||
config.NrThreads = NrThreads;
|
||||
config.IperlCheckErrorsToStop = IperlCheckErrorsToStop;
|
||||
config.DfltQ2c_15_rl = DfltQ2c_15_rl;
|
||||
config.DfltQ2c_15_lr = DfltQ2c_15_lr;
|
||||
config.DfltQ2c_20_rl = DfltQ2c_20_rl;
|
||||
config.DfltQ2c_20_lr = DfltQ2c_20_lr;
|
||||
config.DfltQ2c_25_63_rl = DfltQ2c_25_63_rl;
|
||||
config.DfltQ2c_25_63_lr = DfltQ2c_25_63_lr;
|
||||
config.DfltQ2c_25_10_rl = DfltQ2c_25_10_rl;
|
||||
config.DfltQ2c_25_10_lr = DfltQ2c_25_10_lr;
|
||||
config.DfltQ2c_32_rl = DfltQ2c_32_rl;
|
||||
config.DfltQ2c_32_lr = DfltQ2c_32_lr;
|
||||
config.DfltQ2c_40_rl = DfltQ2c_40_rl;
|
||||
config.DfltQ2c_40_lr = DfltQ2c_40_lr;
|
||||
config.UseWebService = UseWebService;
|
||||
config.BaseUrl = BaseUrl;
|
||||
config.RelativeUrl = RelativeUrl;
|
||||
|
||||
if ((flags & CfgUpdateFlags.InvokeCfgChange) != 0)
|
||||
{
|
||||
iPerlCommunication.TestMethod.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.CfgChange, config));
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
private void ManageCheckGroupBox(CheckBox chk, GroupBox grp)
|
||||
{
|
||||
/// Make sure the CheckBox isn't in the GroupBox. This will only happen the first time.
|
||||
if (chk.Parent == grp)
|
||||
{
|
||||
grp.Parent.Controls.Add(chk); /// Reparent the CheckBox so it's not in the GroupBox.
|
||||
chk.Location = new System.Drawing.Point(chk.Left + grp.Left, chk.Top + grp.Top); /// Adjust the CheckBox's location.
|
||||
chk.BringToFront(); /// Move the CheckBox to the top of the stacking order.
|
||||
}
|
||||
|
||||
/// Enable or disable the GroupBox.
|
||||
grp.Enabled = chk.Checked;
|
||||
}
|
||||
|
||||
private void useWebServiceCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
useWebServiceGroupBox.Enabled = useWebServiceCheckBox.Checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,520 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
namespace TBF.Rig.TestMethods.GenesisFullCommunication
|
||||
{
|
||||
partial class TestMethodCfgCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.commTimeoutTextBox = new System.Windows.Forms.TextBox();
|
||||
this.commTimeoutLabel = new System.Windows.Forms.Label();
|
||||
this.maxCommRetriesTextBox = new System.Windows.Forms.TextBox();
|
||||
this.maxNrRetriesLabel = new System.Windows.Forms.Label();
|
||||
this.nrThreadsTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nrThreadsLabel = new System.Windows.Forms.Label();
|
||||
this.iperlCheckErrorsToStopTextBox = new System.Windows.Forms.TextBox();
|
||||
this.iperlCheckErrorsToStopLabel = new System.Windows.Forms.Label();
|
||||
this.delayBetweenRetriesTextBox = new System.Windows.Forms.TextBox();
|
||||
this.delayBetweenRetriesLabel = new System.Windows.Forms.Label();
|
||||
this.relativeUrlTextBox = new System.Windows.Forms.TextBox();
|
||||
this.relativeUrlLabel = new System.Windows.Forms.Label();
|
||||
this.baseUrlTextBox = new System.Windows.Forms.TextBox();
|
||||
this.baseUrlLabel = new System.Windows.Forms.Label();
|
||||
this.useWebServiceCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.useWebServiceGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.dfltQ2corrFactorsGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.textBox40lr = new System.Windows.Forms.TextBox();
|
||||
this.textBox32lr = new System.Windows.Forms.TextBox();
|
||||
this.textBox25_10lr = new System.Windows.Forms.TextBox();
|
||||
this.textBox25_63lr = new System.Windows.Forms.TextBox();
|
||||
this.textBox20lr = new System.Windows.Forms.TextBox();
|
||||
this.textBox15lr = new System.Windows.Forms.TextBox();
|
||||
this.textBox40rl = new System.Windows.Forms.TextBox();
|
||||
this.textBox32rl = new System.Windows.Forms.TextBox();
|
||||
this.textBox25_10rl = new System.Windows.Forms.TextBox();
|
||||
this.textBox25_63rl = new System.Windows.Forms.TextBox();
|
||||
this.textBox20rl = new System.Windows.Forms.TextBox();
|
||||
this.textBox15rl = new System.Windows.Forms.TextBox();
|
||||
this.useWebServiceGroupBox.SuspendLayout();
|
||||
this.dfltQ2corrFactorsGroupBox.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(237, 31);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
|
||||
this.nameTextBox.TabIndex = 2;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(23, 34);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(35, 13);
|
||||
this.nameLabel.TabIndex = 1;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(234, 11);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
|
||||
this.classNameLabel.TabIndex = 0;
|
||||
this.classNameLabel.Text = "ComonentName";
|
||||
//
|
||||
// commTimeoutTextBox
|
||||
//
|
||||
this.commTimeoutTextBox.Enabled = false;
|
||||
this.commTimeoutTextBox.Location = new System.Drawing.Point(237, 53);
|
||||
this.commTimeoutTextBox.Name = "commTimeoutTextBox";
|
||||
this.commTimeoutTextBox.Size = new System.Drawing.Size(45, 20);
|
||||
this.commTimeoutTextBox.TabIndex = 4;
|
||||
//
|
||||
// commTimeoutLabel
|
||||
//
|
||||
this.commTimeoutLabel.AutoSize = true;
|
||||
this.commTimeoutLabel.Location = new System.Drawing.Point(23, 56);
|
||||
this.commTimeoutLabel.Name = "commTimeoutLabel";
|
||||
this.commTimeoutLabel.Size = new System.Drawing.Size(98, 13);
|
||||
this.commTimeoutLabel.TabIndex = 3;
|
||||
this.commTimeoutLabel.Text = "Comm. timeout [ms]";
|
||||
//
|
||||
// maxCommRetriesTextBox
|
||||
//
|
||||
this.maxCommRetriesTextBox.Enabled = false;
|
||||
this.maxCommRetriesTextBox.Location = new System.Drawing.Point(237, 75);
|
||||
this.maxCommRetriesTextBox.Name = "maxCommRetriesTextBox";
|
||||
this.maxCommRetriesTextBox.Size = new System.Drawing.Size(45, 20);
|
||||
this.maxCommRetriesTextBox.TabIndex = 6;
|
||||
//
|
||||
// maxNrRetriesLabel
|
||||
//
|
||||
this.maxNrRetriesLabel.AutoSize = true;
|
||||
this.maxNrRetriesLabel.Location = new System.Drawing.Point(23, 78);
|
||||
this.maxNrRetriesLabel.Name = "maxNrRetriesLabel";
|
||||
this.maxNrRetriesLabel.Size = new System.Drawing.Size(61, 13);
|
||||
this.maxNrRetriesLabel.TabIndex = 5;
|
||||
this.maxNrRetriesLabel.Text = "Max. retries";
|
||||
//
|
||||
// nrThreadsTextBox
|
||||
//
|
||||
this.nrThreadsTextBox.Enabled = false;
|
||||
this.nrThreadsTextBox.Location = new System.Drawing.Point(237, 119);
|
||||
this.nrThreadsTextBox.Name = "nrThreadsTextBox";
|
||||
this.nrThreadsTextBox.Size = new System.Drawing.Size(45, 20);
|
||||
this.nrThreadsTextBox.TabIndex = 10;
|
||||
//
|
||||
// nrThreadsLabel
|
||||
//
|
||||
this.nrThreadsLabel.AutoSize = true;
|
||||
this.nrThreadsLabel.Location = new System.Drawing.Point(23, 122);
|
||||
this.nrThreadsLabel.Name = "nrThreadsLabel";
|
||||
this.nrThreadsLabel.Size = new System.Drawing.Size(59, 13);
|
||||
this.nrThreadsLabel.TabIndex = 9;
|
||||
this.nrThreadsLabel.Text = "Nr. threads";
|
||||
//
|
||||
// iperlCheckErrorsToStopTextBox
|
||||
//
|
||||
this.iperlCheckErrorsToStopTextBox.Enabled = false;
|
||||
this.iperlCheckErrorsToStopTextBox.Location = new System.Drawing.Point(237, 141);
|
||||
this.iperlCheckErrorsToStopTextBox.Name = "iperlCheckErrorsToStopTextBox";
|
||||
this.iperlCheckErrorsToStopTextBox.Size = new System.Drawing.Size(45, 20);
|
||||
this.iperlCheckErrorsToStopTextBox.TabIndex = 13;
|
||||
//
|
||||
// iperlCheckErrorsToStopLabel
|
||||
//
|
||||
this.iperlCheckErrorsToStopLabel.AutoSize = true;
|
||||
this.iperlCheckErrorsToStopLabel.Location = new System.Drawing.Point(23, 144);
|
||||
this.iperlCheckErrorsToStopLabel.Name = "iperlCheckErrorsToStopLabel";
|
||||
this.iperlCheckErrorsToStopLabel.Size = new System.Drawing.Size(202, 13);
|
||||
this.iperlCheckErrorsToStopLabel.TabIndex = 12;
|
||||
this.iperlCheckErrorsToStopLabel.Text = "iperl_check errors count to stop the cycle";
|
||||
//
|
||||
// delayBetweenRetriesTextBox
|
||||
//
|
||||
this.delayBetweenRetriesTextBox.Enabled = false;
|
||||
this.delayBetweenRetriesTextBox.Location = new System.Drawing.Point(237, 97);
|
||||
this.delayBetweenRetriesTextBox.Name = "delayBetweenRetriesTextBox";
|
||||
this.delayBetweenRetriesTextBox.Size = new System.Drawing.Size(45, 20);
|
||||
this.delayBetweenRetriesTextBox.TabIndex = 8;
|
||||
//
|
||||
// delayBetweenRetriesLabel
|
||||
//
|
||||
this.delayBetweenRetriesLabel.AutoSize = true;
|
||||
this.delayBetweenRetriesLabel.Location = new System.Drawing.Point(23, 100);
|
||||
this.delayBetweenRetriesLabel.Name = "delayBetweenRetriesLabel";
|
||||
this.delayBetweenRetriesLabel.Size = new System.Drawing.Size(131, 13);
|
||||
this.delayBetweenRetriesLabel.TabIndex = 7;
|
||||
this.delayBetweenRetriesLabel.Text = "Delay between retries [ms]";
|
||||
//
|
||||
// relativeUrlTextBox
|
||||
//
|
||||
this.relativeUrlTextBox.Enabled = false;
|
||||
this.relativeUrlTextBox.Location = new System.Drawing.Point(89, 50);
|
||||
this.relativeUrlTextBox.Name = "relativeUrlTextBox";
|
||||
this.relativeUrlTextBox.Size = new System.Drawing.Size(298, 20);
|
||||
this.relativeUrlTextBox.TabIndex = 18;
|
||||
//
|
||||
// relativeUrlLabel
|
||||
//
|
||||
this.relativeUrlLabel.AutoSize = true;
|
||||
this.relativeUrlLabel.Location = new System.Drawing.Point(13, 53);
|
||||
this.relativeUrlLabel.Name = "relativeUrlLabel";
|
||||
this.relativeUrlLabel.Size = new System.Drawing.Size(71, 13);
|
||||
this.relativeUrlLabel.TabIndex = 17;
|
||||
this.relativeUrlLabel.Text = "Relative URL";
|
||||
//
|
||||
// baseUrlTextBox
|
||||
//
|
||||
this.baseUrlTextBox.Enabled = false;
|
||||
this.baseUrlTextBox.Location = new System.Drawing.Point(89, 24);
|
||||
this.baseUrlTextBox.Name = "baseUrlTextBox";
|
||||
this.baseUrlTextBox.Size = new System.Drawing.Size(298, 20);
|
||||
this.baseUrlTextBox.TabIndex = 16;
|
||||
//
|
||||
// baseUrlLabel
|
||||
//
|
||||
this.baseUrlLabel.AutoSize = true;
|
||||
this.baseUrlLabel.Location = new System.Drawing.Point(13, 27);
|
||||
this.baseUrlLabel.Name = "baseUrlLabel";
|
||||
this.baseUrlLabel.Size = new System.Drawing.Size(56, 13);
|
||||
this.baseUrlLabel.TabIndex = 15;
|
||||
this.baseUrlLabel.Text = "Base URL";
|
||||
//
|
||||
// useWebServiceCheckBox
|
||||
//
|
||||
this.useWebServiceCheckBox.AutoSize = true;
|
||||
this.useWebServiceCheckBox.Enabled = false;
|
||||
this.useWebServiceCheckBox.Location = new System.Drawing.Point(15, 0);
|
||||
this.useWebServiceCheckBox.Name = "useWebServiceCheckBox";
|
||||
this.useWebServiceCheckBox.Size = new System.Drawing.Size(189, 17);
|
||||
this.useWebServiceCheckBox.TabIndex = 14;
|
||||
this.useWebServiceCheckBox.Text = "Use web service for default values";
|
||||
this.useWebServiceCheckBox.UseVisualStyleBackColor = true;
|
||||
this.useWebServiceCheckBox.CheckedChanged += new System.EventHandler(this.useWebServiceCheckBox_CheckedChanged);
|
||||
//
|
||||
// useWebServiceGroupBox
|
||||
//
|
||||
this.useWebServiceGroupBox.Controls.Add(this.baseUrlTextBox);
|
||||
this.useWebServiceGroupBox.Controls.Add(this.useWebServiceCheckBox);
|
||||
this.useWebServiceGroupBox.Controls.Add(this.relativeUrlTextBox);
|
||||
this.useWebServiceGroupBox.Controls.Add(this.relativeUrlLabel);
|
||||
this.useWebServiceGroupBox.Controls.Add(this.baseUrlLabel);
|
||||
this.useWebServiceGroupBox.Location = new System.Drawing.Point(11, 266);
|
||||
this.useWebServiceGroupBox.Name = "useWebServiceGroupBox";
|
||||
this.useWebServiceGroupBox.Size = new System.Drawing.Size(404, 83);
|
||||
this.useWebServiceGroupBox.TabIndex = 0;
|
||||
this.useWebServiceGroupBox.TabStop = false;
|
||||
//
|
||||
// dfltQ2corrFactorsGroupBox
|
||||
//
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.label8);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.label7);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.label6);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.label5);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.label4);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.label3);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.label2);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.label1);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox40lr);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox32lr);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox25_10lr);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox25_63lr);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox20lr);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox15lr);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox40rl);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox32rl);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox25_10rl);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox25_63rl);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox20rl);
|
||||
this.dfltQ2corrFactorsGroupBox.Controls.Add(this.textBox15rl);
|
||||
this.dfltQ2corrFactorsGroupBox.Location = new System.Drawing.Point(11, 175);
|
||||
this.dfltQ2corrFactorsGroupBox.Name = "dfltQ2corrFactorsGroupBox";
|
||||
this.dfltQ2corrFactorsGroupBox.Size = new System.Drawing.Size(404, 85);
|
||||
this.dfltQ2corrFactorsGroupBox.TabIndex = 14;
|
||||
this.dfltQ2corrFactorsGroupBox.TabStop = false;
|
||||
this.dfltQ2corrFactorsGroupBox.Text = "Default Q2 correction factors";
|
||||
//
|
||||
// label8
|
||||
//
|
||||
this.label8.AutoSize = true;
|
||||
this.label8.Location = new System.Drawing.Point(344, 17);
|
||||
this.label8.Name = "label8";
|
||||
this.label8.Size = new System.Drawing.Size(35, 13);
|
||||
this.label8.TabIndex = 19;
|
||||
this.label8.Text = "DN40";
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Location = new System.Drawing.Point(289, 17);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(35, 13);
|
||||
this.label7.TabIndex = 18;
|
||||
this.label7.Text = "DN32";
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(233, 17);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(45, 13);
|
||||
this.label6.TabIndex = 17;
|
||||
this.label6.Text = "...Q3 10";
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(163, 17);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(70, 13);
|
||||
this.label5.TabIndex = 16;
|
||||
this.label5.Text = "DN25 Q3 6.3";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(121, 17);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(35, 13);
|
||||
this.label4.TabIndex = 15;
|
||||
this.label4.Text = "DN20";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(65, 17);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(35, 13);
|
||||
this.label3.TabIndex = 14;
|
||||
this.label3.Text = "DN15";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(22, 57);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(24, 13);
|
||||
this.label2.TabIndex = 13;
|
||||
this.label2.Text = "L-R";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(22, 34);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(24, 13);
|
||||
this.label1.TabIndex = 12;
|
||||
this.label1.Text = "R-L";
|
||||
//
|
||||
// textBox40lr
|
||||
//
|
||||
this.textBox40lr.Enabled = false;
|
||||
this.textBox40lr.Location = new System.Drawing.Point(337, 54);
|
||||
this.textBox40lr.Name = "textBox40lr";
|
||||
this.textBox40lr.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox40lr.TabIndex = 11;
|
||||
//
|
||||
// textBox32lr
|
||||
//
|
||||
this.textBox32lr.Enabled = false;
|
||||
this.textBox32lr.Location = new System.Drawing.Point(281, 54);
|
||||
this.textBox32lr.Name = "textBox32lr";
|
||||
this.textBox32lr.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox32lr.TabIndex = 10;
|
||||
//
|
||||
// textBox25_10lr
|
||||
//
|
||||
this.textBox25_10lr.Enabled = false;
|
||||
this.textBox25_10lr.Location = new System.Drawing.Point(225, 54);
|
||||
this.textBox25_10lr.Name = "textBox25_10lr";
|
||||
this.textBox25_10lr.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox25_10lr.TabIndex = 9;
|
||||
//
|
||||
// textBox25_63lr
|
||||
//
|
||||
this.textBox25_63lr.Enabled = false;
|
||||
this.textBox25_63lr.Location = new System.Drawing.Point(169, 54);
|
||||
this.textBox25_63lr.Name = "textBox25_63lr";
|
||||
this.textBox25_63lr.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox25_63lr.TabIndex = 8;
|
||||
//
|
||||
// textBox20lr
|
||||
//
|
||||
this.textBox20lr.Enabled = false;
|
||||
this.textBox20lr.Location = new System.Drawing.Point(113, 54);
|
||||
this.textBox20lr.Name = "textBox20lr";
|
||||
this.textBox20lr.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox20lr.TabIndex = 7;
|
||||
//
|
||||
// textBox15lr
|
||||
//
|
||||
this.textBox15lr.Enabled = false;
|
||||
this.textBox15lr.Location = new System.Drawing.Point(57, 54);
|
||||
this.textBox15lr.Name = "textBox15lr";
|
||||
this.textBox15lr.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox15lr.TabIndex = 6;
|
||||
//
|
||||
// textBox40rl
|
||||
//
|
||||
this.textBox40rl.Enabled = false;
|
||||
this.textBox40rl.Location = new System.Drawing.Point(337, 31);
|
||||
this.textBox40rl.Name = "textBox40rl";
|
||||
this.textBox40rl.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox40rl.TabIndex = 5;
|
||||
//
|
||||
// textBox32rl
|
||||
//
|
||||
this.textBox32rl.Enabled = false;
|
||||
this.textBox32rl.Location = new System.Drawing.Point(281, 31);
|
||||
this.textBox32rl.Name = "textBox32rl";
|
||||
this.textBox32rl.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox32rl.TabIndex = 4;
|
||||
//
|
||||
// textBox25_10rl
|
||||
//
|
||||
this.textBox25_10rl.Enabled = false;
|
||||
this.textBox25_10rl.Location = new System.Drawing.Point(225, 31);
|
||||
this.textBox25_10rl.Name = "textBox25_10rl";
|
||||
this.textBox25_10rl.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox25_10rl.TabIndex = 3;
|
||||
//
|
||||
// textBox25_63rl
|
||||
//
|
||||
this.textBox25_63rl.Enabled = false;
|
||||
this.textBox25_63rl.Location = new System.Drawing.Point(169, 31);
|
||||
this.textBox25_63rl.Name = "textBox25_63rl";
|
||||
this.textBox25_63rl.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox25_63rl.TabIndex = 2;
|
||||
//
|
||||
// textBox20rl
|
||||
//
|
||||
this.textBox20rl.Enabled = false;
|
||||
this.textBox20rl.Location = new System.Drawing.Point(113, 31);
|
||||
this.textBox20rl.Name = "textBox20rl";
|
||||
this.textBox20rl.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox20rl.TabIndex = 1;
|
||||
//
|
||||
// textBox15rl
|
||||
//
|
||||
this.textBox15rl.Enabled = false;
|
||||
this.textBox15rl.Location = new System.Drawing.Point(57, 31);
|
||||
this.textBox15rl.Name = "textBox15rl";
|
||||
this.textBox15rl.Size = new System.Drawing.Size(50, 20);
|
||||
this.textBox15rl.TabIndex = 0;
|
||||
//
|
||||
// TestMethodCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.dfltQ2corrFactorsGroupBox);
|
||||
this.Controls.Add(this.useWebServiceGroupBox);
|
||||
this.Controls.Add(this.delayBetweenRetriesTextBox);
|
||||
this.Controls.Add(this.delayBetweenRetriesLabel);
|
||||
this.Controls.Add(this.iperlCheckErrorsToStopTextBox);
|
||||
this.Controls.Add(this.iperlCheckErrorsToStopLabel);
|
||||
this.Controls.Add(this.nrThreadsTextBox);
|
||||
this.Controls.Add(this.nrThreadsLabel);
|
||||
this.Controls.Add(this.maxCommRetriesTextBox);
|
||||
this.Controls.Add(this.maxNrRetriesLabel);
|
||||
this.Controls.Add(this.commTimeoutTextBox);
|
||||
this.Controls.Add(this.commTimeoutLabel);
|
||||
this.Controls.Add(this.nameTextBox);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
this.Controls.Add(this.classNameLabel);
|
||||
this.Name = "TestMethodCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(427, 363);
|
||||
this.Load += new System.EventHandler(this.EntryFormCfgCtrl_Load);
|
||||
this.useWebServiceGroupBox.ResumeLayout(false);
|
||||
this.useWebServiceGroupBox.PerformLayout();
|
||||
this.dfltQ2corrFactorsGroupBox.ResumeLayout(false);
|
||||
this.dfltQ2corrFactorsGroupBox.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
private System.Windows.Forms.TextBox commTimeoutTextBox;
|
||||
private System.Windows.Forms.Label commTimeoutLabel;
|
||||
private System.Windows.Forms.TextBox maxCommRetriesTextBox;
|
||||
private System.Windows.Forms.Label maxNrRetriesLabel;
|
||||
private System.Windows.Forms.TextBox nrThreadsTextBox;
|
||||
private System.Windows.Forms.Label nrThreadsLabel;
|
||||
private System.Windows.Forms.TextBox iperlCheckErrorsToStopTextBox;
|
||||
private System.Windows.Forms.Label iperlCheckErrorsToStopLabel;
|
||||
private System.Windows.Forms.TextBox delayBetweenRetriesTextBox;
|
||||
private System.Windows.Forms.Label delayBetweenRetriesLabel;
|
||||
private System.Windows.Forms.TextBox relativeUrlTextBox;
|
||||
private System.Windows.Forms.Label relativeUrlLabel;
|
||||
private System.Windows.Forms.TextBox baseUrlTextBox;
|
||||
private System.Windows.Forms.Label baseUrlLabel;
|
||||
private System.Windows.Forms.CheckBox useWebServiceCheckBox;
|
||||
private System.Windows.Forms.GroupBox useWebServiceGroupBox;
|
||||
private System.Windows.Forms.GroupBox dfltQ2corrFactorsGroupBox;
|
||||
private System.Windows.Forms.Label label8;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.Label label6;
|
||||
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.TextBox textBox40lr;
|
||||
private System.Windows.Forms.TextBox textBox32lr;
|
||||
private System.Windows.Forms.TextBox textBox25_10lr;
|
||||
private System.Windows.Forms.TextBox textBox25_63lr;
|
||||
private System.Windows.Forms.TextBox textBox20lr;
|
||||
private System.Windows.Forms.TextBox textBox15lr;
|
||||
private System.Windows.Forms.TextBox textBox40rl;
|
||||
private System.Windows.Forms.TextBox textBox32rl;
|
||||
private System.Windows.Forms.TextBox textBox25_10rl;
|
||||
private System.Windows.Forms.TextBox textBox25_63rl;
|
||||
private System.Windows.Forms.TextBox textBox20rl;
|
||||
private System.Windows.Forms.TextBox textBox15rl;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -6,20 +6,21 @@ using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return GetType().Namespace.Substring(12); } }
|
||||
public override string ToString() { return ClassName; }
|
||||
|
||||
public IComponent DummyComponent() { return new FlowMeter(); }
|
||||
public IComponent DummyComponent() { return new FlowMeter(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new FlowMeter(cfg, components); }
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new FlowMeter(cfg, components); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new FlowMeterCfg(this, "I11+I12"); }
|
||||
public IComponentCfg DefaultConfig() { return new FlowMeterCfg(this, "I11+I12"); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(FlowMeterCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(FlowMeterCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using SchematicDrawing;
|
||||
using SharedComponents;
|
||||
using TBF.Boxes;
|
||||
using TBF.Rig.ControlBoard.Uni;
|
||||
using TBF.Rig.GenericDevices;
|
||||
@@ -12,17 +13,16 @@ using TBF.Rig.GenericDevices;
|
||||
namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
{
|
||||
public class FlowMeter : ComponentBase, IFlowMeter, IDrawingItCmpntWithMeasuredVal
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(FlowMeter));
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(FlowMeter));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
readonly FlowMeterCfg myCfg;
|
||||
readonly FlowMeterCfg flowMeterCfg;
|
||||
|
||||
UniCB uniCB;
|
||||
IFlowMeterSingle flowMtr1;
|
||||
IFlowMeterSingle flowMtr2;
|
||||
IFlowMeterSingle flowMtr3;
|
||||
IFlowMeterSingle inactiveFlowMtr;
|
||||
double nominalFlow;
|
||||
double nominalFreq;
|
||||
double ltrPerPulse;
|
||||
@@ -34,22 +34,20 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
public double NominalFreq { get { return nominalFreq; } }
|
||||
public double LtrPerPulse { get { return ltrPerPulse; } }
|
||||
|
||||
public SchematicDrawing.IDrawingItem DrawingItem { get { return myCfg as SchematicDrawing.IDrawingItem; } }
|
||||
public string MsrdFormat { get { return myCfg.MsrdFormat; } }
|
||||
public Common.Unit MsrdUnit { get { return myCfg.MsrdUnit; } }
|
||||
public double MsrdValLimLo { get { return myCfg.MsrdValLimLo; } set { myCfg.MsrdValLimLo = value; } }
|
||||
public double MsrdValLimHi { get { return myCfg.MsrdValLimHi; } set { myCfg.MsrdValLimHi = value; } }
|
||||
|
||||
public SchematicDrawing.IDrawingItem DrawingItem { get { return flowMeterCfg as SchematicDrawing.IDrawingItem; } }
|
||||
public string MsrdFormat { get { return flowMeterCfg.MsrdFormat; } }
|
||||
public Common.Unit MsrdUnit { get { return flowMeterCfg.MsrdUnit; } }
|
||||
public double MsrdValLimLo { get { return flowMeterCfg.MsrdValLimLo; } set { flowMeterCfg.MsrdValLimLo = value; } }
|
||||
public double MsrdValLimHi { get { return flowMeterCfg.MsrdValLimHi; } set { flowMeterCfg.MsrdValLimHi = value; } }
|
||||
|
||||
public bool MsrmntAvailable
|
||||
{
|
||||
get
|
||||
{
|
||||
bool result = true;
|
||||
if (flowMtr1 != null) result = (result && flowMtr1.MsrmntAvailable);
|
||||
if (flowMtr2 != null) result = (result && flowMtr2.MsrmntAvailable);
|
||||
if (flowMtr3 != null) result = (result && flowMtr3.MsrmntAvailable);
|
||||
if (inactiveFlowMtr != null) result = (result && !inactiveFlowMtr.MsrmntAvailable);
|
||||
if (flowMtr1 != null) result = result && flowMtr1.MsrmntAvailable;
|
||||
if (flowMtr2 != null) result = result && flowMtr2.MsrmntAvailable;
|
||||
if (flowMtr3 != null) result = result && flowMtr3.MsrmntAvailable;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -61,24 +59,22 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
|
||||
public string AltString { get { return "Invalid format"; } }
|
||||
|
||||
public FlowMeter() { }
|
||||
|
||||
public FlowMeter() { }
|
||||
|
||||
public FlowMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
{
|
||||
myCfg = cfg as FlowMeterCfg;
|
||||
}
|
||||
public FlowMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
{
|
||||
flowMeterCfg = cfg as FlowMeterCfg;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
uniCB = TbfComponents.FindComponent(myCfg.ParentName) as UniCB;
|
||||
uniCB = TbfComponents.FindComponent(flowMeterCfg.ParentName) as UniCB;
|
||||
if (uniCB == null) throw new Exception("Cannot find " + Name + " parent");
|
||||
|
||||
if (!string.IsNullOrEmpty(myCfg.Flowmeter1)) flowMtr1 = TbfComponents.FindComponent(myCfg.Flowmeter1) as IFlowMeterSingle;
|
||||
if (!string.IsNullOrEmpty(myCfg.Flowmeter2)) flowMtr2 = TbfComponents.FindComponent(myCfg.Flowmeter2) as IFlowMeterSingle;
|
||||
if (!string.IsNullOrEmpty(myCfg.Flowmeter3)) flowMtr3 = TbfComponents.FindComponent(myCfg.Flowmeter3) as IFlowMeterSingle;
|
||||
if (!string.IsNullOrEmpty(myCfg.InactiveFlowmtr)) inactiveFlowMtr = TbfComponents.FindComponent(myCfg.InactiveFlowmtr) as IFlowMeterSingle;
|
||||
if (!string.IsNullOrEmpty(flowMeterCfg.Flowmeter1)) flowMtr1 = TbfComponents.FindComponent(flowMeterCfg.Flowmeter1) as IFlowMeterSingle;
|
||||
if (!string.IsNullOrEmpty(flowMeterCfg.Flowmeter2)) flowMtr2 = TbfComponents.FindComponent(flowMeterCfg.Flowmeter2) as IFlowMeterSingle;
|
||||
if (!string.IsNullOrEmpty(flowMeterCfg.Flowmeter3)) flowMtr3 = TbfComponents.FindComponent(flowMeterCfg.Flowmeter3) as IFlowMeterSingle;
|
||||
|
||||
nominalFlow = 0;
|
||||
flowMetersCount = 0;
|
||||
@@ -91,8 +87,8 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
flowMetersBitfield |= (4 << flowMtr1.Idx1);
|
||||
flowMetersCount++;
|
||||
}
|
||||
if (flowMtr2 != null)
|
||||
{
|
||||
if (flowMtr2 != null)
|
||||
{
|
||||
nominalFlow += flowMtr2.NominalFlow;
|
||||
nominalFreq += flowMtr2.NominalFreq;
|
||||
flowMetersBitfield |= (4 << flowMtr2.Idx1);
|
||||
@@ -109,15 +105,31 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
|
||||
MsrdValLimHi = nominalFlow;
|
||||
|
||||
nominalFreq = nominalFreq / flowMetersCount;
|
||||
|
||||
ltrPerPulse = nominalFlow / (3.6 * nominalFreq); /// Nominal freq. is sum of particular nominal frquencies
|
||||
|
||||
log.FatalFormat("{0} initialized: {1} nom.flow={2} m3/h nom.freq={3} Hz bitfield=0x{4:X2}",
|
||||
Name, this, nominalFlow, nominalFreq, flowMetersBitfield);
|
||||
Name, true, nominalFlow, nominalFreq, flowMetersBitfield);
|
||||
}
|
||||
|
||||
public double ReadFlow()
|
||||
{
|
||||
return ReadFrequency() * nominalFlow / nominalFreq;
|
||||
double flowByNewFormulaSum = 0;
|
||||
|
||||
if (flowMtr1 != null)
|
||||
{
|
||||
flowByNewFormulaSum += flowMtr1.NominalFlow * uniCB.Data.ReferenceFreq[1] / flowMtr1.NominalFreq;
|
||||
}
|
||||
if (flowMtr2 != null)
|
||||
{
|
||||
flowByNewFormulaSum += flowMtr2.NominalFlow * uniCB.Data.ReferenceFreq[2] / flowMtr2.NominalFreq;
|
||||
}
|
||||
if (flowMtr3 != null)
|
||||
{
|
||||
flowByNewFormulaSum += flowMtr3.NominalFlow * uniCB.Data.ReferenceFreq[3] / flowMtr3.NominalFreq;
|
||||
}
|
||||
return flowByNewFormulaSum/*ReadFrequency() * nominalFlow / nominalFreq*/;
|
||||
}
|
||||
|
||||
public double ReadFrequency()
|
||||
@@ -125,27 +137,26 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
return uniCB.RefFrequency;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events: FlowDone, Error
|
||||
/// </summary>
|
||||
/// <param name="flow">Reference to a variable for the flow in Bar</param>
|
||||
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
|
||||
public IOperation ReadFlowOp(ref DoubleBox flow)
|
||||
{
|
||||
return new ReadFlowOp(this, ref flow);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events: flowDone, Error
|
||||
/// </summary>
|
||||
/// <param name="flow">Reference to a variable for the flow in Bar</param>
|
||||
/// <param name="flowDone">Event returned when measurement done</param>
|
||||
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
|
||||
public IOperation ReadFlowOp(ref DoubleBox flow, Event flowDone)
|
||||
{
|
||||
return new ReadFlowOp(this, ref flow, flowDone);
|
||||
}
|
||||
/// <summary>
|
||||
/// Events: FlowDone, Error
|
||||
/// </summary>
|
||||
/// <param name="flow">Reference to a variable for the flow in Bar</param>
|
||||
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
|
||||
public IOperation ReadFlowOp(ref DoubleBox flow)
|
||||
{
|
||||
return new ReadFlowOp(this, ref flow);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Events: flowDone, Error
|
||||
/// </summary>
|
||||
/// <param name="flow">Reference to a variable for the flow in Bar</param>
|
||||
/// <param name="flowDone">Event returned when measurement done</param>
|
||||
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
|
||||
public IOperation ReadFlowOp(ref DoubleBox flow, Event flowDone)
|
||||
{
|
||||
return new ReadFlowOp(this, ref flow, flowDone);
|
||||
}
|
||||
|
||||
double flowRawSum;
|
||||
double flowSum;
|
||||
@@ -197,7 +208,7 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
public double LtrPerPulseCorrected(double flow, float temperature)
|
||||
{
|
||||
double ltrPerPulseCorrected = (flowRawSum == 0) ? LtrPerPulse : LtrPerPulse * flowSum / flowRawSum;
|
||||
log.WarnFormat("LtrPerPulseCorrected() flow = {0:F3} m3/h flowRawSum = {1:F3} m3/h flowSum = {2:F3} m3/h temperature = {3:F1} C ltrPerPulseCorrected = {4}", flow, flowRawSum, flowSum, temperature, ltrPerPulseCorrected);
|
||||
log.WarnFormat("LtrPerPulseCorrected() flow = {0} m3/h flowRawSum = {1} m3/h flowSum = {2} m3/h temperature = {3} C ltrPerPulseCorrected = {4}", flow, flowRawSum, flowSum, temperature, ltrPerPulseCorrected);
|
||||
return ltrPerPulseCorrected;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ using TBF.Rig.Generic;
|
||||
namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
{
|
||||
public class FlowMeterCfg : ComponentCfgBase, IChildComponentCfg, IParamsProvider, IDrawingItemWithMeasuredVal
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(FlowMeterCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(FlowMeterCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities)
|
||||
{
|
||||
@@ -24,15 +24,14 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
return new Configs.ParamsProvider.ComponentCfgCtrl(this, parents);
|
||||
}
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public string Flowmeter1; /// 0 Flowmeter component name or string.Empty
|
||||
public string Flowmeter2; /// 1 - ' ' -
|
||||
public string Flowmeter3; /// 2 - ' ' -
|
||||
public string InactiveFlowmtr; /// 3 Inactive flowmeter component name or string.Empty
|
||||
public string MsrdFormat { get; set; } /// 4
|
||||
public Unit MsrdUnit { get; set; } /// 5
|
||||
public string MsrdFormat { get; set; } /// 3
|
||||
public Unit MsrdUnit { get; set; } /// 4
|
||||
|
||||
/// Schematic drawing info
|
||||
public Shape Shape { get; set; }
|
||||
@@ -58,9 +57,6 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
|
||||
private IEnumerable<Config.Entities.Component> flowMeters;
|
||||
|
||||
[XmlIgnore]
|
||||
public bool IsOffline { get; set; }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
FlowMeterCfg()
|
||||
{
|
||||
@@ -82,12 +78,13 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
|
||||
public string ComponentName { get { return Name; } }
|
||||
|
||||
public bool IsOffline { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public void InitializeAll()
|
||||
{
|
||||
Flowmeter1 = "I11";
|
||||
Flowmeter2 = "I12";
|
||||
Flowmeter3 = string.Empty;
|
||||
InactiveFlowmtr = "I13";
|
||||
MsrdFormat = "{0:F3} m3/h";
|
||||
MsrdUnit = Unit.m3ph;
|
||||
}
|
||||
@@ -97,9 +94,8 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
"Flow meter 1", /// 0
|
||||
"Flow meter 2", /// 1
|
||||
"Flow meter 3", /// 2
|
||||
"Inactive flow meter", /// 3
|
||||
"Display format", /// 4
|
||||
"Unit of flow on a display", /// 5
|
||||
"Display format", /// 3
|
||||
"Unit of flow on a display", /// 4
|
||||
};
|
||||
public string ParamName(int i) { return paramNames[i]; }
|
||||
public int ParamsCount() { return paramNames.Length; }
|
||||
@@ -111,48 +107,44 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
if (flowMeters == null) return null;
|
||||
var fmtrs = new List<string>();
|
||||
foreach (var fmtr in flowMeters) fmtrs.Add(fmtr.Name);
|
||||
fmtrs.Add("---");
|
||||
return fmtrs;
|
||||
case 5:
|
||||
return new string[] { "m3/h", "l/h", "gal/m" };
|
||||
case 4:
|
||||
return new string[] { "m3/h", "l/h" };
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
public string ToString(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: return string.IsNullOrEmpty(Flowmeter1) ? "---" : Flowmeter1;
|
||||
case 1: return string.IsNullOrEmpty(Flowmeter2) ? "---" : Flowmeter2;
|
||||
case 2: return string.IsNullOrEmpty(Flowmeter3) ? "---" : Flowmeter3;
|
||||
case 3: return string.IsNullOrEmpty(InactiveFlowmtr) ? "---" : InactiveFlowmtr;
|
||||
case 4: return MsrdFormat;
|
||||
case 5: return MsrdUnit.ToDescription();
|
||||
case 3: return MsrdFormat;
|
||||
case 4: return MsrdUnit.ToDescription();
|
||||
|
||||
default:
|
||||
return string.Format("Name={0} {1} {2} {3} ~{4} fmt={5} unit={6} Lo={7} Hi={8}",
|
||||
Name, Flowmeter1, Flowmeter2, Flowmeter3, InactiveFlowmtr,
|
||||
return string.Format("Name={0} {1} {2} {3} fmt={4} unit={5} Lo={6} Hi={7}",
|
||||
Name, Flowmeter1, Flowmeter2, Flowmeter3,
|
||||
MsrdFormat, MsrdUnit.ToDescription(), MsrdValLimLo, MsrdValLimHi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateParam(int i, string str)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: Flowmeter1 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
|
||||
case 1: Flowmeter2 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
|
||||
case 2: Flowmeter3 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
|
||||
case 3: InactiveFlowmtr = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
|
||||
case 4: MsrdFormat = str; return CfgUpdateFlags.RestartRqrd;
|
||||
//case 5: MsrdUnit = (str == "l/h") ? Unit.lph : Unit.m3ph; return CfgUpdateFlags.RestartRqrd;
|
||||
case 5: MsrdUnit = ParseFlowUnit(str); return CfgUpdateFlags.RestartRqrd;
|
||||
case 0: Flowmeter1 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
|
||||
case 1: Flowmeter2 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
|
||||
case 2: Flowmeter3 = (str != "---") ? str : string.Empty; return CfgUpdateFlags.RestartRqrd;
|
||||
case 3: MsrdFormat = str; return CfgUpdateFlags.RestartRqrd;
|
||||
case 4: MsrdUnit = (str == "l/h") ? Unit.lph : Unit.m3ph; return CfgUpdateFlags.RestartRqrd;
|
||||
default:
|
||||
return CfgUpdateFlags.None;
|
||||
}
|
||||
@@ -167,11 +159,10 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
case 4:
|
||||
if (ParamValues(i).Contains(str)) return true;
|
||||
break;
|
||||
case 4:
|
||||
case 3:
|
||||
return true;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
@@ -187,7 +178,6 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
prms.Flowmeter1 = this.Flowmeter1;
|
||||
prms.Flowmeter2 = this.Flowmeter2;
|
||||
prms.Flowmeter3 = this.Flowmeter3;
|
||||
prms.InactiveFlowmtr = this.InactiveFlowmtr;
|
||||
prms.MsrdFormat = this.MsrdFormat;
|
||||
prms.MsrdUnit = this.MsrdUnit;
|
||||
}
|
||||
@@ -203,19 +193,5 @@ namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
{
|
||||
return true; /// =OK, do nothing
|
||||
}
|
||||
public static Unit ParseFlowUnit(string str)
|
||||
{
|
||||
//Check if the string is a valid unit description
|
||||
Unit fromDescription = Units.FromDescription(str);
|
||||
if (fromDescription != Unit.None) return fromDescription;
|
||||
//check if the string is a valid unit name
|
||||
switch (str)
|
||||
{
|
||||
case "l/h": return Unit.lph;
|
||||
case "gal/m": return Unit.USgalpm;
|
||||
case "m3/h":
|
||||
default: return Unit.m3ph;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,57 +8,57 @@ using TBF.Rig.GenericDevices;
|
||||
|
||||
namespace TBF.Rig.Uni.FlowMetersInParallel
|
||||
{
|
||||
public class ReadFlowOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(ReadFlowOp));
|
||||
public class ReadFlowOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(ReadFlowOp));
|
||||
public override string ToString() { return string.Format("ReadFlowOp({0},.,.,{1})", flowMeter.Idx1, eventDone); }
|
||||
|
||||
/// Set by the constructor
|
||||
/// Set by the constructor
|
||||
readonly IFlowMeter flowMeter;
|
||||
readonly DoubleBox flowBox;
|
||||
readonly Event eventDone;
|
||||
readonly DoubleBox flowBox;
|
||||
readonly Event eventDone;
|
||||
|
||||
/// <summary>
|
||||
/// Events: FlowInDone, FlowOutDone or Error
|
||||
/// </summary>
|
||||
/// <param name="flowMeter">Flow meter reference</param>
|
||||
/// <param name="flowBox">Reference to the measured flow variable, value is in bar</param>
|
||||
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
|
||||
/// <summary>
|
||||
/// Events: FlowInDone, FlowOutDone or Error
|
||||
/// </summary>
|
||||
/// <param name="flowMeter">Flow meter reference</param>
|
||||
/// <param name="flowBox">Reference to the measured flow variable, value is in bar</param>
|
||||
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
|
||||
public ReadFlowOp(IFlowMeter flowMeter, ref DoubleBox flowBox, Event eventDone)
|
||||
{
|
||||
if (flowMeter == null) throw new ArgumentNullException();
|
||||
|
||||
this.flowMeter = flowMeter;
|
||||
this.eventDone = eventDone;
|
||||
this.flowBox = flowBox;
|
||||
this.eventDone = eventDone;
|
||||
this.flowBox = flowBox;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
public ReadFlowOp(IFlowMeter flowMeter, ref DoubleBox flowBox)
|
||||
: this(flowMeter, ref flowBox, Event.FlowMeasurementDone)
|
||||
{
|
||||
}
|
||||
: this(flowMeter, ref flowBox, Event.FlowMeasurementDone)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start() { }
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start() { }
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>
|
||||
/// Event.FlowInDone or Event.FlowOutDone
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>
|
||||
/// Event.FlowInDone or Event.FlowOutDone
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
if (flowMeter.MsrmntAvailable)
|
||||
{
|
||||
{
|
||||
if (flowBox != null) flowBox.Val = flowMeter.ReadFlow();
|
||||
return eventDone;
|
||||
}
|
||||
return eventDone;
|
||||
}
|
||||
|
||||
return Event.Error;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop() { }
|
||||
}
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop() { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
///
|
||||
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2021 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using TBF.Rig.ControlBoard.Uni;
|
||||
using TBF.Rig.GenericDevices;
|
||||
|
||||
namespace TBF.Rig.Uni.RegValve
|
||||
@@ -14,12 +13,12 @@ namespace TBF.Rig.Uni.RegValve
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(ChangeRegValvePositionOp));
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("ChangeRegValvePositionOp({0},{1}s)", regV.Name, timePulseSec.ToString("F2"));
|
||||
return string.Format("ChangeRegValvePositionOp({0},{1}s)", regulValve.Name, timePulseSec.ToString("F2"));
|
||||
}
|
||||
|
||||
/// Set by the constructor
|
||||
readonly UniCB uniCB;
|
||||
readonly RegValve regV;
|
||||
readonly TBF.Rig.ControlBoard.Uni.UniCB controlBoard;
|
||||
readonly RegValve regulValve;
|
||||
readonly int regulValveNr;
|
||||
readonly double timePulseSec;
|
||||
|
||||
@@ -33,14 +32,14 @@ namespace TBF.Rig.Uni.RegValve
|
||||
/// <param name="posHiPct">Upper limit of the position to be achieved</param>
|
||||
/// <param name="timeout">Timeout in sec. for setting the flow</param>
|
||||
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
|
||||
public ChangeRegValvePositionOp(UniCB uniCB, RegValve regV, double timePulseSec)
|
||||
public ChangeRegValvePositionOp(TBF.Rig.ControlBoard.IControlBoard cb, RegValve rv, double timePulseSec)
|
||||
{
|
||||
this.uniCB = uniCB;
|
||||
if (this.uniCB == null) throw new ArgumentNullException("ctrlBoard");
|
||||
controlBoard = cb as TBF.Rig.ControlBoard.Uni.UniCB;
|
||||
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
|
||||
|
||||
this.regV = regV as RegValve;
|
||||
if (this.regV == null) throw new ArgumentNullException("regValve is null or not Uni");
|
||||
regulValveNr = this.regV.Idx1;
|
||||
regulValve = rv as RegValve;
|
||||
if (regulValve == null) throw new ArgumentNullException("regValve is null or not Elde");
|
||||
regulValveNr = this.regulValve.Idx1;
|
||||
|
||||
this.timePulseSec = timePulseSec;
|
||||
|
||||
@@ -50,7 +49,13 @@ namespace TBF.Rig.Uni.RegValve
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
uniCB.RegVlvIncrMove(false, regulValveNr, timePulseSec);
|
||||
//double positionPct = controlBoard.RValvePosition(regulValveNr);
|
||||
//log.WarnFormat("RV#={0}, actPos={1}%", regulValveNr, positionPct.ToString("F1"));
|
||||
|
||||
//controlBoard.ValveMove(regulValveNr,
|
||||
// TBF.Rig.ControlBoard.Legacy.RegulValveMode.PulseWidth,
|
||||
// new double[2] { timePulseSec, timePulseSec },
|
||||
// regulValve.StableTime);
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
@@ -59,6 +64,9 @@ namespace TBF.Rig.Uni.RegValve
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
//float positionPct = controlBoard.RValvePosition(regulValveNr);
|
||||
//log.WarnFormat("RV#={0}, actPos={1}%", regulValveNr, positionPct.ToString("F1"));
|
||||
|
||||
return Event.PositionReached;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2021 Sensus Metering Systems
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2021 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using log4net;
|
||||
|
||||
@@ -20,10 +20,11 @@ namespace TBF.Rig.Uni.RegValve
|
||||
return string.Format("SetFlowOp({0}, Qfrom={1}, Qto={2})", regV.Name, shrinkedTgtFlowLo, shrinkedTgtFlowHi);
|
||||
}
|
||||
|
||||
|
||||
public const double RqrdFlowRangeRatio = 0.5;
|
||||
|
||||
///
|
||||
/// Set by the constructor
|
||||
/// Set by the constructor
|
||||
///
|
||||
readonly UniCB uniCB;
|
||||
readonly RegValve regV;
|
||||
@@ -36,8 +37,8 @@ namespace TBF.Rig.Uni.RegValve
|
||||
readonly bool leaveFlowControlRunning;
|
||||
|
||||
readonly double maximalFlow;
|
||||
|
||||
///
|
||||
|
||||
///
|
||||
/// Internal state of this operation
|
||||
///
|
||||
enum OpState
|
||||
@@ -56,12 +57,13 @@ namespace TBF.Rig.Uni.RegValve
|
||||
|
||||
double currentReqFlowLo;
|
||||
double currentReqFlowHi;
|
||||
double targetPositionLo;
|
||||
double targetPositionHi;
|
||||
double targetPositionLo;
|
||||
double targetPositionHi;
|
||||
|
||||
int startTime;
|
||||
int setFlowTime;
|
||||
int expireTime;
|
||||
DoubleBox msrdFlow;
|
||||
DoubleBox flowBox;
|
||||
int isFlowOkDuration;
|
||||
|
||||
|
||||
@@ -70,23 +72,23 @@ namespace TBF.Rig.Uni.RegValve
|
||||
/// Events: FlowSet, FlowTimeOut
|
||||
/// </summary>
|
||||
/// <param name="uniCB">Control board device</param>
|
||||
/// <param name="regValve">Regulation valve component</param>
|
||||
/// <param name="regulValve">Regulation valve component</param>
|
||||
/// <param name="flowMeter">Flowmeter component</param>
|
||||
/// <param name="qFrom">Lower limit of the flow to be achieved in [m3/h]</param>
|
||||
/// <param name="qTo">Upper limit of the flow to be achieved in [m3/h]</param>
|
||||
/// <param name="msrdFlow">DoubleBox for measured flow</param>
|
||||
/// <param name="pidCoef">PID coefficient (float)</param>
|
||||
/// <param name="timeout">Timeout for the flow setting in [s]</param>
|
||||
/// <param name="delay">Flow setting starts after this delay in [s]</param>
|
||||
/// <param name="delay">Flow setting starts after this delay [s]</param>
|
||||
/// <param name="leaveFlowControlRunning">true = Leave the measurement running after op. stop</param>
|
||||
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
|
||||
public SetFlowOp(UniCB uniCB, IRegValve regValve, IFlowMeter flowMeter, double qFrom, double qTo, DoubleBox msrdFlow,
|
||||
public SetFlowOp(UniCB uniCB, IRegValve regValve, IFlowMeter flowMeter, double qFrom, double qTo, DoubleBox flowBox,
|
||||
int timeout, int delay, bool leaveFlowControlRunning)
|
||||
{
|
||||
this.uniCB = uniCB;
|
||||
if (this.uniCB == null) throw new ArgumentNullException("Control board is null or not Uni");
|
||||
this.uniCB = uniCB;
|
||||
if (this.uniCB == null) throw new ArgumentNullException("cBoard is null or not Uni");
|
||||
|
||||
this.regV = regValve as RegValve;
|
||||
if (this.regV == null) throw new ArgumentNullException(string.Format("{0} is not Uni.RegValve", regValve.Name));
|
||||
if (this.regV == null) throw new ArgumentNullException("regValve is null or not Uni");
|
||||
|
||||
this.flowMeter = flowMeter;
|
||||
if (this.flowMeter == null) throw new ArgumentNullException("flowMeter");
|
||||
@@ -96,14 +98,15 @@ namespace TBF.Rig.Uni.RegValve
|
||||
double rqrdFlowLoBeforeCorr = qFrom - MeasurementCorrection.GetCorrection(qFrom, flowMeter.Corrections);
|
||||
double rqrdFlowHiBeforeCorr = qTo - MeasurementCorrection.GetCorrection(qTo, flowMeter.Corrections);
|
||||
targetFlowAve = (rqrdFlowLoBeforeCorr + rqrdFlowHiBeforeCorr) / 2;
|
||||
shrinkedTgtFlowLo = (RqrdFlowRangeRatio * rqrdFlowLoBeforeCorr)
|
||||
+ ((1 - RqrdFlowRangeRatio) * targetFlowAve); /// Move the lower limit 15% of the range up
|
||||
shrinkedTgtFlowHi = (RqrdFlowRangeRatio * rqrdFlowHiBeforeCorr)
|
||||
+ ((1 - RqrdFlowRangeRatio) * targetFlowAve); /// Move the upper limit 15% of the range down
|
||||
shrinkedTgtFlowLo = (RqrdFlowRangeRatio * rqrdFlowLoBeforeCorr) + ((1 - RqrdFlowRangeRatio) * targetFlowAve); /// Move the lower limit 15% of the range up
|
||||
shrinkedTgtFlowHi = (RqrdFlowRangeRatio * rqrdFlowHiBeforeCorr) + ((1 - RqrdFlowRangeRatio) * targetFlowAve); /// Move the upper limit 15% of the range down
|
||||
|
||||
this.flowBox = flowBox;
|
||||
if (this.flowBox == null) throw new ArgumentNullException("flowBox");
|
||||
|
||||
this.msrdFlow = msrdFlow;
|
||||
this.timeout = timeout;
|
||||
this.delay = delay;
|
||||
|
||||
this.leaveFlowControlRunning = leaveFlowControlRunning;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
@@ -169,13 +172,16 @@ namespace TBF.Rig.Uni.RegValve
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
/// <summary>
|
||||
/// Start this operation
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
|
||||
regV.Idx1, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi);
|
||||
|
||||
/// Store the current time, etc.
|
||||
startTime = StateMachine.Time;
|
||||
setFlowTime = StateMachine.Time + delay;
|
||||
expireTime = StateMachine.Time + timeout;
|
||||
if (expireTime < 0) expireTime = int.MaxValue;
|
||||
@@ -273,16 +279,17 @@ namespace TBF.Rig.Uni.RegValve
|
||||
///
|
||||
double frequency = flowMeter.ReadFrequency();
|
||||
double flow = flowMeter.ReadFlow();
|
||||
if (msrdFlow != null && flow != 0) msrdFlow.Val = flow;
|
||||
if (flow != 0) flowBox.Val = flow;
|
||||
|
||||
if (currentReqFlowLo <= flow && flow <= currentReqFlowHi)
|
||||
if ((currentReqFlowLo <= flow) && (flow <= currentReqFlowHi))
|
||||
{
|
||||
isFlowOkDuration++; /// Increment the flow within range duration
|
||||
/// Flow is within range
|
||||
isFlowOkDuration++;
|
||||
|
||||
if (isFlowOkDuration >= regV.FlowStableSec)
|
||||
{
|
||||
/// Flow is within range for sufficiently long time
|
||||
if (regV.StoredPositionReuse)
|
||||
if (regV.regValveCfg.StoredPositionReuse)
|
||||
{
|
||||
double rvPosition = regV.Position; /// Read the current position
|
||||
double storedPosition;
|
||||
@@ -329,12 +336,13 @@ namespace TBF.Rig.Uni.RegValve
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (!leaveFlowControlRunning)
|
||||
{
|
||||
uniCB.StopFlowControl(false, regV.Idx1); /// Stop the flow measurement
|
||||
/// Stop flow measurement
|
||||
uniCB.StopFlowControl(false, regV.Idx1);
|
||||
}
|
||||
|
||||
opState = OpState.Idle;
|
||||
|
||||
@@ -14,7 +14,9 @@ using log4net;
|
||||
using NHibernate.Util;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.implementations;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader;
|
||||
using TBF.Rig.Sequences;
|
||||
@@ -157,6 +159,14 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
correctionsList.Add(new PoseidonCorrections(this,log, rfidDataLogger, componentBase, cfg, tests, multiTestParams));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (smartHead is GenesisSmartReader genSmartReader)
|
||||
{
|
||||
if (correctionsList.Any(x => x is GenesisSmartReader))
|
||||
continue;
|
||||
correctionsList.Add(new GenesisCorrections( this,componentBase, cfg, tests, multiTestParams));
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new Exception("Unknown smart head type");
|
||||
}
|
||||
@@ -189,6 +199,14 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
correctionsList.Add(new PoseidonCorrections(form));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (smartHead is GenesisSmartReader genSmartReader)
|
||||
{
|
||||
if (correctionsList.Any(x => x is GenesisSmartReader))
|
||||
continue;
|
||||
correctionsList.Add(new GenesisCorrections(form));
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new Exception("Unknown smart head type");
|
||||
}
|
||||
@@ -223,6 +241,12 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
typeReaders.Add(smartReader.ClassName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (smartHead is GenesisSmartReader genSmartReader)
|
||||
{
|
||||
typeReaders.Add(genSmartReader.ClassName);
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new Exception("Unknown smart head type");
|
||||
}
|
||||
@@ -327,7 +351,13 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
{
|
||||
checkBoxesEditMode = false;
|
||||
|
||||
ITestMethodCfg cfg = (componentBase as ITestMethodCfg);
|
||||
ITestMethodSmart smart = (componentBase as ITestMethodSmart);
|
||||
ITestMethodCfg cfg = (componentBase as ITestMethodCfg);
|
||||
if (smart != null && cfg == null)
|
||||
{
|
||||
cfg = (componentBase.Cfg as ITestMethodCfg);
|
||||
}
|
||||
|
||||
ISmartTestMethod smartTestMethod = componentBase as ISmartTestMethod;
|
||||
|
||||
//TODO get corrections based on defined meter
|
||||
@@ -410,7 +440,8 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
if (iperlHeads == null) iperlHeads = new List<ISmartReader>();
|
||||
waterMeterPositions0?.Clear();
|
||||
if (waterMeterPositions0 == null) waterMeterPositions0 = new List<int>();
|
||||
//iperlHeads = ProcessData.SmartHeadsUni;
|
||||
//TODO BUMI check
|
||||
iperlHeads = ProcessData.SmartHeadsUni;
|
||||
string comparedTypeReader = SelectedTypeReader;
|
||||
if (string.IsNullOrEmpty(SelectedTypeReader))
|
||||
{
|
||||
@@ -460,25 +491,47 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
|
||||
private void InitializeMeterTypeItems()
|
||||
{
|
||||
if (_corrections.Count >= 0)
|
||||
meterTypeComboBox.Items.Clear();
|
||||
|
||||
if (_corrections == null || _corrections.Count == 0)
|
||||
{
|
||||
meterTypeComboBox.Items.Clear();
|
||||
int iItem = 0;
|
||||
foreach (ICorrections correction in _corrections)
|
||||
{
|
||||
string name = correction?.TypeIdentificatorName();
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
name = iItem.ToString();
|
||||
}
|
||||
meterTypeComboBox.Items.Add(name);
|
||||
if (iItem == 0)
|
||||
SelectedTypeReader = name;
|
||||
iItem++;
|
||||
}
|
||||
meterTypeComboBox.Visible = true;
|
||||
meterTypeComboBox.Enabled = true;
|
||||
meterTypeComboBox.SelectedIndex = 0;
|
||||
meterTypeComboBox.Visible = false;
|
||||
meterTypeComboBox.Enabled = false;
|
||||
SelectedTypeReader = null;
|
||||
return;
|
||||
}
|
||||
|
||||
int iItem = 0;
|
||||
|
||||
foreach (ICorrections correction in _corrections)
|
||||
{
|
||||
string name = correction?.TypeIdentificatorName();
|
||||
|
||||
if (string.IsNullOrEmpty(name))
|
||||
name = iItem.ToString();
|
||||
|
||||
meterTypeComboBox.Items.Add(name);
|
||||
|
||||
if (iItem == 0)
|
||||
SelectedTypeReader = name;
|
||||
|
||||
iItem++;
|
||||
}
|
||||
|
||||
meterTypeComboBox.Visible = true;
|
||||
meterTypeComboBox.Enabled = true;
|
||||
|
||||
initializingMeterTypes = true;
|
||||
try
|
||||
{
|
||||
// fill items...
|
||||
|
||||
if (meterTypeComboBox.Items.Count > 0)
|
||||
meterTypeComboBox.SelectedIndex = 0;
|
||||
}
|
||||
finally
|
||||
{
|
||||
initializingMeterTypes = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,7 +544,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
WaterMetersCount = iperlHeads.Count;
|
||||
ShuffleTextBoxes(WaterMetersCount, ProcessData.LineSize);
|
||||
|
||||
Correction.PrepareForTestsActivities(WaterMetersCount);
|
||||
Correction?.PrepareForTestsActivities(WaterMetersCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -530,7 +583,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
|
||||
private void DoOnCommCompleted(object sender, CommCompletedEventArgs data)
|
||||
{
|
||||
Correction.DoOnCommCompleted(sender, data, waterMeterPositions0);
|
||||
Correction?.DoOnCommCompleted(sender, data, waterMeterPositions0);
|
||||
}
|
||||
|
||||
|
||||
@@ -572,7 +625,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
textBoxesCount = wmsCount;
|
||||
}
|
||||
|
||||
int count = checkBoxesEditMode ? textBoxesCount : Math.Min(textBoxesCount, Correction.GetHeadsCount());
|
||||
int count = checkBoxesEditMode ? textBoxesCount : Math.Min(textBoxesCount, Correction?.GetHeadsCount() ?? 0);
|
||||
for (int j = 0; j < count; j++)
|
||||
{
|
||||
labels[j].Text = (j + 1).ToString();
|
||||
@@ -674,11 +727,15 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
samplePictureBox3.Visible = false;
|
||||
}
|
||||
|
||||
if (_corrections.Count > 0)//enable combo for choose SmartMeter
|
||||
if (_corrections != null && _corrections.Count > 0)
|
||||
{
|
||||
meterTypeComboBox.Visible = true;
|
||||
}
|
||||
Correction.Load(labels,counters,messages,checkBoxes,ckbIndex,ckbState, iperlHeads,textBoxesCount,checkBoxesEditMode );
|
||||
else
|
||||
{
|
||||
meterTypeComboBox.Visible = false;
|
||||
}
|
||||
Correction?.Load(labels,counters,messages,checkBoxes,ckbIndex,ckbState, iperlHeads,textBoxesCount,checkBoxesEditMode );
|
||||
|
||||
///
|
||||
/// Set location and checkbox states to values stored in local settings
|
||||
@@ -693,7 +750,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
/// Regular activity (not a checkbox edit mode invoked from TBF menu)
|
||||
|
||||
/// Reset opto-data indication
|
||||
for (int i = 0; i < Correction.GetHeadsCount(); i++)
|
||||
for (int i = 0; i < (Correction?.GetHeadsCount() ?? 0); i++)
|
||||
{
|
||||
counters[i].BackColor = iPerlCommunicationConstants.OptoNokColor;
|
||||
}
|
||||
@@ -702,11 +759,14 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
//currentGroup++;
|
||||
|
||||
int wtId = 0;
|
||||
foreach (var wt in Correction.GetAllThreads())
|
||||
{
|
||||
wt.Start(new Boxes.IntBox(wtId++)); /// Start worker threads !!!
|
||||
}
|
||||
}
|
||||
if (Correction?.GetAllThreads() != null)
|
||||
{
|
||||
foreach (var wt in Correction?.GetAllThreads())
|
||||
{
|
||||
wt.Start(new Boxes.IntBox(wtId++)); /// Start worker threads !!!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -917,13 +977,32 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
}
|
||||
|
||||
|
||||
private bool initializingMeterTypes;
|
||||
|
||||
private void meterTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (initializingMeterTypes)
|
||||
return;
|
||||
|
||||
ComboBox senderCombo = sender as ComboBox;
|
||||
if (senderCombo == null) return;
|
||||
if (senderCombo == null)
|
||||
return;
|
||||
|
||||
SelectedTypeReader = senderCombo.SelectedItem?.ToString();
|
||||
|
||||
UpdateHeads();
|
||||
SmartCommunicationForm_Load(this, EventArgs.Empty);
|
||||
|
||||
Correction?.Load(
|
||||
labels,
|
||||
counters,
|
||||
messages,
|
||||
checkBoxes,
|
||||
ckbIndex,
|
||||
ckbState,
|
||||
iperlHeads,
|
||||
textBoxesCount,
|
||||
checkBoxesEditMode
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2878
File diff suppressed because it is too large
Load Diff
+40
-8
@@ -71,7 +71,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;CAMERA;LANG_PL;IPERL;</DefineConstants>
|
||||
<DefineConstants>TRACE;CAMERA;LANG_PL;IPERL;LIVELOGDIAG_FlowMeter_cs;LIVELOGDIAG_RegValve_cs</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -1049,7 +1049,9 @@
|
||||
<Compile Include="Rig\Operations\LargeMessageBoxOp.cs" />
|
||||
<Compile Include="Rig\Operations\ReturnGivenEventOp.cs" />
|
||||
<Compile Include="Rig\Output\DB\DatabaseWriter\Factory.cs" />
|
||||
<Compile Include="Rig\Output\DB\DatabaseWriter\WriteDBCfgCtrl.cs" />
|
||||
<Compile Include="Rig\Output\DB\DatabaseWriter\WriteDBCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\Output\DB\DatabaseWriter\WriteDBCfgCtrl.designer.cs" />
|
||||
<Compile Include="Rig\Output\DB\DatabaseWriter\WriterCfg.cs" />
|
||||
<Compile Include="Rig\Output\DB\DatabaseWriter\WritingToDB.cs" />
|
||||
@@ -1386,12 +1388,16 @@
|
||||
<Compile Include="Rig\RegisterReaders\GenesisRegReader\communication\Utils\SerialDriver.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\GenesisRegReader\communication\Utils\SerialDriverBuilder.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\GenesisRegReader\Factory.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\GenesisRegReader\GenesisHeadTestCtrl.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\GenesisRegReader\GenesisHeadTestCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\RegisterReaders\GenesisRegReader\GenesisHeadTestCtrl.Designer.cs">
|
||||
<DependentUpon>GenesisHeadTestCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\RegisterReaders\GenesisRegReader\GenesisCfg.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\GenesisRegReader\GenesisCfgCtrl.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\GenesisRegReader\GenesisCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\RegisterReaders\GenesisRegReader\GenesisCfgCtrl.designer.cs">
|
||||
<DependentUpon>GenesisCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
@@ -1410,9 +1416,13 @@
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\Factory.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\implementations\IPerlASICImplHeadTestCtrl.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\implementations\SmartReader.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\IperlASICUniHeadTestCtrl.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\IperlASICUniHeadTestCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\IperlASICUniHeadTestCtrl.Designer.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\IPerlUniCfgCtrl.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\IPerlUniCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\IPerlUniCfgCtrl.designer.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\common\IUniHeadTestCtrl.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\Factory.cs" />
|
||||
@@ -1484,6 +1494,8 @@
|
||||
<DependentUpon>RRCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\CliRunner.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\CliTaskInfo.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\CliTaskState.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\Factory.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\JsonDataFromPoseidon.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\PoseidonCfg.cs" />
|
||||
@@ -1715,12 +1727,26 @@
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisHead\Factory.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisHead\GenesisHead.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisHead\GenesisHeadCfg.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisHead\GenesisHeadCfgCtrl.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisHead\GenesisHeadCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisHead\GenesisHeadCfgCtrl.designer.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisHead\OptoReceivedEventArgs.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisHead\OptoTelegramRaw.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisHead\ProcParams.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisCommunication\GenesisHead\StatusStruct.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisFullCommunication\Factory.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisFullCommunication\GenesisCommunicationSeq.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisFullCommunication\GenesisCommunicationParams.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisFullCommunication\SequenceConditionOp.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisFullCommunication\TestMethod.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisFullCommunication\TestMethodCfg.cs" />
|
||||
<Compile Include="Rig\TestMethods\GenesisFullCommunication\TestMethodCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\TestMethods\GenesisFullCommunication\TestMethodCfgCtrl.designer.cs">
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\TestMethods\iPerlCommunication\AllCompletedEventArgs.cs" />
|
||||
<Compile Include="Rig\TestMethods\iPerlCommunication\CheckBoxImage.cs">
|
||||
<SubType>Component</SubType>
|
||||
@@ -1771,7 +1797,9 @@
|
||||
<Compile Include="Rig\TestMethods\iPerlCommunication\communication\Utils\ISerialDriver.cs" />
|
||||
<Compile Include="Rig\TestMethods\iPerlCommunication\communication\Utils\SerialDriver.cs" />
|
||||
<Compile Include="Rig\TestMethods\iPerlCommunication\communication\Utils\SerialDriverBuilder.cs" />
|
||||
<Compile Include="Rig\TestMethods\iPerlCommunication\iPerlCommunicationForm.cs" />
|
||||
<Compile Include="Rig\TestMethods\iPerlCommunication\iPerlCommunicationForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\TestMethods\iPerlCommunication\iPerlCommunicationForm.designer.cs" />
|
||||
<Compile Include="Rig\TestMethods\iPerlCommunication\iPerlCommunicationParams.cs" />
|
||||
<Compile Include="Rig\TestMethods\iPerlCommunication\iPerlCommunicationSeq.cs" />
|
||||
@@ -2288,6 +2316,7 @@
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\common\ICorrections.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\common\ISmartReader.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\implementations\EnumExtensions.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\implementations\GenesisCorrections.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\implementations\IPerlASICCorrections.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\implementations\IPerlCorrections.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\implementations\PoseidonCorrections.cs" />
|
||||
@@ -3647,6 +3676,9 @@
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\TestMethods\GenesisCommunication\GenesisHead\GenesisHeadCfgCtrl.resx" />
|
||||
<EmbeddedResource Include="Rig\TestMethods\GenesisFullCommunication\TestMethodCfgCtrl.resx">
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\TestMethods\GrabImage\GrabImageCfgCtrl.resx">
|
||||
<DependentUpon>GrabImageCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
@@ -189,8 +189,16 @@ namespace TBF.UI.Bench.Components
|
||||
int extraWidth = splitContainer.Panel2.Width + 40;
|
||||
int extraHeight = 80;
|
||||
|
||||
this.Width = desired.Width + extraWidth;
|
||||
this.Height = desired.Height + extraHeight;
|
||||
if (!desired.IsEmpty)
|
||||
{
|
||||
this.Width = desired.Width + extraWidth;
|
||||
this.Height = desired.Height + extraHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
//this.Width += extraWidth;
|
||||
//this.Height += extraHeight;
|
||||
}
|
||||
|
||||
// Do not exceed screen working area
|
||||
var screen = Screen.FromControl(this).WorkingArea;
|
||||
|
||||
@@ -43,7 +43,10 @@ namespace TBF.UI.Bench.Components
|
||||
{
|
||||
availCmpntsLstBox.SelectedIndex = selectedIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/// SharedDlgSearchForListBox configuration
|
||||
sharedSearchForListBox1.ListBoxEx = availCmpntsLstBox;
|
||||
}
|
||||
|
||||
void Localize()
|
||||
{
|
||||
|
||||
+2
-1
@@ -1199,7 +1199,8 @@ namespace TBF.UI
|
||||
|
||||
private void optoHeadsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new iPerlCommunicationForm(true).ShowDialog();
|
||||
//new iPerlCommunicationForm(true).ShowDialog();
|
||||
new SmartCommunicationForm(true).ShowDialog();
|
||||
}
|
||||
|
||||
private void statusStrip1_DoubleClick(object sender, EventArgs e)
|
||||
|
||||
@@ -86,8 +86,38 @@ namespace TBF.UI.Process
|
||||
|
||||
Bridge.StateMachineTickHandler += delegate(object sndr, UiBridge.StateMachineTickEventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.StateMachineTickEventArgs>(OnStateMachineTick), sndr, args); }
|
||||
else OnStateMachineTick(sndr, args);
|
||||
try
|
||||
{
|
||||
if (IsDisposed || Disposing || !IsHandleCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (InvokeRequired)
|
||||
{
|
||||
BeginInvoke(new EventHandler<UiBridge.StateMachineTickEventArgs>(OnStateMachineTick), sndr, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnStateMachineTick(sndr, args);
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException e)
|
||||
{
|
||||
log.DebugFormat("ProcessTabPageCtrl.OnStateMachineTick() skipped because control is disposed: {0}", e.Message);
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
log.DebugFormat("ProcessTabPageCtrl.OnStateMachineTick() skipped because UI is not available: {0}", e.Message);
|
||||
}
|
||||
catch (System.ComponentModel.InvalidAsynchronousStateException e)
|
||||
{
|
||||
log.DebugFormat("ProcessTabPageCtrl.OnStateMachineTick() skipped because UI thread is no longer available: {0}", e.Message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.ErrorFormat("ProcessTabPageCtrl.OnStateMachineTick() failed: {0}", e.Message);
|
||||
}
|
||||
};
|
||||
|
||||
Bridge.TestCompletedHandler += delegate(object sender, TestCompletedEventArgs args)
|
||||
|
||||
+53
-100
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.common;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.communication;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.implementations;
|
||||
@@ -14,10 +15,16 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
public class GenesisReaderTests
|
||||
{
|
||||
|
||||
private static GenesisCfg CreateCfg()
|
||||
{
|
||||
Factory factory = new Factory();
|
||||
return new GenesisCfg(factory);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Debug_ProcessOptoLine_FormatVariants()
|
||||
{
|
||||
var reader = new GenesisSmartReader();
|
||||
var reader = new GenesisSmartReader(CreateCfg());
|
||||
InitializeReaderForTest(reader);
|
||||
|
||||
string[] variants =
|
||||
@@ -28,26 +35,28 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
"@he \t1\t0\t0A1F59C4\t00017A43\t00115C45\t72E1596B\t00000400\t00001998\t7D91B652\t7D4F37E6\t000191E6\t0C\t062E4A9C\t5331"
|
||||
};
|
||||
|
||||
int[] counts = new int[variants.Length];
|
||||
|
||||
for (int i = 0; i < variants.Length; i++)
|
||||
{
|
||||
bool blockCompleted = false;
|
||||
reader.ProcessOptoLine(variants[i], DataStreamState.ProcessAndSave, out blockCompleted);
|
||||
|
||||
int optoDataCount = GetPrivateField<int>(reader, "optoDataCount");
|
||||
counts[i] = GetPrivateField<int>(reader, "optoDataCount");
|
||||
|
||||
Console.WriteLine($"Variant {i}: {variants[i]}");
|
||||
Console.WriteLine($" blockCompleted={blockCompleted}");
|
||||
Console.WriteLine($" optoDataCount={optoDataCount}");
|
||||
Console.WriteLine($" optoDataCount={counts[i]}");
|
||||
Console.WriteLine("--------------------------------");
|
||||
}
|
||||
|
||||
Assert.Fail("Inspect which variant, if any, is accepted.");
|
||||
Assert.IsTrue(counts.Any(c => c > 0), "At least one telegram format variant should be accepted.");
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void RealInput_ShouldCalculate_StartEndVolumes_AndTimes()
|
||||
public void RealInput_ShouldParseCalibrationTelegrams()
|
||||
{
|
||||
var reader = new GenesisSmartReader();
|
||||
var reader = new GenesisSmartReader(CreateCfg());
|
||||
InitializeReaderForTest(reader);
|
||||
|
||||
string[] realInputLines = LoadRealInputLines();
|
||||
@@ -110,87 +119,33 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
Console.WriteLine($"Final firstValidIx = {firstValidIx}");
|
||||
Console.WriteLine($"Final lastValidIx = {lastValidIx}");
|
||||
|
||||
if (processedCount <= 0)
|
||||
{
|
||||
Assert.Fail(
|
||||
"No valid calibration telegrams were parsed.\n" +
|
||||
"Check the following:\n" +
|
||||
"1. exact telegram prefix (for example @h vs @he)\n" +
|
||||
"2. exact separators (spaces vs tabs)\n" +
|
||||
"3. exact CRC / checksum\n" +
|
||||
"4. whether ProcessOptoLine expects a complete multi-line block format\n" +
|
||||
"See test output for per-line diagnostics.");
|
||||
}
|
||||
Assert.AreEqual(3, processedCount, "Expected all 3 calibration telegrams to be parsed.");
|
||||
Assert.AreEqual(0, firstValidIx);
|
||||
Assert.AreEqual(2, lastValidIx);
|
||||
|
||||
var optoData = GetPrivateField<OptoTelegramRaw[]>(reader, "optoData");
|
||||
Assert.IsNotNull(optoData);
|
||||
|
||||
Assert.AreEqual(0, optoData[0].IChannel());
|
||||
Assert.AreEqual(1, optoData[1].IChannel());
|
||||
Assert.AreEqual(2, optoData[2].IChannel());
|
||||
|
||||
// With only one telegram per channel, full start/end reconstruction is not expected yet.
|
||||
reader.TestStartTelegramIx = firstValidIx;
|
||||
reader.TestEndTelegramIx = lastValidIx;
|
||||
|
||||
Console.WriteLine("=== BEFORE POST PROCESSING ===");
|
||||
Console.WriteLine($"TestStartTelegramIx = {reader.TestStartTelegramIx}");
|
||||
Console.WriteLine($"TestEndTelegramIx = {reader.TestEndTelegramIx}");
|
||||
InvokePrivate(reader, "AddTestStartEndMarksToData", new object[] { 0, 0 });
|
||||
InvokePrivate(reader, "DataStreamPostProcessing");
|
||||
InvokePrivate(reader, "PrepareCalculatedChannelData");
|
||||
|
||||
object[] markArgs = { 0, 0 };
|
||||
|
||||
try
|
||||
{
|
||||
InvokePrivate(reader, "AddTestStartEndMarksToData", markArgs);
|
||||
Console.WriteLine("AddTestStartEndMarksToData OK");
|
||||
|
||||
InvokePrivate(reader, "DataStreamPostProcessing");
|
||||
Console.WriteLine("DataStreamPostProcessing OK");
|
||||
|
||||
InvokePrivate(reader, "PrepareCalculatedChannelData");
|
||||
Console.WriteLine("PrepareCalculatedChannelData OK");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Assert.Fail(
|
||||
"Post-processing failed.\n" +
|
||||
$"Exception: {ex.GetType().Name}: {ex.Message}\n" +
|
||||
$"StackTrace:\n{ex.StackTrace}");
|
||||
}
|
||||
|
||||
Console.WriteLine("=== CALCULATED VALUES ===");
|
||||
Console.WriteLine($"NoSamples = {reader.NoSamples}");
|
||||
Console.WriteLine($"VolumeLtrStart = {reader.VolumeLtrStart}");
|
||||
Console.WriteLine($"VolumeLtrEnd = {reader.VolumeLtrEnd}");
|
||||
Console.WriteLine($"TimestampSecStart = {reader.TimestampSecStart}");
|
||||
Console.WriteLine($"TimestampSecEnd = {reader.TimestampSecEnd}");
|
||||
|
||||
Assert.IsFalse(double.IsNaN(reader.VolumeLtrStart), "VolumeLtrStart is NaN");
|
||||
Assert.IsFalse(double.IsNaN(reader.VolumeLtrEnd), "VolumeLtrEnd is NaN");
|
||||
Assert.IsFalse(double.IsNaN(reader.TimestampSecStart), "TimestampSecStart is NaN");
|
||||
Assert.IsFalse(double.IsNaN(reader.TimestampSecEnd), "TimestampSecEnd is NaN");
|
||||
|
||||
Assert.IsTrue(reader.TimestampSecEnd >= reader.TimestampSecStart,
|
||||
$"Timestamp ordering invalid: start={reader.TimestampSecStart}, end={reader.TimestampSecEnd}");
|
||||
|
||||
Assert.IsTrue(reader.VolumeLtrEnd >= reader.VolumeLtrStart,
|
||||
$"Volume ordering invalid: start={reader.VolumeLtrStart}, end={reader.VolumeLtrEnd}");
|
||||
|
||||
// When parser input is finally correct, replace these expected values:
|
||||
const double expectedVolumeStart = 0.0;
|
||||
const double expectedVolumeEnd = 0.0;
|
||||
const double expectedTimeStart = 0.0;
|
||||
const double expectedTimeEnd = 0.0;
|
||||
const double tolerance = 0.000001;
|
||||
|
||||
Console.WriteLine("=== EXPECTED VS ACTUAL ===");
|
||||
Console.WriteLine($"expectedVolumeStart = {expectedVolumeStart}, actual = {reader.VolumeLtrStart}");
|
||||
Console.WriteLine($"expectedVolumeEnd = {expectedVolumeEnd}, actual = {reader.VolumeLtrEnd}");
|
||||
Console.WriteLine($"expectedTimeStart = {expectedTimeStart}, actual = {reader.TimestampSecStart}");
|
||||
Console.WriteLine($"expectedTimeEnd = {expectedTimeEnd}, actual = {reader.TimestampSecEnd}");
|
||||
|
||||
Assert.AreEqual(expectedVolumeStart, reader.VolumeLtrStart, tolerance, "VolumeLtrStart mismatch");
|
||||
Assert.AreEqual(expectedVolumeEnd, reader.VolumeLtrEnd, tolerance, "VolumeLtrEnd mismatch");
|
||||
Assert.AreEqual(expectedTimeStart, reader.TimestampSecStart, tolerance, "TimestampSecStart mismatch");
|
||||
Assert.AreEqual(expectedTimeEnd, reader.TimestampSecEnd, tolerance, "TimestampSecEnd mismatch");
|
||||
Assert.IsTrue(reader.NoSamples,
|
||||
"With only one telegram per channel, recalculated start/end samples should still be unavailable.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RealInput_ShouldSupport_RolloverNormalization()
|
||||
public void RealInput_ShouldParseRolloverInputLines()
|
||||
{
|
||||
var reader = new GenesisSmartReader();
|
||||
var reader = new GenesisSmartReader(CreateCfg());
|
||||
InitializeReaderForTest(reader);
|
||||
|
||||
string[] realInputLines = LoadRealInputLinesWithRollover();
|
||||
@@ -211,29 +166,25 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
|
||||
int finalOptoDataCount = GetPrivateField<int>(reader, "optoDataCount");
|
||||
|
||||
Assert.IsTrue(
|
||||
finalOptoDataCount > 1,
|
||||
"Need at least 2 valid telegrams. Check exact telegram format / CRC in LoadRealInputLinesWithRollover().");
|
||||
|
||||
reader.TestStartTelegramIx = 0;
|
||||
reader.TestEndTelegramIx = finalOptoDataCount - 1;
|
||||
|
||||
object[] markArgs = { 0, 0 };
|
||||
InvokePrivate(reader, "AddTestStartEndMarksToData", markArgs);
|
||||
InvokePrivate(reader, "DataStreamPostProcessing");
|
||||
InvokePrivate(reader, "PrepareCalculatedChannelData");
|
||||
|
||||
Console.WriteLine($"VolumeLtrStart={reader.VolumeLtrStart}");
|
||||
Console.WriteLine($"VolumeLtrEnd={reader.VolumeLtrEnd}");
|
||||
Console.WriteLine($"TimestampSecStart={reader.TimestampSecStart}");
|
||||
Console.WriteLine($"TimestampSecEnd={reader.TimestampSecEnd}");
|
||||
|
||||
Assert.IsTrue(reader.TimestampSecEnd >= reader.TimestampSecStart,
|
||||
"Normalized end time should be >= start time");
|
||||
Assert.IsTrue(reader.VolumeLtrEnd >= reader.VolumeLtrStart,
|
||||
"Normalized end volume should be >= start volume");
|
||||
Assert.AreEqual(3, finalOptoDataCount,
|
||||
"Expected all provided rollover input lines to be parsed as telegrams.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PrepareCalculatedChannelDataSimulationForTest_ShouldProduceUsableSamples()
|
||||
{
|
||||
var reader = new GenesisSmartReader(CreateCfg());
|
||||
InitializeReaderForTest(reader);
|
||||
|
||||
reader.PrepareCalculatedChannelDataSimulationForTest();
|
||||
|
||||
Assert.IsFalse(reader.NoSamples);
|
||||
Assert.AreEqual(105.0, reader.VolumeLtrStartAverage, 0.0001);
|
||||
Assert.AreEqual(157.0, reader.VolumeLtrEndAwerage, 0.0001);
|
||||
Assert.AreEqual(10.0, reader.TimestampSecStart, 0.0001);
|
||||
Assert.AreEqual(20.0, reader.TimestampSecEnd, 0.0001);
|
||||
}
|
||||
|
||||
private static void InitializeReaderForTest(GenesisSmartReader reader)
|
||||
{
|
||||
const int channelCount = 3;
|
||||
@@ -264,6 +215,8 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
SetPrivateField(reader, "partOfTelegram", string.Empty);
|
||||
SetPrivateField(reader, "startDataProcessing", true);
|
||||
|
||||
reader.StopQueueData = false;
|
||||
|
||||
reader.TestStartTelegramIx = 0;
|
||||
reader.TestEndTelegramIx = 0;
|
||||
}
|
||||
|
||||
+10
-26
@@ -133,13 +133,13 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
InvokePrepareCalculatedChannelData(reader);
|
||||
|
||||
Assert.AreEqual(200.666666666667, reader.VolumeLtrStart, 1e-9);
|
||||
Assert.AreEqual(219.0, reader.VolumeLtrEnd, 1e-9);
|
||||
Assert.AreEqual(219.666666666667, reader.VolumeLtrEnd, 1e-9);
|
||||
|
||||
Assert.AreEqual(1.0, reader.TimestampSecStart, 1e-9);
|
||||
Assert.AreEqual(20.0, reader.TimestampSecEnd, 1e-9);
|
||||
|
||||
Assert.AreEqual(200.666666666667, reader.VolumeLtrStartRaw, 1e-9);
|
||||
Assert.AreEqual(219.0, reader.VolumeLtrEndRaw, 1e-9);
|
||||
Assert.AreEqual(200.666666666667, reader.VolumeLtrStartAverage, 1e-9);
|
||||
Assert.AreEqual(219.666666666667, reader.VolumeLtrEndAwerage, 1e-9);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -162,11 +162,6 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
index++;
|
||||
}
|
||||
|
||||
// channel 1 loses its last two valid records
|
||||
// valid ch1 becomes: 200..207 with timestamps 1..8
|
||||
// longest channel deltaTime is 9 (channels 0 and 2)
|
||||
// ch1 deltaVolume = 7, deltaTime = 7 => recalculated deltaVolume = 7 * 9 / 7 = 9
|
||||
// recalculated end ch1 = 200 + 9 = 209
|
||||
optoData[25].Flags = OptoTelegramFlags.InvalidTelegram;
|
||||
optoData[28].Flags = OptoTelegramFlags.InvalidTelegram;
|
||||
|
||||
@@ -177,14 +172,14 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
InvokePrepareCalculatedChannelData(reader);
|
||||
|
||||
Assert.AreEqual(200.666666666667, reader.VolumeLtrStart, 1e-9);
|
||||
Assert.AreEqual(208.33333333333334, reader.VolumeLtrEnd, 1e-9);
|
||||
Assert.AreEqual(208.33333333333334, reader.VolumeLtrEndRaw, 1e-9);
|
||||
Assert.AreEqual(209.666666666667, reader.VolumeLtrEnd, 1e-9);
|
||||
Assert.AreEqual(209.666666666667, reader.VolumeLtrEndAwerage, 1e-9);
|
||||
|
||||
Assert.AreEqual(101.0, reader.VolumeLtrStartCh1, 1e-9);
|
||||
Assert.AreEqual(201.0, reader.VolumeLtrStartCh2, 1e-9);
|
||||
Assert.AreEqual(300.0, reader.VolumeLtrStartCh3, 1e-9);
|
||||
|
||||
Assert.AreEqual(200.666666666667, reader.VolumeLtrStartRaw, 1e-9);
|
||||
Assert.AreEqual(200.666666666667, reader.VolumeLtrStartAverage, 1e-9);
|
||||
|
||||
Assert.AreEqual(110.0, reader.VolumeLtrEndCh1, 1e-9);
|
||||
Assert.AreEqual(210.0, reader.VolumeLtrEndCh2, 1e-9);
|
||||
@@ -272,24 +267,13 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
Assert.AreEqual(20.0, reader.TimestampSecEndCh2, 1e-9);
|
||||
Assert.AreEqual(20.0, reader.TimestampSecEndCh3, 1e-9);
|
||||
|
||||
Assert.AreEqual(101.0, reader.VolumeLtrStartCh1, 1e-9);
|
||||
Assert.AreEqual(201.0, reader.VolumeLtrStartCh2, 1e-9);
|
||||
Assert.AreEqual(300.0, reader.VolumeLtrStartCh3, 1e-9);
|
||||
|
||||
Assert.AreEqual(219.0, reader.VolumeLtrEnd, 1e-9);
|
||||
Assert.AreEqual(219.666666666667, reader.VolumeLtrEnd, 1e-9);
|
||||
|
||||
Assert.AreEqual(1.0, reader.TimestampSecStart, 1e-9);
|
||||
Assert.AreEqual(20.0, reader.TimestampSecEnd, 1e-9);
|
||||
|
||||
Assert.AreEqual(200.666666666667, reader.VolumeLtrStartRaw, 1e-9);
|
||||
Assert.AreEqual(219.0, reader.VolumeLtrEndRaw, 1e-9);
|
||||
|
||||
Assert.AreEqual(120.0, reader.VolumeLtrEndCh1, 1e-9);
|
||||
Assert.AreEqual(220.0, reader.VolumeLtrEndCh2, 1e-9);
|
||||
Assert.AreEqual(319.0, reader.VolumeLtrEndCh3, 1e-9);
|
||||
|
||||
Assert.AreEqual(219.0, reader.VolumeLtrEnd, 1e-9);
|
||||
Assert.AreEqual(219.0, reader.VolumeLtrEndRaw, 1e-9);
|
||||
Assert.AreEqual(200.666666666667, reader.VolumeLtrStartAverage, 1e-9);
|
||||
Assert.AreEqual(219.666666666667, reader.VolumeLtrEndAwerage, 1e-9);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -313,7 +297,7 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
InvokePrepareCalculatedChannelData(reader);
|
||||
|
||||
Assert.AreEqual(15.5, reader.VolumeLtrStart, 1e-9);
|
||||
Assert.AreEqual(19.0, reader.VolumeLtrEnd, 1e-9);
|
||||
Assert.AreEqual(19.5, reader.VolumeLtrEnd, 1e-9);
|
||||
|
||||
Assert.AreEqual(11.0, reader.VolumeLtrStartCh1, 1e-9);
|
||||
Assert.AreEqual(20.0, reader.VolumeLtrStartCh2, 1e-9);
|
||||
|
||||
+18
-8
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.common;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.implementations;
|
||||
@@ -36,6 +38,15 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
return (T)field.GetValue(target);
|
||||
}
|
||||
|
||||
private static void WaitForStopToFinish(GenesisSmartReader reader, int timeoutMs = 3000)
|
||||
{
|
||||
var stopTask = GetPrivateField<Task>(reader, "_backgroundStopTask");
|
||||
if (stopTask != null)
|
||||
{
|
||||
stopTask.Wait(timeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
private static OptoTelegramRaw CreateOptoRecord(int channel, double volumeRawExt, double timestampExt)
|
||||
{
|
||||
return new OptoTelegramRaw
|
||||
@@ -87,11 +98,10 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
Assert.AreEqual(DataStreamState.Flush, finalState, "Stop() should finish in Flush state.");
|
||||
Assert.IsFalse(fake.IsOpen, "Serial port should be closed by Stop().");
|
||||
|
||||
// These values are populated only if DataStreamPostProcessing() ran.
|
||||
Assert.AreEqual((11.0 + 20.0 + 30.0) / 3.0, reader.VolumeLtrStartRaw, 1e-9,
|
||||
"Expected post-processing to prepare raw start values.");
|
||||
Assert.AreEqual((15.0 + 25.0 + 35.0) / 3.0, reader.VolumeLtrEndRaw, 1e-9,
|
||||
"Expected post-processing to prepare raw end values.");
|
||||
Assert.AreEqual((11.0 + 20.0 + 30.0) / 3.0, reader.VolumeLtrStartAverage, 1e-9,
|
||||
"Expected post-processing to prepare raw/recalculated start values.");
|
||||
Assert.AreEqual((15.0 + 25.0 + 36.0) / 3.0, reader.VolumeLtrEndAwerage, 1e-9,
|
||||
"Expected post-processing to prepare recalculated end values.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -111,6 +121,7 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
reader.optoSerialPort = fake;
|
||||
|
||||
reader.Stop();
|
||||
WaitForStopToFinish(reader);
|
||||
|
||||
var finalState = GetPrivateField<DataStreamState>(reader, "dataStreamState");
|
||||
var stopQueueData = GetPrivateField<bool>(reader, "_stopQueueData");
|
||||
@@ -119,10 +130,9 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
Assert.IsTrue(stopQueueData, "Immediate stop path should stop queueing.");
|
||||
Assert.IsFalse(fake.IsOpen, "Serial port should be closed by Stop().");
|
||||
|
||||
// Should still be default because DataStreamPostProcessing() must NOT run.
|
||||
Assert.AreEqual(0.0, reader.VolumeLtrStartRaw, 1e-9,
|
||||
Assert.AreEqual(0.0, reader.VolumeLtrStartAverage, 1e-9,
|
||||
"Post-processing should not run when previous state was ProcessAndSave.");
|
||||
Assert.AreEqual(0.0, reader.VolumeLtrEndRaw, 1e-9,
|
||||
Assert.AreEqual(0.0, reader.VolumeLtrEndAwerage, 1e-9,
|
||||
"Post-processing should not run when previous state was ProcessAndSave.");
|
||||
}
|
||||
|
||||
|
||||
+107
-76
@@ -79,6 +79,15 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
reader.StopQueueData = false;
|
||||
}
|
||||
|
||||
private static void WaitForStopToFinish(GenesisSmartReader reader, int timeoutMs = 3000)
|
||||
{
|
||||
var stopTask = GetPrivateField<Task>(reader, "_backgroundStopTask");
|
||||
if (stopTask != null)
|
||||
{
|
||||
stopTask.Wait(timeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Start_ShouldOpenPort_AndEnableProcessing()
|
||||
{
|
||||
@@ -129,9 +138,10 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
reader.TestEndTelegramIx = 1;
|
||||
|
||||
reader.Stop();
|
||||
WaitForStopToFinish(reader);
|
||||
|
||||
Assert.IsFalse(fake.IsOpen);
|
||||
Assert.AreEqual(2, fake.CloseCalls);
|
||||
Assert.IsTrue(fake.CloseCalls >= 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,6 +175,9 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
reader.Initialize();
|
||||
reader.optoSerialPort = fake;
|
||||
|
||||
InitializeThreeChannelState(reader);
|
||||
EnableProcessingLoopForTests(reader);
|
||||
|
||||
bool reset;
|
||||
|
||||
reader.ProcessOptoLine("@h 1 0 0A1F59C4 00017A43 00115C45 72E1596B 00000400 00001998 7D91B652 7D4F37E6 000191E6 0C 062E4A9C 5331", DataStreamState.ProcessAndSave, out reset);
|
||||
@@ -199,6 +212,7 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
|
||||
reader.optoSerialPort = fake;
|
||||
InitializeThreeChannelState(reader);
|
||||
EnableProcessingLoopForTests(reader);
|
||||
|
||||
reader.ProcessOptoLine(line, DataStreamState.ProcessAndSave, out bool resetDataBuffer);
|
||||
|
||||
@@ -254,6 +268,7 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
|
||||
reader.optoSerialPort = fake;
|
||||
InitializeThreeChannelState(reader);
|
||||
EnableProcessingLoopForTests(reader);
|
||||
|
||||
var line =
|
||||
"@h 2 0 0A1B1FE8 00017B7F 00116B56 72B77427 00000400 0000199A 7DC09688 7B570006 000191E6 0C 062E5326 95BD";
|
||||
@@ -265,9 +280,15 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
}
|
||||
|
||||
[DataTestMethod]
|
||||
[DataRow("@h 1 0 0A1F59C4 00017A43 00115C45 72E1596B 00000400 00001998 7D91B652 7D4F37E6 000191E6 0C 062E4A9C 5331", 0)]
|
||||
[DataRow("@h 2 0 0A1B1FE8 00017B7F 00116B56 72B77427 00000400 0000199A 7DC09688 7B570006 000191E6 0C 062E5326 95BD", 1)]
|
||||
[DataRow("@h 3 0 0A1DF1D5 00017EA8 00118037 741F80F3 00000400 00001998 7E58A62E 7CC2C606 000191E6 0C 062E5BAE D40E", 2)]
|
||||
[DataRow(
|
||||
"@h 1 0 0A1F59C4 00017A43 00115C45 72E1596B 00000400 00001998 7D91B652 7D4F37E6 000191E6 0C 062E4A9C 5331",
|
||||
0)]
|
||||
[DataRow(
|
||||
"@h 2 0 0A1B1FE8 00017B7F 00116B56 72B77427 00000400 0000199A 7DC09688 7B570006 000191E6 0C 062E5326 95BD",
|
||||
1)]
|
||||
[DataRow(
|
||||
"@h 3 0 0A1DF1D5 00017EA8 00118037 741F80F3 00000400 00001998 7E58A62E 7CC2C606 000191E6 0C 062E5BAE D40E",
|
||||
2)]
|
||||
public void ProcessOptoLine_ShouldInsertTelegramAndUpdateExpectedChannel(string line, int expectedChannelIndex)
|
||||
{
|
||||
var fake = new FakeSerialDriver();
|
||||
@@ -277,6 +298,9 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
reader.Initialize();
|
||||
reader.optoSerialPort = fake;
|
||||
|
||||
InitializeThreeChannelState(reader);
|
||||
EnableProcessingLoopForTests(reader);
|
||||
|
||||
reader.ProcessOptoLine(line, DataStreamState.ProcessAndSave, out bool resetDataBuffer);
|
||||
|
||||
var volumeRawExtLast = GetPrivateField<double[]>(reader, "volumeRawExtLast");
|
||||
@@ -284,27 +308,25 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
var optoData = GetPrivateField<OptoTelegramRaw[]>(reader, "optoData");
|
||||
var optoDataCount = GetPrivateField<int>(reader, "optoDataCount");
|
||||
|
||||
Assert.AreEqual(1, optoDataCount, "Exactly one telegram should be inserted.");
|
||||
Assert.AreEqual(1, optoDataCount);
|
||||
|
||||
var inserted = optoData[0];
|
||||
Assert.IsNotNull(inserted, "Inserted telegram should not be null.");
|
||||
Assert.IsNotNull(inserted);
|
||||
|
||||
Assert.AreEqual(expectedChannelIndex, inserted.IChannel(), "Inserted telegram channel does not match expected channel.");
|
||||
Assert.AreEqual(0, inserted.Counter, "First inserted telegram should have counter 0.");
|
||||
Assert.AreEqual(OptoTelegramFlags.OK, inserted.Flags, "Inserted telegram should be marked OK.");
|
||||
Assert.AreNotEqual(default(DateTime), inserted.DateTime, "Inserted telegram DateTime should be initialized.");
|
||||
Assert.AreEqual(expectedChannelIndex, inserted.IChannel());
|
||||
Assert.AreEqual(0, inserted.Counter);
|
||||
Assert.AreEqual(OptoTelegramFlags.OK, inserted.Flags);
|
||||
|
||||
Assert.AreNotEqual(0.0, inserted.VolumeRaw, "Inserted telegram VolumeRaw should be set.");
|
||||
Assert.AreNotEqual(0.0, inserted.VolumeRawExt, "Inserted telegram VolumeRawExt should be set.");
|
||||
Assert.AreNotEqual(0.0, inserted.Timestamp, "Inserted telegram Timestamp should be set.");
|
||||
Assert.AreNotEqual(0.0, inserted.TimestampExt, "Inserted telegram TimestampExt should be set.");
|
||||
Assert.AreNotEqual(0.0, inserted.VolumeRawExt);
|
||||
Assert.AreNotEqual(0.0, inserted.TimestampExt);
|
||||
|
||||
for (int i = 0; i < ChannelCount; i++)
|
||||
{
|
||||
if (i == expectedChannelIndex)
|
||||
{
|
||||
Assert.AreNotEqual(0.0, volumeRawExtLast[i], $"Expected channel {i} volume cache was not updated.");
|
||||
Assert.AreNotEqual(0.0, timestampExtLast[i], $"Expected channel {i} timestamp cache was not updated.");
|
||||
Assert.AreNotEqual(0.0, timestampExtLast[i],
|
||||
$"Expected channel {i} timestamp cache was not updated.");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -313,11 +335,8 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
}
|
||||
}
|
||||
|
||||
Assert.AreEqual(volumeRawExtLast[expectedChannelIndex], inserted.VolumeRawExt, 1e-9,
|
||||
"Inserted telegram VolumeRawExt should match updated channel cache.");
|
||||
|
||||
Assert.AreEqual(timestampExtLast[expectedChannelIndex], inserted.TimestampExt, 1e-9,
|
||||
"Inserted telegram TimestampExt should match updated channel cache.");
|
||||
Assert.AreEqual(volumeRawExtLast[expectedChannelIndex], inserted.VolumeRawExt, 1e-9);
|
||||
Assert.AreEqual(timestampExtLast[expectedChannelIndex], inserted.TimestampExt, 1e-9);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -344,13 +363,16 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
InvokePrepareCalculatedChannelData(reader);
|
||||
|
||||
Assert.AreEqual((11.0 + 20.0 + 30.0) / 3.0, reader.VolumeLtrStart, 1e-9);
|
||||
Assert.AreEqual((15.0 + 25.0 + 35.0) / 3.0, reader.VolumeLtrEnd, 1e-9);
|
||||
Assert.AreEqual((15.0 + 25.0 + 36.0) / 3.0, reader.VolumeLtrEnd, 1e-9);
|
||||
|
||||
Assert.AreEqual(100.0, reader.TimestampSecStart, 1e-9);
|
||||
Assert.AreEqual(105.0, reader.TimestampSecEnd, 1e-9);
|
||||
|
||||
Assert.AreEqual((11.0 + 20.0 + 30.0) / 3.0, reader.VolumeLtrStartRaw, 1e-9);
|
||||
Assert.AreEqual((15.0 + 25.0 + 35.0) / 3.0, reader.VolumeLtrEndRaw, 1e-9);
|
||||
Assert.AreEqual((11.0 + 20.0 + 30.0) / 3.0, reader.VolumeLtrStartAverage, 1e-9);
|
||||
Assert.AreEqual((15.0 + 25.0 + 36.0) / 3.0, reader.VolumeLtrEndAwerage, 1e-9);
|
||||
|
||||
Assert.AreEqual((11.0 + 20.0 + 30.0) / 3.0, reader.VolumeLtrStartRawRaw, 1e-9);
|
||||
Assert.AreEqual((15.0 + 25.0 + 35.0) / 3.0, reader.VolumeLtrEndRawRaw, 1e-9);
|
||||
}
|
||||
|
||||
private static OptoTelegramRaw CreateOptoRecord(int channel, double volumeRawExt, double timestampExt)
|
||||
@@ -388,7 +410,21 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
InvokePrepareCalculatedChannelData(reader);
|
||||
|
||||
Assert.AreEqual(15.5, reader.VolumeLtrStart, 1e-9);
|
||||
Assert.AreEqual(19.0, reader.VolumeLtrEnd, 1e-9);
|
||||
Assert.AreEqual(19.5, reader.VolumeLtrEnd, 1e-9);
|
||||
|
||||
Assert.AreEqual(15.5, reader.VolumeLtrStartAverage, 1e-9);
|
||||
Assert.AreEqual(19.5, reader.VolumeLtrEndAwerage, 1e-9);
|
||||
|
||||
Assert.AreEqual(15.5, reader.VolumeLtrStartRawRaw, 1e-9);
|
||||
Assert.AreEqual(19.0, reader.VolumeLtrEndRawRaw, 1e-9);
|
||||
|
||||
Assert.AreEqual(11.0, reader.VolumeLtrStartRawCh1, 1e-9);
|
||||
Assert.AreEqual(20.0, reader.VolumeLtrStartRawCh2, 1e-9);
|
||||
Assert.AreEqual(0.0, reader.VolumeLtrStartRawCh3, 1e-9);
|
||||
|
||||
Assert.AreEqual(14.0, reader.VolumeLtrEndRawCh1, 1e-9);
|
||||
Assert.AreEqual(24.0, reader.VolumeLtrEndRawCh2, 1e-9);
|
||||
Assert.AreEqual(0.0, reader.VolumeLtrEndRawCh3, 1e-9);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -425,39 +461,37 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ReadOptoData_FullBlock_ShouldDiscardBuffersAfterClosingF()
|
||||
public void ProcessingLoop_FullBlock_ShouldDiscardBuffersAfterClosingF()
|
||||
{
|
||||
var fake = new FakeSerialDriver();
|
||||
|
||||
fake.EnqueueLine("@f AA754B 4D0CEE78 5D89");
|
||||
fake.EnqueueLine("@h 1 0 0A1F59C4 00017A43 00115C45 72E1596B 00000400 00001998 7D91B652 7D4F37E6 000191E6 0C 062E4A9C 5331");
|
||||
fake.EnqueueLine("@h 2 0 0A1B1FE8 00017B7F 00116B56 72B77427 00000400 0000199A 7DC09688 7B570006 000191E6 0C 062E5326 95BD");
|
||||
fake.EnqueueLine("@h 3 0 0A1DF1D5 00017EA8 00118037 741F80F3 00000400 00001998 7E58A62E 7CC2C606 000191E6 0C 062E5BAE D40E");
|
||||
fake.EnqueueLine("@f AA7C01 4D0CFE76 B08F");
|
||||
fake.Open();
|
||||
|
||||
var reader = new GenesisSmartReader(CreateCfg(), () => fake);
|
||||
reader.Initialize();
|
||||
|
||||
fake.Open();
|
||||
reader.optoSerialPort = fake;
|
||||
reader.ResetAfterBlockRepetitions = 1;
|
||||
|
||||
var readMethod = typeof(GenesisSmartReader).GetMethod(
|
||||
"ReadOptoData",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic,
|
||||
null,
|
||||
new[] { typeof(DataStreamState) },
|
||||
null);
|
||||
InitializeThreeChannelState(reader);
|
||||
EnableProcessingLoopForTests(reader);
|
||||
|
||||
Assert.IsNotNull(readMethod);
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
reader.StartProcessingLoop();
|
||||
try
|
||||
{
|
||||
readMethod.Invoke(reader, new object[] { DataStreamState.ProcessAndSave });
|
||||
}
|
||||
reader.TestEnqueueLine("@f AA754B 4D0CEE78 5D89");
|
||||
reader.TestEnqueueLine("@h 1 0 0A1F59C4 00017A43 00115C45 72E1596B 00000400 00001998 7D91B652 7D4F37E6 000191E6 0C 062E4A9C 5331");
|
||||
reader.TestEnqueueLine("@h 2 0 0A1B1FE8 00017B7F 00116B56 72B77427 00000400 0000199A 7DC09688 7B570006 000191E6 0C 062E5326 95BD");
|
||||
reader.TestEnqueueLine("@h 3 0 0A1DF1D5 00017EA8 00118037 741F80F3 00000400 00001998 7E58A62E 7CC2C606 000191E6 0C 062E5BAE D40E");
|
||||
reader.TestEnqueueLine("@f AA7C01 4D0CFE76 B08F");
|
||||
|
||||
Assert.AreEqual(1, fake.DiscardInCalls, "Input buffer should be discarded once after completed block.");
|
||||
Assert.AreEqual(1, fake.DiscardOutCalls, "Output buffer should be discarded once after completed block.");
|
||||
Thread.Sleep(300);
|
||||
|
||||
Assert.AreEqual(1, fake.DiscardInCalls, "Input buffer should be discarded once after completed block.");
|
||||
Assert.AreEqual(1, fake.DiscardOutCalls, "Output buffer should be discarded once after completed block.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader.StopProcessingLoop();
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -471,10 +505,13 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
reader.optoSerialPort = fake;
|
||||
reader.ResetAfterBlockRepetitions = 1;
|
||||
|
||||
InitializeThreeChannelState(reader);
|
||||
EnableProcessingLoopForTests(reader);
|
||||
|
||||
bool reset;
|
||||
|
||||
reader.ProcessOptoLine("@f AA754B 4D0CEE78 5D89", DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset, "Opening @f must not reset buffers.");
|
||||
Assert.IsFalse(reset);
|
||||
|
||||
reader.ProcessOptoLine("@h 1 0 0A1F59C4 00017A43 00115C45 72E1596B 00000400 00001998 7D91B652 7D4F37E6 000191E6 0C 062E4A9C 5331", DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset);
|
||||
@@ -529,24 +566,24 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
reader.optoSerialPort = fake;
|
||||
reader.ResetAfterBlockRepetitions = 3;
|
||||
|
||||
InitializeThreeChannelState(reader);
|
||||
EnableProcessingLoopForTests(reader);
|
||||
|
||||
bool reset;
|
||||
|
||||
for (int repetition = 1; repetition <= 3; repetition++)
|
||||
{
|
||||
reader.ProcessOptoLine("@f AA754B 4D0CEE78 5D89", DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset, "Reset must not happen on opening @f, repetition " + repetition);
|
||||
Assert.IsFalse(reset);
|
||||
|
||||
reader.ProcessOptoLine("@h 1 0 0A1F59C4 00017A43 00115C45 72E1596B 00000400 00001998 7D91B652 7D4F37E6 000191E6 0C 062E4A9C 5331",
|
||||
DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset, "Reset must not happen after @h1, repetition " + repetition);
|
||||
reader.ProcessOptoLine("@h 1 0 0A1F59C4 00017A43 00115C45 72E1596B 00000400 00001998 7D91B652 7D4F37E6 000191E6 0C 062E4A9C 5331", DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset);
|
||||
|
||||
reader.ProcessOptoLine("@h 2 0 0A1B1FE8 00017B7F 00116B56 72B77427 00000400 0000199A 7DC09688 7B570006 000191E6 0C 062E5326 95BD",
|
||||
DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset, "Reset must not happen after @h2, repetition " + repetition);
|
||||
reader.ProcessOptoLine("@h 2 0 0A1B1FE8 00017B7F 00116B56 72B77427 00000400 0000199A 7DC09688 7B570006 000191E6 0C 062E5326 95BD", DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset);
|
||||
|
||||
reader.ProcessOptoLine("@h 3 0 0A1DF1D5 00017EA8 00118037 741F80F3 00000400 00001998 7E58A62E 7CC2C606 000191E6 0C 062E5BAE D40E",
|
||||
DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset, "Reset must not happen after @h3, repetition " + repetition);
|
||||
reader.ProcessOptoLine("@h 3 0 0A1DF1D5 00017EA8 00118037 741F80F3 00000400 00001998 7E58A62E 7CC2C606 000191E6 0C 062E5BAE D40E", DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset);
|
||||
|
||||
reader.ProcessOptoLine("@f AA7C01 4D0CFE76 B08F", DataStreamState.ProcessAndSave, out reset);
|
||||
|
||||
@@ -568,24 +605,24 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
reader.optoSerialPort = fake;
|
||||
reader.ResetAfterBlockRepetitions = 5;
|
||||
|
||||
InitializeThreeChannelState(reader);
|
||||
EnableProcessingLoopForTests(reader);
|
||||
|
||||
bool reset;
|
||||
|
||||
for (int repetition = 1; repetition <= 5; repetition++)
|
||||
{
|
||||
reader.ProcessOptoLine("@f AA754B 4D0CEE78 5D89", DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset, "Reset must not happen on opening @f, repetition " + repetition);
|
||||
Assert.IsFalse(reset);
|
||||
|
||||
reader.ProcessOptoLine("@h 1 0 0A1F59C4 00017A43 00115C45 72E1596B 00000400 00001998 7D91B652 7D4F37E6 000191E6 0C 062E4A9C 5331",
|
||||
DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset, "Reset must not happen after @h1, repetition " + repetition);
|
||||
reader.ProcessOptoLine("@h 1 0 0A1F59C4 00017A43 00115C45 72E1596B 00000400 00001998 7D91B652 7D4F37E6 000191E6 0C 062E4A9C 5331", DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset);
|
||||
|
||||
reader.ProcessOptoLine("@h 2 0 0A1B1FE8 00017B7F 00116B56 72B77427 00000400 0000199A 7DC09688 7B570006 000191E6 0C 062E5326 95BD",
|
||||
DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset, "Reset must not happen after @h2, repetition " + repetition);
|
||||
reader.ProcessOptoLine("@h 2 0 0A1B1FE8 00017B7F 00116B56 72B77427 00000400 0000199A 7DC09688 7B570006 000191E6 0C 062E5326 95BD", DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset);
|
||||
|
||||
reader.ProcessOptoLine("@h 3 0 0A1DF1D5 00017EA8 00118037 741F80F3 00000400 00001998 7E58A62E 7CC2C606 000191E6 0C 062E5BAE D40E",
|
||||
DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset, "Reset must not happen after @h3, repetition " + repetition);
|
||||
reader.ProcessOptoLine("@h 3 0 0A1DF1D5 00017EA8 00118037 741F80F3 00000400 00001998 7E58A62E 7CC2C606 000191E6 0C 062E5BAE D40E", DataStreamState.ProcessAndSave, out reset);
|
||||
Assert.IsFalse(reset);
|
||||
|
||||
reader.ProcessOptoLine("@f AA7C01 4D0CFE76 B08F", DataStreamState.ProcessAndSave, out reset);
|
||||
|
||||
@@ -742,18 +779,12 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
Assert.AreEqual(20.0, sut.TimestampSecEndCh2, 0.0001);
|
||||
Assert.AreEqual(20.0, sut.TimestampSecEndCh3, 0.0001);
|
||||
|
||||
Assert.AreEqual(105.0, sut.VolumeLtrStartRaw, 0.0001);
|
||||
Assert.AreEqual(157.0, sut.VolumeLtrEndRaw, 0.0001);
|
||||
Assert.AreEqual(105.0, sut.VolumeLtrStartAverage, 0.0001);
|
||||
Assert.AreEqual(157.0, sut.VolumeLtrEndAwerage, 0.0001);
|
||||
|
||||
Assert.AreEqual(10.0, sut.TimestampSecStart, 0.0001);
|
||||
Assert.AreEqual(20.0, sut.TimestampSecEnd, 0.0001);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void METHOD()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+260
-28
@@ -10,22 +10,33 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
[TestClass]
|
||||
public class GenesisSmartReader_Q3Test
|
||||
{
|
||||
private static readonly double[] ValidInitFactors = { 15625.0, 15625.0, 15625.0 };
|
||||
|
||||
[TestMethod]
|
||||
public void GetQ3Calibration_ShouldReturnInvalid_WhenRawDataIsNull()
|
||||
public void GetQ3Calibration_ShouldRemainInvalid_WhenRawDataIsNull()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
InitializeReaderForQ3Test(sut);
|
||||
|
||||
SetPrivateField(sut, "_rawStartEndByChannel", null);
|
||||
|
||||
sut.GetQ3Calibration(refVolume: 1000.0, refTime: 120.0, initCalibFactor: 15625.0);
|
||||
var valid = new bool[3];
|
||||
var calib = new double[3];
|
||||
|
||||
sut.GetQ3Calibration(
|
||||
refVolume: 1000.0,
|
||||
refTime: 120.0,
|
||||
initCalibFactor: ValidInitFactors,
|
||||
ref valid,
|
||||
ref calib);
|
||||
|
||||
Assert.IsFalse(sut.Q3CalibValid);
|
||||
Assert.AreEqual(0.0, sut.Q3CalibValue, 0.000001);
|
||||
CollectionAssert.AreEqual(new[] { false, false, false }, valid);
|
||||
CollectionAssert.AreEqual(new[] { 0.0, 0.0, 0.0 }, calib);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetQ3Calibration_ShouldReturnInvalid_WhenNoSamplesConditionIsTrue()
|
||||
public void GetQ3Calibration_ShouldRemainInvalid_WhenNoSamplesIsTrue()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
InitializeReaderForQ3Test(sut);
|
||||
@@ -34,69 +45,255 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
|
||||
Assert.IsTrue(sut.NoSamples, "Expected NoSamples to be true for this test.");
|
||||
|
||||
sut.GetQ3Calibration(refVolume: 1000.0, refTime: 120.0, initCalibFactor: 15625.0);
|
||||
var valid = new bool[3];
|
||||
var calib = new double[3];
|
||||
|
||||
sut.GetQ3Calibration(
|
||||
refVolume: 1000.0,
|
||||
refTime: 120.0,
|
||||
initCalibFactor: ValidInitFactors,
|
||||
ref valid,
|
||||
ref calib);
|
||||
|
||||
Assert.IsFalse(sut.Q3CalibValid);
|
||||
Assert.AreEqual(0.0, sut.Q3CalibValue, 0.000001);
|
||||
CollectionAssert.AreEqual(new[] { false, false, false }, valid);
|
||||
CollectionAssert.AreEqual(new[] { 0.0, 0.0, 0.0 }, calib);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetQ3Calibration_ShouldReturnInvalid_WhenRefVolumeIsZero()
|
||||
public void GetQ3Calibration_ShouldRemainInvalid_WhenRefVolumeIsZero()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
|
||||
InvokePrivateByName(sut, "PrepareCalculatedChannelDataForTest", true);
|
||||
Assert.IsFalse(sut.NoSamples);
|
||||
|
||||
Assert.IsFalse(sut.NoSamples, "Prepared data should produce valid samples.");
|
||||
var valid = new bool[3];
|
||||
var calib = new double[3];
|
||||
|
||||
sut.GetQ3Calibration(refVolume: 0.0, refTime: 120.0, initCalibFactor: 15625.0);
|
||||
sut.GetQ3Calibration(
|
||||
refVolume: 0.0,
|
||||
refTime: 120.0,
|
||||
initCalibFactor: ValidInitFactors,
|
||||
ref valid,
|
||||
ref calib);
|
||||
|
||||
Assert.IsFalse(sut.Q3CalibValid);
|
||||
Assert.AreEqual(0.0, sut.Q3CalibValue, 0.000001);
|
||||
CollectionAssert.AreEqual(new[] { false, false, false }, valid);
|
||||
CollectionAssert.AreEqual(new[] { 0.0, 0.0, 0.0 }, calib);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetQ3Calibration_ShouldReturnInvalid_WhenRefTimeIsZero()
|
||||
public void GetQ3Calibration_ShouldRemainInvalid_WhenRefTimeIsZero()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
|
||||
InvokePrivateByName(sut, "PrepareCalculatedChannelDataForTest", true);
|
||||
Assert.IsFalse(sut.NoSamples);
|
||||
|
||||
Assert.IsFalse(sut.NoSamples, "Prepared data should produce valid samples.");
|
||||
var valid = new bool[3];
|
||||
var calib = new double[3];
|
||||
|
||||
sut.GetQ3Calibration(refVolume: 1000.0, refTime: 0.0, initCalibFactor: 15625.0);
|
||||
sut.GetQ3Calibration(
|
||||
refVolume: 1000.0,
|
||||
refTime: 0.0,
|
||||
initCalibFactor: ValidInitFactors,
|
||||
ref valid,
|
||||
ref calib);
|
||||
|
||||
Assert.IsFalse(sut.Q3CalibValid);
|
||||
Assert.AreEqual(0.0, sut.Q3CalibValue, 0.000001);
|
||||
CollectionAssert.AreEqual(new[] { false, false, false }, valid);
|
||||
CollectionAssert.AreEqual(new[] { 0.0, 0.0, 0.0 }, calib);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetQ3Calibration_ShouldReturnInvalid_WhenInitCalibFactorIsZero()
|
||||
public void GetQ3Calibration_ShouldMarkInvalid_WhenInitFactorsAreZero()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
|
||||
InvokePrivateByName(sut, "PrepareCalculatedChannelDataForTest", true);
|
||||
Assert.IsFalse(sut.NoSamples);
|
||||
|
||||
Assert.IsFalse(sut.NoSamples, "Prepared data should produce valid samples.");
|
||||
var init = new[] { 0.0, 0.0, 0.0 };
|
||||
var valid = new bool[3];
|
||||
var calib = new double[3];
|
||||
|
||||
sut.GetQ3Calibration(refVolume: 1000.0, refTime: 120.0, initCalibFactor: 0.0);
|
||||
sut.GetQ3Calibration(
|
||||
refVolume: 1000.0,
|
||||
refTime: 120.0,
|
||||
initCalibFactor: init,
|
||||
ref valid,
|
||||
ref calib);
|
||||
|
||||
Assert.IsFalse(sut.Q3CalibValid);
|
||||
Assert.AreEqual(0.0, sut.Q3CalibValue, 0.000001);
|
||||
CollectionAssert.AreEqual(new[] { false, false, false }, valid);
|
||||
CollectionAssert.AreEqual(new[] { 0.0, 0.0, 0.0 }, calib);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetQ3Calibration_ShouldProduceNonNegativeResult_WithPreparedSimulationData()
|
||||
public void CalculateQ3Calibration_ShouldPopulatePerChannelValues_WithPreparedSimulationData()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
|
||||
InvokePrivateByName(sut, "PrepareCalculatedChannelDataForTest", true);
|
||||
InvokePrivateByName(sut, "SetQ3Calibration", new object[] { ValidInitFactors });
|
||||
|
||||
Assert.IsFalse(sut.NoSamples, "Prepared data should produce valid samples.");
|
||||
Assert.IsFalse(sut.NoSamples);
|
||||
|
||||
sut.GetQ3Calibration(refVolume: 1.0, refTime: 120.0, initCalibFactor: 15625.0);
|
||||
sut.CalculateQ3Calibration(200.0, 120.0);
|
||||
|
||||
Assert.IsTrue(sut.Q3CalibValue >= 0.0);
|
||||
Assert.IsNotNull(sut.Q3CalibValue);
|
||||
Assert.AreEqual(3, sut.Q3CalibValue.Length);
|
||||
|
||||
Assert.IsTrue(sut.Q3CalibValue.All(v => !Double.IsNaN(v)));
|
||||
Assert.IsTrue(sut.Q3CalibValue.All(v => v >= 0.0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetQ3Calibration_ShouldCalculateExpectedValues_ForKnownInput()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
|
||||
var raw = CreateKnownStartEndData(
|
||||
// start volume / end volume / start time / end time
|
||||
(100.0, 150.0, 10.0, 20.0), // dV = 50, dT = 10
|
||||
(105.0, 165.0, 10.0, 22.0), // dV = 60, dT = 12
|
||||
(110.0, 180.0, 10.0, 25.0) // dV = 70, dT = 15
|
||||
);
|
||||
|
||||
SetPrivateField(sut, "_rawStartEndByChannel", raw);
|
||||
SetPrivateField(sut, "_recalculatedStartEndByChannel", raw); // important for NoSamples == false
|
||||
SetPrivateField(sut, "optoDataCount", 2);
|
||||
|
||||
sut.TestStartTelegramIx = 0;
|
||||
sut.TestEndTelegramIx = 1;
|
||||
|
||||
Assert.IsFalse(sut.NoSamples, "Expected prepared data to produce valid samples.");
|
||||
|
||||
var init = new[] { 15625.0, 15625.0, 15625.0 };
|
||||
var valid = new bool[3];
|
||||
var calib = new double[3];
|
||||
|
||||
sut.GetQ3Calibration(
|
||||
refVolume: 200.0,
|
||||
refTime: 120.0,
|
||||
initCalibFactor: init,
|
||||
ref valid,
|
||||
ref calib);
|
||||
|
||||
double expectedCh1 = (200.0 / 600.0) * 15625.0;
|
||||
double expectedCh2 = (200.0 / 600.0) * 15625.0;
|
||||
double expectedCh3 = (200.0 / 560.0) * 15625.0;
|
||||
|
||||
Assert.AreEqual(expectedCh1, calib[0], 0.0001);
|
||||
Assert.AreEqual(expectedCh2, calib[1], 0.0001);
|
||||
Assert.AreEqual(expectedCh3, calib[2], 0.0001);
|
||||
|
||||
Assert.IsFalse(valid[0]);
|
||||
Assert.IsFalse(valid[1]);
|
||||
Assert.IsFalse(valid[2]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetQ3Calibration_ShouldMarkChannelValid_WhenDifferenceIsWithinFivePercent()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
|
||||
// We want recalculatedDeltaVolume == refVolume, so calculated factor == initial factor.
|
||||
// refVolume = 200, refTime = 120
|
||||
// choose dT = 10, dV = 16.6666666666667 => coef = 12 => recalculated dV = 200
|
||||
|
||||
var raw = CreateKnownStartEndData(
|
||||
(100.0, 116.6666666666667, 10.0, 20.0),
|
||||
(200.0, 216.6666666666667, 10.0, 20.0),
|
||||
(300.0, 316.6666666666667, 10.0, 20.0)
|
||||
);
|
||||
|
||||
SetPrivateField(sut, "_rawStartEndByChannel", raw);
|
||||
SetPrivateField(sut, "_recalculatedStartEndByChannel", raw);
|
||||
SetPrivateField(sut, "optoDataCount", 2);
|
||||
sut.TestStartTelegramIx = 0;
|
||||
sut.TestEndTelegramIx = 1;
|
||||
|
||||
Assert.IsFalse(sut.NoSamples, "Expected prepared data to produce valid samples.");
|
||||
|
||||
var init = new[] { 15625.0, 15625.0, 15625.0 };
|
||||
var valid = new bool[3];
|
||||
var calib = new double[3];
|
||||
|
||||
sut.GetQ3Calibration(
|
||||
refVolume: 200.0,
|
||||
refTime: 120.0,
|
||||
initCalibFactor: init,
|
||||
ref valid,
|
||||
ref calib);
|
||||
|
||||
Assert.IsTrue(valid[0], $"Ch1 invalid, value={calib[0]}");
|
||||
Assert.IsTrue(valid[1], $"Ch2 invalid, value={calib[1]}");
|
||||
Assert.IsTrue(valid[2], $"Ch3 invalid, value={calib[2]}");
|
||||
|
||||
Assert.AreEqual(15625.0, calib[0], 0.001);
|
||||
Assert.AreEqual(15625.0, calib[1], 0.001);
|
||||
Assert.AreEqual(15625.0, calib[2], 0.001);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CalculateQ3Calibration_ShouldComputeExpectedChannelValues_FromSimulationData()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
|
||||
InvokePrivateByName(sut, "PrepareCalculatedChannelDataForTest", true);
|
||||
InvokePrivateByName(sut, "SetQ3Calibration", new object[] { ValidInitFactors });
|
||||
|
||||
sut.CalculateQ3Calibration(200.0, 120.0);
|
||||
|
||||
// initial values remain exposed through Q3CalibValue
|
||||
Assert.AreEqual(15625.0, sut.Q3CalibValue[0], 0.000001);
|
||||
Assert.AreEqual(15625.0, sut.Q3CalibValue[1], 0.000001);
|
||||
Assert.AreEqual(15625.0, sut.Q3CalibValue[2], 0.000001);
|
||||
|
||||
// calculated values
|
||||
Assert.AreEqual(5208.33333333333, sut.Q3Calib_Ch1Value, 0.000001);
|
||||
Assert.AreEqual(5008.01282051282, sut.Q3Calib_Ch2Value, 0.000001);
|
||||
Assert.AreEqual(4822.53086419753, sut.Q3Calib_Ch3Value, 0.000001);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CalculateQ3Calibration_ShouldKeepInitialArray_AndUpdateCalculatedChannelProperties()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
|
||||
InvokePrivateByName(sut, "PrepareCalculatedChannelDataForTest", true);
|
||||
InvokePrivateByName(sut, "SetQ3Calibration", new object[] { ValidInitFactors });
|
||||
|
||||
sut.CalculateQ3Calibration(200.0, 120.0);
|
||||
|
||||
// Q3CalibValue currently exposes INITIAL calibration values, not calculated ones
|
||||
Assert.AreEqual(15625.0, sut.Q3CalibValue[0], 0.000001);
|
||||
Assert.AreEqual(15625.0, sut.Q3CalibValue[1], 0.000001);
|
||||
Assert.AreEqual(15625.0, sut.Q3CalibValue[2], 0.000001);
|
||||
|
||||
// Per-channel public properties expose calculated values
|
||||
Assert.IsTrue(sut.Q3Calib_Ch1Value > 0.0);
|
||||
Assert.IsTrue(sut.Q3Calib_Ch2Value > 0.0);
|
||||
Assert.IsTrue(sut.Q3Calib_Ch3Value > 0.0);
|
||||
|
||||
Assert.AreNotEqual(sut.Q3CalibValue[0], sut.Q3Calib_Ch1Value, 0.000001);
|
||||
Assert.AreNotEqual(sut.Q3CalibValue[1], sut.Q3Calib_Ch2Value, 0.000001);
|
||||
Assert.AreNotEqual(sut.Q3CalibValue[2], sut.Q3Calib_Ch3Value, 0.000001);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PrepareCalculatedChannelDataSimulationForTest_ShouldPrepareUsableData()
|
||||
{
|
||||
var sut = new GenesisSmartReader();
|
||||
|
||||
InvokePrivateByName(sut, "PrepareCalculatedChannelDataSimulationForTest");
|
||||
|
||||
Assert.IsFalse(sut.NoSamples);
|
||||
Assert.IsTrue(sut.VolumeLtrStart >= 0.0);
|
||||
Assert.IsTrue(sut.VolumeLtrEnd >= 0.0);
|
||||
Assert.IsTrue(sut.TimestampSecEnd >= sut.TimestampSecStart);
|
||||
}
|
||||
|
||||
private static void InitializeReaderForQ3Test(GenesisSmartReader reader)
|
||||
@@ -115,20 +312,55 @@ namespace TBFTests.Rig.RegisterReaders.GenesisRegReader.implementations
|
||||
{
|
||||
new[]
|
||||
{
|
||||
CreateRecord(0.0, 0.0),
|
||||
CreateRecord(15625.0, 120.0)
|
||||
CreateRecord(0.0, 0.0, 1),
|
||||
CreateRecord(15625.0, 120.0, 1)
|
||||
},
|
||||
new OptoTelegramRaw[2],
|
||||
new OptoTelegramRaw[2]
|
||||
new[]
|
||||
{
|
||||
CreateRecord(0.0, 0.0, 2),
|
||||
CreateRecord(15625.0, 120.0, 2)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
CreateRecord(0.0, 0.0, 3),
|
||||
CreateRecord(15625.0, 120.0, 3)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static OptoTelegramRaw CreateRecord(double volumeRawExt, double timestampExt)
|
||||
private static OptoTelegramRaw[][] CreateKnownStartEndData(
|
||||
(double startVolume, double endVolume, double startTime, double endTime) ch1,
|
||||
(double startVolume, double endVolume, double startTime, double endTime) ch2,
|
||||
(double startVolume, double endVolume, double startTime, double endTime) ch3)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new[]
|
||||
{
|
||||
CreateRecord(ch1.startVolume, ch1.startTime, 1),
|
||||
CreateRecord(ch1.endVolume, ch1.endTime, 1)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
CreateRecord(ch2.startVolume, ch2.startTime, 2),
|
||||
CreateRecord(ch2.endVolume, ch2.endTime, 2)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
CreateRecord(ch3.startVolume, ch3.startTime, 3),
|
||||
CreateRecord(ch3.endVolume, ch3.endTime, 3)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static OptoTelegramRaw CreateRecord(double volumeRawExt, double timestampExt, int channel)
|
||||
{
|
||||
return new OptoTelegramRaw
|
||||
{
|
||||
VolumeRawExt = volumeRawExt,
|
||||
TimestampExt = timestampExt
|
||||
TimestampExt = timestampExt,
|
||||
iChannel = channel,
|
||||
Flags = OptoTelegramFlags.OK
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -12,35 +12,36 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
[TestSubject(typeof(CliRunner))]
|
||||
public class CliRunnerTest
|
||||
{
|
||||
|
||||
[TestMethod]
|
||||
public void ExtractJson_Test()
|
||||
{
|
||||
String allOutput = " {\n \"DeviceId\": \"1000000267\"\n}\n";
|
||||
string allOutput = " {\n \"DeviceId\": \"1000000267\"\n}\n";
|
||||
CliRunner cliRunner = new CliRunner(false);
|
||||
string json = cliRunner.ExtractJson(allOutput);
|
||||
|
||||
Assert.IsTrue(!string.IsNullOrEmpty(json));
|
||||
|
||||
Assert.IsFalse(string.IsNullOrEmpty(json));
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void ExtractJson_Test2()
|
||||
{
|
||||
String allOutput = "{\n \"NfcTagDetected\": true,\n \"ProductType\": 74,\n \"ProductTypeVersion\": \"B1.0.13\",\n \"DeviceId\": \"1000000267\",\n \"Reading\": \"0003292.1\",\n \"Reading_Totalizer\": \"000329218\",\n \"Reading_Digits\": \"8\",\n \"Reading_Shift\": \"-1\",\n \"Reading_Resolution\": \"-2\",\n \"Reading_Units\": \"2\",\n \"Reading_FlowDirection\": \"3\",\n \"Reading_FlowRate\": \"0\",\n \"CalibrationFactor\": \"3197\",\n \"ReadingComplete\": true,\n \"MeterState\": \"0x02\",\n \"OpticalDataMode\": \"0x00\",\n \"SpreadSpectrumParameters\": \"Disabled: 0xTrue\",\n \"BuildInformation\": \"\"\n}\n";
|
||||
string allOutput = "{\n \"NfcTagDetected\": true,\n \"ProductType\": 74,\n \"ProductTypeVersion\": \"B1.0.13\",\n \"DeviceId\": \"1000000267\",\n \"Reading\": \"0003292.1\",\n \"Reading_Totalizer\": \"000329218\",\n \"Reading_Digits\": \"8\",\n \"Reading_Shift\": \"-1\",\n \"Reading_Resolution\": \"-2\",\n \"Reading_Units\": \"2\",\n \"Reading_FlowDirection\": \"3\",\n \"Reading_FlowRate\": \"0\",\n \"CalibrationFactor\": \"3197\",\n \"ReadingComplete\": true,\n \"MeterState\": \"0x02\",\n \"OpticalDataMode\": \"0x00\",\n \"SpreadSpectrumParameters\": \"Disabled: 0xTrue\",\n \"BuildInformation\": \"\"\n}\n";
|
||||
CliRunner cliRunner = new CliRunner(false);
|
||||
string json = cliRunner.ExtractJson(allOutput);
|
||||
|
||||
Assert.IsTrue(!string.IsNullOrEmpty(json));
|
||||
|
||||
Assert.IsFalse(string.IsNullOrEmpty(json));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TryJsonStringDeserialize_Test()
|
||||
{
|
||||
String allOutput = "{\n \"NfcTagDetected\": true,\n \"ProductType\": 74,\n \"ProductTypeVersion\": \"B1.0.13\",\n \"DeviceId\": \"1000000267\",\n \"Reading\": \"0003292.1\",\n \"Reading_Totalizer\": \"000329218\",\n \"Reading_Digits\": \"8\",\n \"Reading_Shift\": \"-1\",\n \"Reading_Resolution\": \"-2\",\n \"Reading_Units\": \"2\",\n \"Reading_FlowDirection\": \"3\",\n \"Reading_FlowRate\": \"0\",\n \"CalibrationFactor\": \"3197\",\n \"ReadingComplete\": true,\n \"MeterState\": \"0x02\",\n \"OpticalDataMode\": \"0x00\",\n \"SpreadSpectrumParameters\": \"Disabled: 0xTrue\",\n \"BuildInformation\": \"\"\n}\n";
|
||||
string allOutput = "{\n \"NfcTagDetected\": true,\n \"ProductType\": 74,\n \"ProductTypeVersion\": \"B1.0.13\",\n \"DeviceId\": \"1000000267\",\n \"Reading\": \"0003292.1\",\n \"Reading_Totalizer\": \"000329218\",\n \"Reading_Digits\": \"8\",\n \"Reading_Shift\": \"-1\",\n \"Reading_Resolution\": \"-2\",\n \"Reading_Units\": \"2\",\n \"Reading_FlowDirection\": \"3\",\n \"Reading_FlowRate\": \"0\",\n \"CalibrationFactor\": \"3197\",\n \"ReadingComplete\": true,\n \"MeterState\": \"0x02\",\n \"OpticalDataMode\": \"0x00\",\n \"SpreadSpectrumParameters\": \"Disabled: 0xTrue\",\n \"BuildInformation\": \"\"\n}\n";
|
||||
|
||||
CliRunner cliRunner = new CliRunner(false);
|
||||
string json = cliRunner.ExtractJson(allOutput);
|
||||
|
||||
var ok = cliRunner.TryJsonStringDeserialize<JsonDataFromPoseidon>(json, out var dto);
|
||||
bool ok = cliRunner.TryJsonStringDeserialize<JsonDataFromPoseidon>(json, out var dto);
|
||||
|
||||
Assert.IsTrue(ok, "Deserialization failed");
|
||||
Assert.IsNotNull(dto);
|
||||
Assert.AreEqual("1000000267", dto.DeviceId);
|
||||
@@ -53,120 +54,165 @@ namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
[TestMethod]
|
||||
public void RunMultipleTimesTestProgram_CheckParalelWork()
|
||||
{
|
||||
SerialPortData serialPort = new SerialPortData("COM3","cmdSleepTest.exe",74);
|
||||
|
||||
// Check if the executable exists in current directory
|
||||
SerialPortData serialPort = new SerialPortData("COM3", "cmdSleepTest.exe", 74);
|
||||
|
||||
if (!System.IO.File.Exists(serialPort.SerialPortCmdClientPath))
|
||||
{
|
||||
Assert.Inconclusive($"Test executable '{serialPort.SerialPortCmdClientPath}' not found. Please ensure cmdSleepTest.exe exists in the test directory.");
|
||||
Assert.Inconclusive(
|
||||
$"Test executable '{serialPort.SerialPortCmdClientPath}' not found. Please ensure cmdSleepTest.exe exists in the test directory.");
|
||||
return;
|
||||
}
|
||||
|
||||
CliRunner cliRunner = new CliRunner(false);
|
||||
|
||||
|
||||
CliRunner cliRunnerOne = new CliRunner(false);
|
||||
DateTime StartTime = DateTime.Now;
|
||||
cliRunnerOne.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
DateTime startTime = DateTime.Now;
|
||||
|
||||
cliRunnerOne.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(
|
||||
serialPort,
|
||||
SerialPortData.EMeterArg.AllParams);
|
||||
|
||||
cliRunnerOne.WaitAll();
|
||||
TimeSpan OneEndTime = DateTime.Now - StartTime;
|
||||
|
||||
StartTime = DateTime.Now;
|
||||
Console.WriteLine($"Start Time Loop: {StartTime.ToString("yyyy-MM-dd HH:mm:ss")}");
|
||||
|
||||
|
||||
TimeSpan oneEndTime = DateTime.Now - startTime;
|
||||
|
||||
startTime = DateTime.Now;
|
||||
Console.WriteLine($"Start Time Loop: {startTime:yyyy-MM-dd HH:mm:ss}");
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(
|
||||
serialPort,
|
||||
SerialPortData.EMeterArg.AllParams);
|
||||
}
|
||||
|
||||
cliRunner.WaitAll();
|
||||
|
||||
DateTime EndTime = DateTime.Now;
|
||||
Console.WriteLine($"End Time Loop: {EndTime.ToString("yyyy-MM-dd HH:mm:ss")}");
|
||||
TimeSpan delta = EndTime - StartTime;
|
||||
Console.WriteLine($"Delta Time One process {OneEndTime.Hours:D2}:{OneEndTime.Minutes:D2}:{OneEndTime.Seconds:D2}.{OneEndTime.Milliseconds:D3} " +
|
||||
$"vs Loop: {delta.Hours:D2}:{delta.Minutes:D2}:{delta.Seconds:D2}.{delta.Milliseconds:D3}");
|
||||
DateTime endTime = DateTime.Now;
|
||||
Console.WriteLine($"End Time Loop: {endTime:yyyy-MM-dd HH:mm:ss}");
|
||||
|
||||
TimeSpan delta = endTime - startTime;
|
||||
Console.WriteLine(
|
||||
$"Delta Time One process {oneEndTime.Hours:D2}:{oneEndTime.Minutes:D2}:{oneEndTime.Seconds:D2}.{oneEndTime.Milliseconds:D3} " +
|
||||
$"vs Loop: {delta.Hours:D2}:{delta.Minutes:D2}:{delta.Seconds:D2}.{delta.Milliseconds:D3}");
|
||||
Console.WriteLine($"Total tasks: {cliRunner.TaskPool.Count}");
|
||||
|
||||
|
||||
foreach (Task<JsonDataFromPoseidon> task in cliRunner.TaskPool)
|
||||
|
||||
foreach (CliTaskInfo taskInfo in cliRunner.TaskPool)
|
||||
{
|
||||
if (task != null)
|
||||
Assert.IsNotNull(taskInfo);
|
||||
Assert.IsNotNull(taskInfo.Task);
|
||||
|
||||
if (taskInfo.UseResult)
|
||||
{
|
||||
var task = taskInfo.Task as Task<JsonDataFromPoseidon>;
|
||||
Assert.IsNotNull(task, "Expected Task<JsonDataFromPoseidon>.");
|
||||
|
||||
JsonDataFromPoseidon jsonDataFromPoseidon = task.Result;
|
||||
Console.WriteLine($"Result: {jsonDataFromPoseidon.DeviceId}");
|
||||
Console.WriteLine($"Result: {jsonDataFromPoseidon?.DeviceId}");
|
||||
Assert.IsNotNull(jsonDataFromPoseidon);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Fail($"Task did not complete successfully. State={taskInfo.State}, Status={taskInfo.Task.Status}");
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the total time is greater than the sum of the individual times
|
||||
Assert.IsTrue((cliRunner.TaskPool.Count*OneEndTime.Ticks) > delta.Ticks);
|
||||
|
||||
|
||||
Assert.IsTrue((cliRunner.TaskPool.Count * oneEndTime.Ticks) > delta.Ticks);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task RunMultipleTimesTestProgram_CheckParalelWorkCumulative()
|
||||
{
|
||||
SerialPortData serialPort = new SerialPortData("COM3","cmdSleepTest.exe",74);
|
||||
|
||||
// Check if the executable exists in current directory
|
||||
SerialPortData serialPort = new SerialPortData("COM3", "cmdSleepTest.exe", 74);
|
||||
|
||||
if (!System.IO.File.Exists(serialPort.SerialPortCmdClientPath))
|
||||
{
|
||||
Assert.Inconclusive($"Test executable '{serialPort.SerialPortCmdClientPath}' not found. Please ensure cmdSleepTest.exe exists in the test directory.");
|
||||
Assert.Inconclusive(
|
||||
$"Test executable '{serialPort.SerialPortCmdClientPath}' not found. Please ensure cmdSleepTest.exe exists in the test directory.");
|
||||
return;
|
||||
}
|
||||
|
||||
List<CliRunner> cliRunnerList = new List<CliRunner>();
|
||||
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
cliRunnerList.Add(new CliRunner(false));
|
||||
|
||||
}
|
||||
|
||||
CliRunner cliRunnerOne = new CliRunner(false);
|
||||
DateTime StartTime = DateTime.Now;
|
||||
cliRunnerOne.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
DateTime startTime = DateTime.Now;
|
||||
|
||||
cliRunnerOne.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(
|
||||
serialPort,
|
||||
SerialPortData.EMeterArg.AllParams);
|
||||
|
||||
cliRunnerOne.WaitAll();
|
||||
TimeSpan OneEndTime = DateTime.Now - StartTime;
|
||||
|
||||
StartTime = DateTime.Now;
|
||||
Console.WriteLine($"Start Time Loop: {StartTime.ToString("yyyy-MM-dd HH:mm:ss")}");
|
||||
|
||||
TimeSpan oneEndTime = DateTime.Now - startTime;
|
||||
|
||||
startTime = DateTime.Now;
|
||||
Console.WriteLine($"Start Time Loop: {startTime:yyyy-MM-dd HH:mm:ss}");
|
||||
|
||||
for (int iCliRunner = 0; iCliRunner < cliRunnerList.Count; iCliRunner++)
|
||||
{
|
||||
cliRunnerList[iCliRunner].AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort,
|
||||
cliRunnerList[iCliRunner].AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(
|
||||
serialPort,
|
||||
SerialPortData.EMeterArg.AllParams);
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
cliRunnerList[iCliRunner].AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort,
|
||||
cliRunnerList[iCliRunner].AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(
|
||||
serialPort,
|
||||
SerialPortData.EMeterArg.AllParams);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for ALL tasks from ALL runners
|
||||
var allTasks = cliRunnerList.SelectMany(r => r.TaskPool).ToArray();
|
||||
Task[] allTasks = cliRunnerList
|
||||
.SelectMany(r => r.TaskPool)
|
||||
.Where(ti => ti != null && ti.Task != null)
|
||||
.Select(ti => ti.Task)
|
||||
.ToArray();
|
||||
|
||||
await Task.WhenAll(allTasks);
|
||||
|
||||
DateTime EndTime = DateTime.Now;
|
||||
Console.WriteLine($"End Time Loop: {EndTime.ToString("yyyy-MM-dd HH:mm:ss")}");
|
||||
TimeSpan delta = EndTime - StartTime;
|
||||
Console.WriteLine($"Delta Time One process {OneEndTime.Hours:D2}:{OneEndTime.Minutes:D2}:{OneEndTime.Seconds:D2}.{OneEndTime.Milliseconds:D3} " +
|
||||
$"vs Loop: {delta.Hours:D2}:{delta.Minutes:D2}:{delta.Seconds:D2}.{delta.Milliseconds:D3}");
|
||||
DateTime endTime = DateTime.Now;
|
||||
Console.WriteLine($"End Time Loop: {endTime:yyyy-MM-dd HH:mm:ss}");
|
||||
|
||||
TimeSpan delta = endTime - startTime;
|
||||
Console.WriteLine(
|
||||
$"Delta Time One process {oneEndTime.Hours:D2}:{oneEndTime.Minutes:D2}:{oneEndTime.Seconds:D2}.{oneEndTime.Milliseconds:D3} " +
|
||||
$"vs Loop: {delta.Hours:D2}:{delta.Minutes:D2}:{delta.Seconds:D2}.{delta.Milliseconds:D3}");
|
||||
Console.WriteLine($"Total tasks: {cliRunnerList.Sum(runner => runner.TaskPool.Count)}");
|
||||
|
||||
|
||||
for (int iCliRunner = 0; iCliRunner < cliRunnerList.Count; iCliRunner++)
|
||||
{
|
||||
string results = $"iCliRunner: {iCliRunner}";
|
||||
foreach (Task<JsonDataFromPoseidon> task in cliRunnerList[iCliRunner].TaskPool)
|
||||
|
||||
foreach (CliTaskInfo taskInfo in cliRunnerList[iCliRunner].TaskPool)
|
||||
{
|
||||
if (task != null)
|
||||
Assert.IsNotNull(taskInfo);
|
||||
Assert.IsNotNull(taskInfo.Task);
|
||||
|
||||
if (taskInfo.UseResult)
|
||||
{
|
||||
var task = taskInfo.Task as Task<JsonDataFromPoseidon>;
|
||||
Assert.IsNotNull(task, "Expected Task<JsonDataFromPoseidon>.");
|
||||
|
||||
JsonDataFromPoseidon jsonDataFromPoseidon = task.Result;
|
||||
results += ($" ID: {jsonDataFromPoseidon.DeviceId}");
|
||||
results += $" ID: {jsonDataFromPoseidon?.DeviceId}";
|
||||
Assert.IsNotNull(jsonDataFromPoseidon);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Fail(
|
||||
$"Task did not complete successfully. Runner={iCliRunner}, State={taskInfo.State}, Status={taskInfo.Task.Status}");
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine(results);
|
||||
}
|
||||
|
||||
// Check that the total time is greater than the sum of the individual times
|
||||
Assert.IsTrue((cliRunnerList.Count*OneEndTime.Ticks) > delta.Ticks);
|
||||
Assert.IsTrue((cliRunnerList.Count * oneEndTime.Ticks) > delta.Ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using TBF.Rig.RegisterReaders.PoseidonCmdStartStop;
|
||||
|
||||
namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
[TestClass]
|
||||
[TestSubject(typeof(CliRunner))]
|
||||
public class CliRunnerTimeoutTest
|
||||
{
|
||||
private static string GetCmdSleepTestPath()
|
||||
{
|
||||
var serialPort = new SerialPortData("COM3", "cmdSleepTest.exe", 74);
|
||||
return serialPort.SerialPortCmdClientPath;
|
||||
}
|
||||
|
||||
private static void EnsureExeExists(string exePath)
|
||||
{
|
||||
if (!File.Exists(exePath))
|
||||
{
|
||||
Assert.Inconclusive(
|
||||
$"Test executable '{exePath}' not found. " +
|
||||
"Please ensure cmdSleepTest.exe exists in the test directory.");
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Timeout_ShouldBeDetected_ForLongRunningTask()
|
||||
{
|
||||
string exePath = GetCmdSleepTestPath();
|
||||
EnsureExeExists(exePath);
|
||||
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(exePath, "sleep=5000");
|
||||
|
||||
await Task.Delay(200);
|
||||
|
||||
bool timedOut = cliRunner.TimeOutReceived(100);
|
||||
|
||||
Assert.IsTrue(timedOut, "Timeout should have been detected.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CancelUndoneTasksAsTimedOut_ShouldMarkRunningTaskAsTimedOut()
|
||||
{
|
||||
string exePath = GetCmdSleepTestPath();
|
||||
EnsureExeExists(exePath);
|
||||
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(exePath, "sleep=5000");
|
||||
|
||||
await Task.Delay(150);
|
||||
|
||||
cliRunner.CancelUndoneTasksAsTimedOut();
|
||||
cliRunner.RefreshTaskStates();
|
||||
|
||||
Assert.AreEqual(1, cliRunner.TaskPool.Count);
|
||||
|
||||
var taskInfo = cliRunner.TaskPool.Single();
|
||||
|
||||
Assert.IsNotNull(taskInfo);
|
||||
Assert.AreEqual(CliTaskState.TimedOut, taskInfo.State);
|
||||
Assert.IsFalse(taskInfo.UseResult, "Timed out task must not be used.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CancelUndoneTasksAsTimedOut_ShouldKeepCompletedTaskCompleted()
|
||||
{
|
||||
string exePath = GetCmdSleepTestPath();
|
||||
EnsureExeExists(exePath);
|
||||
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(exePath, "sleep=50");
|
||||
|
||||
try
|
||||
{
|
||||
cliRunner.WaitAll();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// let assertions inspect states
|
||||
}
|
||||
|
||||
cliRunner.RefreshTaskStates();
|
||||
cliRunner.CancelUndoneTasksAsTimedOut();
|
||||
cliRunner.RefreshTaskStates();
|
||||
|
||||
Assert.AreEqual(1, cliRunner.TaskPool.Count);
|
||||
|
||||
var taskInfo = cliRunner.TaskPool.Single();
|
||||
|
||||
Assert.IsNotNull(taskInfo);
|
||||
Assert.AreEqual(CliTaskState.Completed, taskInfo.State);
|
||||
Assert.IsTrue(taskInfo.UseResult, "Completed task should remain usable.");
|
||||
|
||||
var task = taskInfo.Task as Task<JsonDataFromPoseidon>;
|
||||
Assert.IsNotNull(task);
|
||||
Assert.AreEqual(TaskStatus.RanToCompletion, task.Status);
|
||||
Assert.IsNotNull(task.Result);
|
||||
Assert.IsFalse(string.IsNullOrEmpty(task.Result.DeviceId));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CancelUndoneTasksAsTimedOut_ShouldKeepDoneTask_AndMarkUndoneTask()
|
||||
{
|
||||
string exePath = GetCmdSleepTestPath();
|
||||
EnsureExeExists(exePath);
|
||||
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(exePath, "sleep=50");
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(exePath, "sleep=5000");
|
||||
|
||||
await Task.Delay(250);
|
||||
|
||||
cliRunner.RefreshTaskStates();
|
||||
|
||||
Assert.AreEqual(2, cliRunner.TaskPool.Count);
|
||||
Assert.AreEqual(1, cliRunner.TaskPool.Count(t => t.State == CliTaskState.Completed),
|
||||
"Exactly one fast task should be completed before timeout handling.");
|
||||
|
||||
cliRunner.CancelUndoneTasksAsTimedOut();
|
||||
cliRunner.RefreshTaskStates();
|
||||
|
||||
var doneTask = cliRunner.TaskPool.Single(t => t.State == CliTaskState.Completed);
|
||||
var timedOutTask = cliRunner.TaskPool.Single(t => t.State == CliTaskState.TimedOut);
|
||||
|
||||
Assert.IsTrue(doneTask.UseResult);
|
||||
Assert.IsFalse(timedOutTask.UseResult);
|
||||
|
||||
var completed = doneTask.Task as Task<JsonDataFromPoseidon>;
|
||||
Assert.IsNotNull(completed);
|
||||
Assert.AreEqual(TaskStatus.RanToCompletion, completed.Status);
|
||||
Assert.IsNotNull(completed.Result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task AreTasksDone_ShouldReturnTrue_AfterTimeoutCancellation()
|
||||
{
|
||||
string exePath = GetCmdSleepTestPath();
|
||||
EnsureExeExists(exePath);
|
||||
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(exePath, "sleep=5000");
|
||||
|
||||
await Task.Delay(150);
|
||||
|
||||
Assert.IsFalse(cliRunner.AreTasksDone(), "Task should still be running before timeout cancellation.");
|
||||
|
||||
cliRunner.CancelUndoneTasksAsTimedOut();
|
||||
cliRunner.RefreshTaskStates();
|
||||
|
||||
Assert.IsTrue(cliRunner.AreTasksDone(),
|
||||
"After timed out tasks are marked, runner should report no running tasks.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TimedOutTask_ShouldNotHaveUseResult()
|
||||
{
|
||||
string exePath = GetCmdSleepTestPath();
|
||||
EnsureExeExists(exePath);
|
||||
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(exePath, "sleep=5000");
|
||||
|
||||
await Task.Delay(150);
|
||||
|
||||
cliRunner.CancelUndoneTasksAsTimedOut();
|
||||
cliRunner.RefreshTaskStates();
|
||||
|
||||
var taskInfo = cliRunner.TaskPool.Single();
|
||||
|
||||
Assert.AreEqual(CliTaskState.TimedOut, taskInfo.State);
|
||||
Assert.IsFalse(taskInfo.UseResult);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task MultipleSlowTasks_ShouldAllBeMarkedTimedOut()
|
||||
{
|
||||
string exePath = GetCmdSleepTestPath();
|
||||
EnsureExeExists(exePath);
|
||||
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(exePath, "sleep=5000");
|
||||
}
|
||||
|
||||
await Task.Delay(200);
|
||||
|
||||
cliRunner.CancelUndoneTasksAsTimedOut();
|
||||
cliRunner.RefreshTaskStates();
|
||||
|
||||
Assert.AreEqual(5, cliRunner.TaskPool.Count);
|
||||
Assert.AreEqual(5, cliRunner.TaskPool.Count(t => t.State == CliTaskState.TimedOut));
|
||||
Assert.AreEqual(0, cliRunner.TaskPool.Count(t => t.UseResult));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FastTask_WithInvalidJson_ShouldFinishButNotProduceUsefulResult()
|
||||
{
|
||||
string exePath = GetCmdSleepTestPath();
|
||||
EnsureExeExists(exePath);
|
||||
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(exePath, "sleep=50 invalidjson=true");
|
||||
|
||||
try
|
||||
{
|
||||
cliRunner.WaitAll();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
cliRunner.RefreshTaskStates();
|
||||
|
||||
Assert.AreEqual(1, cliRunner.TaskPool.Count);
|
||||
|
||||
var taskInfo = cliRunner.TaskPool.Single();
|
||||
Assert.AreEqual(CliTaskState.Completed, taskInfo.State);
|
||||
|
||||
var task = taskInfo.Task as Task<JsonDataFromPoseidon>;
|
||||
Assert.IsNotNull(task);
|
||||
Assert.AreEqual(TaskStatus.RanToCompletion, task.Status);
|
||||
|
||||
// depending on your TryJsonStringDeserialize fallback,
|
||||
// result may be null or an empty/default object
|
||||
// so avoid asserting UseResult=false here
|
||||
// instead assert no valid device id
|
||||
if (task.Result != null)
|
||||
{
|
||||
Assert.IsTrue(string.IsNullOrEmpty(task.Result.DeviceId),
|
||||
"Invalid JSON should not produce a valid DeviceId.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using TBF.Rig.RegisterReaders.PoseidonCmdStartStop;
|
||||
|
||||
namespace TBFTests.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
[TestClass]
|
||||
[TestSubject(typeof(CliRunner))]
|
||||
public class CliRunnerTimeoutUnitTest
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task CancelUndoneTasksAsTimedOut_ShouldMarkOnlyRunningTasks()
|
||||
{
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
var completedTask = Task.FromResult("done");
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
var runningTask = Task.Delay(TimeSpan.FromSeconds(30), cts.Token);
|
||||
|
||||
cliRunner.AddTaskForTest(completedTask, "completed");
|
||||
cliRunner.AddTaskForTest(runningTask, "running", cts);
|
||||
|
||||
await Task.Delay(50);
|
||||
|
||||
cliRunner.RefreshTaskStates();
|
||||
cliRunner.CancelUndoneTasksAsTimedOut();
|
||||
cliRunner.RefreshTaskStates();
|
||||
|
||||
Assert.AreEqual(2, cliRunner.TaskPool.Count);
|
||||
|
||||
var completed = cliRunner.TaskPool.First(t => t.Name == "completed");
|
||||
var timedOut = cliRunner.TaskPool.First(t => t.Name == "running");
|
||||
|
||||
Assert.AreEqual(CliTaskState.Completed, completed.State);
|
||||
Assert.IsTrue(completed.UseResult);
|
||||
|
||||
Assert.AreEqual(CliTaskState.TimedOut, timedOut.State);
|
||||
Assert.IsFalse(timedOut.UseResult);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TimeOutReceived_ShouldReturnTrue_WhenElapsedExceedsTimeout()
|
||||
{
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
Thread.Sleep(30);
|
||||
|
||||
Assert.IsTrue(cliRunner.TimeOutReceived(1));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task AreTasksDone_ShouldReturnTrue_WhenTimedOutTasksAreMarked()
|
||||
{
|
||||
var cliRunner = new CliRunner(false);
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
var runningTask = Task.Delay(TimeSpan.FromSeconds(30), cts.Token);
|
||||
|
||||
cliRunner.AddTaskForTest(runningTask, "running", cts);
|
||||
|
||||
await Task.Delay(50);
|
||||
|
||||
Assert.IsFalse(cliRunner.AreTasksDone());
|
||||
|
||||
cliRunner.CancelUndoneTasksAsTimedOut();
|
||||
cliRunner.RefreshTaskStates();
|
||||
|
||||
Assert.IsTrue(cliRunner.AreTasksDone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,8 @@
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\wiredProtocol\TouchReadBaudRateDetectionTests.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\iPerlASICReader\communication\C4\wiredProtocol\TouchReadFrameBuilderTest.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\CliRunnerTest.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\CliRunnerTimeoutTest.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\CliRunnerTimeoutUnitTest.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\PoseidonReaderTest.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonReader\UniHeadTestCtrlTest.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\ReadStableMassOpTest.cs" />
|
||||
|
||||
Reference in New Issue
Block a user