Add simulation logic to `StandingStartStopTestOp` and handle zero `TestTime` edge cases in `FlyingStartMassCollectionSeq`
245 lines
9.1 KiB
C#
245 lines
9.1 KiB
C#
///
|
|
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
|
///
|
|
using System;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using Common;
|
|
using log4net;
|
|
using TBF.Rig.GenericDevices;
|
|
|
|
namespace TBF.Rig.ControlBoard.Uni
|
|
{
|
|
public class StandingStartStopTestOp : IOperation
|
|
{
|
|
private static readonly ILog log = LogManager.GetLogger(typeof(StandingStartStopTestOp));
|
|
public override string ToString() { return string.Format("StandingStartStopTestOp()"); }
|
|
|
|
///
|
|
/// Set by the constructor
|
|
///
|
|
readonly UniCB uniCB;
|
|
readonly object flowMeter;
|
|
readonly TBF.Rig.Uni.FlowMetersInParallel.FlowMeter flowMeterInParallel;
|
|
readonly TBF.Rig.Uni.Diverter.Diverter diverter;
|
|
readonly int pulsesCount; /// Number of reference pulses for a complete test
|
|
readonly bool withDiverter; /// Test with diverter (and scale)
|
|
|
|
private DateTime startTimeForSimulation;
|
|
private bool simulationTimerStarted = false;
|
|
|
|
///
|
|
/// Internal state of this operation
|
|
///
|
|
enum OpState
|
|
{
|
|
StartingTest,
|
|
TestInProgress,
|
|
TestCompleted,
|
|
}
|
|
|
|
OpState opState;
|
|
|
|
/// <summary>
|
|
/// Operation for a Standing start-stop test (constructor)
|
|
///
|
|
/// Events: OpArgumentError .... invalid arguments, test cannot be started
|
|
/// StartingTest ....... starting a test
|
|
/// TestInProgress ..... test was successfully started, test is running
|
|
/// TestCompleted ...... test was successfully completed
|
|
/// Error .............. unspecified error while running a test
|
|
/// </summary>
|
|
/// <param name="cb">Control board component</param>
|
|
/// <param name="devices">Components used by the test</param>
|
|
/// <param name="qFrom">Flow lower limit</param>
|
|
/// <param name="qTo">Flow upper limit</param>
|
|
/// <param name="pulsesCount">Test duration - number of reference flow meter pulses</param>
|
|
public StandingStartStopTestOp(UniCB cb, OutputPath devices, int pulsesCount, bool withDiverter)
|
|
{
|
|
this.uniCB = cb;
|
|
try
|
|
{
|
|
flowMeter = devices.FlowMeter as TBF.Rig.Uni.FlowMeter.FlowMeter;
|
|
if(flowMeter == null) flowMeter = devices.FlowMeter as TBF.Rig.Uni.FlowMetersInParallel.FlowMeter;
|
|
|
|
if (flowMeter == null) throw new ArgumentNullException("Invalid flow meter");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
string deviceInfo = GetAllDevicesInfo(devices);
|
|
string flowMeterStatus = devices.FlowMeter == null
|
|
? "devices.FlowMeter je NULL"
|
|
: $"devices.FlowMeter je typu: {devices.FlowMeter.GetType().FullName}";
|
|
|
|
MessageBox.Show(
|
|
$"Chyba počas zastavenia regulácie prietoku, v ramci StandingStartStopTestOp() pre flowMeter:\n" +
|
|
$"{ex.Message}\n\n" +
|
|
$"Diagnostika:\n{flowMeterStatus}\n\n" +
|
|
$"{deviceInfo}\n\n" +
|
|
$"Stack trace:\n{ex.StackTrace}",
|
|
"Chyba",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Error
|
|
);
|
|
|
|
throw;
|
|
}
|
|
|
|
this.pulsesCount = pulsesCount;
|
|
this.withDiverter = withDiverter;
|
|
|
|
if (withDiverter)
|
|
{
|
|
try
|
|
{
|
|
diverter = devices.Diverter as TBF.Rig.Uni.Diverter.Diverter;
|
|
if (diverter == null) throw new ArgumentNullException("Invalid diverter");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
string deviceInfo = GetAllDevicesInfo(devices);
|
|
|
|
MessageBox.Show(
|
|
$"Chyba počas zastavenia regulácie prietoku, v ramci StandingStartStopTestOp() pre diverter:\n" +
|
|
$"{ex.Message}\n\n{deviceInfo}\n\nStack trace:\n{ex.StackTrace}",
|
|
"Chyba",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Error
|
|
);
|
|
|
|
throw;
|
|
}
|
|
}
|
|
|
|
log.Debug(this.ToString());
|
|
}
|
|
|
|
string GetAllDevicesInfo(object obj)
|
|
{
|
|
if (obj == null) return "devices objekt je null.";
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.AppendLine("Zoznam zariadení v devices:");
|
|
|
|
var props = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
|
foreach (var prop in props)
|
|
{
|
|
try
|
|
{
|
|
object value = prop.GetValue(obj);
|
|
string valueStr = value != null ? value.ToString() : "null";
|
|
sb.AppendLine($"{prop.Name}: {valueStr}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
sb.AppendLine($"{prop.Name}: [Chyba pri načítaní - {ex.Message}]");
|
|
}
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Start this operation
|
|
/// </summary>
|
|
public void Start()
|
|
{
|
|
if (flowMeter is TBF.Rig.Uni.FlowMeter.FlowMeter)
|
|
{
|
|
log.InfoFormat("Start() Et#={0} pulses={1} withDiverter={2}", ((TBF.Rig.Uni.FlowMeter.FlowMeter)flowMeter).Idx1, pulsesCount, withDiverter);
|
|
|
|
/// Start the test (and the flow measurement)
|
|
if (withDiverter) { uniCB.DivResolution = diverter.Resolution; }
|
|
uniCB.SetActivity(Activity.StandingStartStopTest);
|
|
uniCB.StartTest(false, ((TBF.Rig.Uni.FlowMeter.FlowMeter)flowMeter).Idx1, (withDiverter ? diverter.DiverterNr : 0), 0,
|
|
false, withDiverter, false, true, false, pulsesCount);
|
|
|
|
opState = OpState.StartingTest;
|
|
}
|
|
else if (flowMeter is TBF.Rig.Uni.FlowMetersInParallel.FlowMeter)
|
|
{
|
|
log.InfoFormat("Start() Et#={0} pulses={1} withDiverter={2}", ((TBF.Rig.Uni.FlowMetersInParallel.FlowMeter)flowMeter).Idx1, pulsesCount, withDiverter);
|
|
|
|
/// Start the test (and the flow measurement)
|
|
if (withDiverter) { uniCB.DivResolution = diverter.Resolution; }
|
|
uniCB.SetActivity(Activity.StandingStartStopTest);
|
|
uniCB.StartTest(false, ((TBF.Rig.Uni.FlowMetersInParallel.FlowMeter)flowMeter).Idx1, (withDiverter ? diverter.DiverterNr : 0), 0,
|
|
false, withDiverter, false, true, false, pulsesCount);
|
|
|
|
opState = OpState.StartingTest;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Run this operation
|
|
/// </summary>
|
|
/// <returns>
|
|
/// Event.OpArgumentError .... invalid arguments, test cannot be started
|
|
/// Event.StartingTest ....... starting a test
|
|
/// Event.TestInProgress ..... test was successfully started, test is running
|
|
/// Event.TestCompleted ...... test was successfully completed
|
|
/// Event.Error .............. unspecified error while running a test
|
|
/// </returns>
|
|
public Event Run()
|
|
{
|
|
log.DebugFormat("Run() opState={0}", opState);
|
|
|
|
//Simulation of processing time 25 seconds
|
|
if (uniCB.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
if (opState == OpState.StartingTest)
|
|
{
|
|
startTimeForSimulation = DateTime.Now;
|
|
simulationTimerStarted = false;
|
|
}
|
|
if (opState == OpState.TestInProgress)
|
|
{
|
|
if (!simulationTimerStarted)
|
|
{
|
|
startTimeForSimulation = DateTime.Now;
|
|
simulationTimerStarted = true;
|
|
}
|
|
else if (DateTime.Now - startTimeForSimulation > TimeSpan.FromSeconds(25))
|
|
{
|
|
return Event.TestCompleted;
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (opState)
|
|
{
|
|
case OpState.StartingTest:
|
|
|
|
opState = OpState.TestInProgress;
|
|
return Event.TestInProgress;
|
|
|
|
case OpState.TestInProgress:
|
|
|
|
if (uniCB.RefPulses < pulsesCount)
|
|
{
|
|
return Event.TestInProgress; /// Test was not completed yet
|
|
}
|
|
opState = OpState.TestCompleted;
|
|
return Event.TestCompleted;
|
|
|
|
case OpState.TestCompleted:
|
|
default:
|
|
return Event.TestCompleted;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stop this operation
|
|
/// </summary>
|
|
public void Stop()
|
|
{
|
|
log.Info("Stop()");
|
|
uniCB.SetActivity((opState == OpState.TestCompleted) ? Activity.TestCompleted : Activity.Idle);
|
|
uniCB.StopAll(false);
|
|
}
|
|
}
|
|
}
|