tbf/TestBenchFramework/BenchControl/Sequences/SequenceBase.cs
Milan Hanajik c56848958e - MessageBoxOp, MesssageBoxForm
- Configuration error handling in MainSeq
- Paths selection inside MainSeq
2014-08-12 22:21:26 +02:00

635 lines
28 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using log4net;
using TBF.BenchControl.GenericDevices;
using TBF.BenchControl.Operations;
using TBF.Boxes;
using TBF.Resources;
using TBF.UiBridge;
namespace TBF.BenchControl.Sequences
{
/// <summary>
/// Sequence is a group of states that can be dynamically added to
/// and removed from the state machine
/// </summary>
public class SequenceBase
{
private static readonly ILog log = LogManager.GetLogger(typeof(SequenceBase));
///------------------------------------------------------------
/// Global static variables set only once.
///------------------------------------------------------------
public static BenchId.Component BenchId;
public static IList<IRegulValve> RegulValves; /// list of regulation valves
public static IList<IWaterMeter> WaterMeters; /// list of water meters
public static IList<ICamera> Cameras; /// list of cameras
///------------------------------------------------------------
/// Procedure related (static) variables.
/// They are re-initialized when LoadProcedure() is called
///------------------------------------------------------------
protected static IList<Entities.TestResult> results;
public static float Qrise;
public static float Qfall;
/// <summary>
/// Clear all test results.
/// </summary>
protected static void ResetResults()
{
results = new List<Entities.TestResult>();
Qrise = 0;
Qfall = 0;
}
/// <summary>
/// Add result to the list of results.
/// Overwrite (=delete) any previous result with the same name.
/// </summary>
/// <param name="newTestResult">New test result</param>
protected static void AddOrOverwriteResult(Entities.TestResult newTestResult)
{
try
{
Entities.TestResult toDelete =
results.First<Entities.TestResult>(x => x.Name.Equals(newTestResult.Name));
results.Remove(toDelete);
}
catch { };
results.Add(newTestResult);
}
/// <summary>
/// Check whether the results are complete, whether there is a result for each test.
/// </summary>
/// <param name="tests">All tests</param>
/// <returns>true = The results are complete</returns>
protected static bool ResultsAreComplete(IList<Entities.Test> tests)
{
foreach (var test in tests)
{
if (!test.Method.Contains("RoiDetection"))
{
for (int r = 1; r <= test.Repeats; r++)
{
bool resultExists = false;
foreach (var tr in results)
{
if ((tr.DoNotEvaluate == false) && (tr.RepetitionNr == r) && (tr.TestName == test.Name))
{
resultExists = true;
break;
}
}
if (!resultExists) return false;
}
}
}
return true;
}
protected static float TimeEstimateTotal; /// Time estimate of the selected cycle or test
protected static float TimeEstimateBeginRpts; /// Time estimate at the beginning of all repetitions of the current tests
protected static float TimeEstimateOneTest; /// Time estimate of the current test (one repetition)
static SequenceBase()
{
results = new List<Entities.TestResult>();
WMVolumes = new FloatBox[Program.WMsCount];
WMErrors = new FloatBox[Program.WMsCount];
for (int i = 0; i < Program.WMsCount; i++)
{
WMVolumes[i] = new FloatBox() { Name = string.Format("Volume{0}", i), Format = "F2" };
WMErrors[i] = new FloatBox() { Name = string.Format("Error{0}", i), Format = "F2" };
}
}
///------------------------------------------------------------
/// Test related (instance) variables.
/// Created when test sequence is open.
/// They persist during all repetitions of the same test
///------------------------------------------------------------
protected static BenchControl.FeedingPath inPath;
protected static BenchControl.BenchPath benchPath;
protected static BenchControl.OutputPath outPath;
protected static BenchControl.MetersPath sensPath;
protected static Entities.TransitionSequence transitionStart;
protected static Entities.TransitionSequence transitionStop;
#region Temperature_Pressure_Humidity
protected static FloatBox tempIn = new FloatBox() { Name = "Temperature In", Format = "F1" };
protected static FloatBox tempOut = new FloatBox() { Name = "Temperature Out", Format = "F1" };
protected static FloatBox tempDiv = new FloatBox() { Name = "Temperature Div", Format = "F1" };
protected static FloatBox pressIn = new FloatBox() { Name = "Pressure In", Format = "F3", Factor = 0.01f };
protected static FloatBox pressOut = new FloatBox() { Name = "Pressure Out", Format = "F3", Factor = 0.01f };
protected static FloatBox airTemperature = new FloatBox() { Name = "Ambient Temperature", Format = "F1" };
protected static FloatBox airPressure = new FloatBox() { Name = "Ambient Pressure", Format = "F1" };
protected static FloatBox airHumidity = new FloatBox() { Name = "Ambient Humidity", Format = "F1" };
///
protected float tempInSum;
protected float tempOutSum;
protected float tempDivSum;
protected float pressInSum;
protected float pressOutSum;
protected float ambientTempSum;
protected float ambientPressSum;
protected float ambientHumiSum;
///
protected int averagedDataCount;
///
protected void ResetAveragedData()
{
tempInSum = 0;
tempOutSum = 0;
tempDivSum = 0;
pressInSum = 0;
pressOutSum = 0;
ambientTempSum = 0;
ambientPressSum = 0;
ambientHumiSum = 0;
///
averagedDataCount = 0;
}
///
protected void AccumulateAveragedData()
{
tempInSum += tempIn.Val;
tempOutSum += tempOut.Val;
tempDivSum += tempDiv.Val;
pressInSum += pressIn.Val;
pressOutSum += pressOut.Val;
ambientTempSum += airTemperature.Val;
ambientPressSum += airPressure.Val;
ambientHumiSum += airHumidity.Val;
///
averagedDataCount++;
}
///
protected void UpdateTestRsltWithAveragedData(Entities.TestResult tstRslt)
{
if (averagedDataCount != 0)
{
float denominator = (float)averagedDataCount;
tstRslt.AmbientTempAve = ambientTempSum / denominator;
tstRslt.AmbientPressAve = ambientPressSum / denominator;
tstRslt.AmbientHumiAve = ambientHumiSum / denominator;
tstRslt.PressInAvrg = pressInSum / denominator;
tstRslt.PressOutAvrg = pressOutSum / denominator;
tstRslt.TempInAvrg = tempInSum / denominator;
tstRslt.TempOutAvrg = tempOutSum / denominator;
tstRslt.TempDivAvrg = tempDivSum / denominator;
}
}
#endregion
protected IOperation readRegisters1;
protected IOperation readRegisters2;
protected IOperation queryEnd1;
protected IOperation queryEnd2;
protected IOperation checkUiOp;
protected bool ticTac = false;
protected int[] WMPulses = new int[Program.WMsCount];
protected int[] WMRefPulses = new int[Program.WMsCount];
protected static FloatBox[] WMVolumes;
protected static FloatBox[] WMErrors;
protected static IntBox refCount = new IntBox() { Name = "RefCount" };
protected static FloatBox refFreq = new FloatBox() { Name = "RefFreq", Format = "F2" };
protected static FloatBox refFlow = new FloatBox() { Name = "RefFlow", Format = "F2" };
protected static FloatBox mass = new FloatBox() { Name = "Mass", Format = "F1" };
protected static FloatBox startMass = new FloatBox() { Name = "Start Mass", Format = "F1" };
protected static FloatBox endMass = new FloatBox() { Name = "End Mass", Format = "F1" };
/// <summary>
/// To clear process values at the beginning of each test
/// </summary>
protected void ClearProcessValues()
{
//if (WMPulses != null) { for (int i = 0; i < WMPulses.Length; i++) WMPulses[i] = 0; }
//if (WMRefPulses != null) { for (int i = 0; i < WMRefPulses.Length; i++) WMPulses[i] = 0; }
for (int i = 0; i < Program.WMsCount; i++)
{
WMPulses[i] = 0;
WMPulses[i] = 0;
WMVolumes[i].Clear();
WMErrors[i].Clear();
}
refCount.Clear();
refFreq.Clear();
refFlow.Clear();
mass.Clear();
startMass.Clear();
endMass.Clear();
}
/// <summary>
/// Empties the tank: opens the emptying valve and measures the weight.
/// </summary>
/// <param name="EmptyTankValve">Valve to empty the tank</param>
/// <param name="Balance">Balance underneath the tank</param>
/// <returns>Event.Done or Event.Error</returns>
protected Event EmptyTheTank(IValve EmptyTankValve, IBalance Balance)
{
//------------------------------------------------
Bridge.OnActivity(this, TBF.Resources.Strings.Emptying_tank);
//------------------------------------------------
IList<Event> e;
Bridge.Bench2UI(ButtonsEtc.StopBtnEn);
State.Create("SequenceBase : Opening the emptying valve")
.AddOperation(checkUiOp)
.AddOperation(StateMachine.ControlBoard.SetValvesOp(EmptyTankValve, null))
.EnterState();
do { e = StateMachine.WaitRunDevsRunOps(); }
while (!e.Contains(Event.ValvesSet));
do
{
//--------------------------------
State.Create("SequenceBase : Emptying the tank")
.AddOperation(checkUiOp)
.AddOperation(Balance.ReadMassOp(ref mass))
.AddOperation(StateMachine.ControlBoard.UpdateTankWeightOp())
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) return Event.Error;
if (e.Contains(Event.UiCmdStop)) goto quit_emptying;
if (e.Contains(Event.BalanceOverload)) { }; /// Tank should be emptying now
}
while (!e.Contains(Event.BalanceDone));
}
while (mass.Val > (Balance.Capacity / 100.0f + 20.0f));
quit_emptying:
//--------------------------------
State.Create("SequenceBase : Closing the emptying valve")
.AddOperation(checkUiOp)
.AddOperation(Balance.ReadMassOp(ref mass))
.AddOperation(StateMachine.ControlBoard.UpdateTankWeightOp())
.AddOperation(StateMachine.ControlBoard.SetValvesOp(null, EmptyTankValve))
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) return Event.Error;
}
while (!e.Contains(Event.ValvesSet) || !e.Contains(Event.BalanceDone));
State.Create("SequenceBase : Updating the weight")
.AddOperation(checkUiOp)
.AddOperation(Balance.ReadMassOp(ref mass))
.AddOperation(new Operations.TimerOp(5))
.AddOperation(StateMachine.ControlBoard.UpdateTankWeightOp())
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) return Event.Error;
}
while (!e.Contains(Event.BalanceDone) || !e.Contains(Event.TimerExpired));
return Event.Done;
}
/// <summary>
/// Executes steps of a transition sequence.
/// </summary>
/// <param name="transitionSequence">TransitionSequence entity</param>
/// <returns>Event.Done, Event.Error or Event.UiCmdStop</returns>
protected Event Transition(Entities.TransitionSequence transitionSequence, string message)
{
if (transitionSequence == null) return Event.None;
IList<Entities.TransitionStep> transitionSteps = StateMachine.WtSession
.CreateQuery("FROM TransitionStep WHERE TransitionSequence = :tsId ORDER BY ItemNr")
.SetParameter("tsId", transitionSequence.Id)
.List<Entities.TransitionStep>();
IList<Event> e;
int stepsCount = transitionSteps.Count;
foreach (var step in transitionSteps)
{
//------------------------------------------------
Bridge.OnActivity(this, string.Format(message, transitionSequence.Name, step.ItemNr + 1, stepsCount));
//------------------------------------------------
/// Get new regulation valve positions and calculate the number of valves to change
float[] allRegvPositions = Utils.RegulValvesPositions(step);
///
IList<IOperation> rvPosOperations = new List<IOperation>();
for (int i = 0; i < allRegvPositions.Length; i++)
{
if (allRegvPositions[i] >= 0) /// Negative value means no position change
{
rvPosOperations.Add(RegulValves[i].SetRegulValvePositionOp(
Math.Max(0, allRegvPositions[i] - 0.05f), Math.Min(100.0f, allRegvPositions[i] + 0.05f), 60));
}
}
int changingRVsCount = rvPosOperations.Count; /// Number of RV-s with changing position in this step
/// Duration must be at least the number of regulation valves to change seconds
int duration = Math.Max(step.Duration, changingRVsCount);
///
/// The first state updates all (regular) valves and the 1st regulation valve to be changed
/// Max. one regulation valve may be controlled in each sub-step (in each state)
///
State oneStep = State.Create(string.Format("SequenceBase.Transition() : Step {0}.1/{1}", step.ItemNr + 1, stepsCount))
.AddOperation(checkUiOp)
.AddOperation(StateMachine.ControlBoard.SetValvesOp(Utils.ValvesOpen(step), Utils.ValvesClose(step)))
.AddOperation(new TimerOp((changingRVsCount <= 1) ? step.Duration : 1));
if (changingRVsCount > 0)
{
oneStep.AddOperation(rvPosOperations[0]);
}
oneStep.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
log.InfoFormat("RV1={0}% RV2={1}% RV3={2}% RV4={3}% RV5={4}%", StateMachine.ControlBoard.RValvePosition(1),
StateMachine.ControlBoard.RValvePosition(2), StateMachine.ControlBoard.RValvePosition(3),
StateMachine.ControlBoard.RValvePosition(4), StateMachine.ControlBoard.RValvePosition(5));
if (e.Contains(Event.Error)) return Event.Error;
if (e.Contains(Event.RegulValveTimeOut)) return Event.Error;
if (e.Contains(Event.UiCmdStop)) return Event.UiCmdStop;
}
while (!e.Contains(Event.TimerExpired));
///
/// Additional extra states the 2nd and all subsequent regulation valves to be changed
/// Max. one regulation valve may be controlled in each sub-step (in each state)
///
for (int j = 1; j < changingRVsCount; j++)
{
/// The first state updating all plain valves and the 1st regulation valve
/// Max. one regulation valve may change in each step
State oneStepContinued = State.Create(string.Format("SequenceBase.Transition() : Step {0}.{2}/{1}", step.ItemNr + 1, stepsCount, j+1))
.AddOperation(checkUiOp)
.AddOperation(new TimerOp((j == changingRVsCount - 1) ? (step.Duration - changingRVsCount + 1) : 1));
for (int k = 0; k <= j; k++) { oneStepContinued.AddOperation(rvPosOperations[k]); }
oneStepContinued.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
log.InfoFormat("RV1={0}% RV2={1}% RV3={2}% RV4={3}% RV5={4}%", StateMachine.ControlBoard.RValvePosition(1),
StateMachine.ControlBoard.RValvePosition(2), StateMachine.ControlBoard.RValvePosition(3),
StateMachine.ControlBoard.RValvePosition(4), StateMachine.ControlBoard.RValvePosition(5));
if (e.Contains(Event.Error)) return Event.Error;
if (e.Contains(Event.RegulValveTimeOut)) return Event.Error;
if (e.Contains(Event.UiCmdStop)) return Event.UiCmdStop;
}
while (!e.Contains(Event.TimerExpired));
}
}
return Event.Done;
}
/// <summary>
/// Main loop where measurements are collected.
/// </summary>
/// <param name="realTest">false = a flow setting or a switching flow detection, true = measurement</param>
/// <returns>Event.MeasurementCompleted, Event.UiCmdStop, Event.Error or Event.Done</returns>
protected Event ReadRegistersTempPressAmbient(IList<IOperation> measureOperations, bool realTest)
{
IList<Event> e;
ticTac = !ticTac;
State.Create("Read water meters")
.AddOperation(checkUiOp)
.AddOperations(measureOperations)
.AddOperation(ticTac ? readRegisters1 : readRegisters2)
.AddOperation(benchPath.TempIn.ReadTempOp(ref tempIn, Event.TempInDone))
.AddOperation(benchPath.TempOut.ReadTempOp(ref tempOut, Event.TempOutDone))
.AddOperation(outPath.TempDiv.ReadTempOp(ref tempDiv, Event.TempDivDone))
.AddOperation(benchPath.PressIn.ReadPressureOp(ref pressIn, Event.PressureInDone))
.AddOperation(benchPath.PressOut.ReadPressureOp(ref pressOut, Event.PressureOutDone))
.AddOperation(realTest ? outPath.Balance.ReadMassOp(ref mass) : null)
.AddOperation(StateMachine.ControlBoard.UpdateTankWeightOp())
.AddOperation((StateMachine.Ambient != null)
? StateMachine.Ambient.ReadAmbientOp(airTemperature, airPressure, airHumidity)
: null)
.AddOperation(realTest ? (ticTac ? queryEnd1 : queryEnd2) : null)
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) return Event.Error;
if (e.Contains(Event.UiCmdStop)) return Event.UiCmdStop;
if (e.Contains(Event.MeasurementCompleted)) return Event.MeasurementCompleted;
}
while ( !e.Contains(Event.TempInDone) ||
!e.Contains(Event.TempOutDone) ||
!e.Contains(Event.TempDivDone) ||
!e.Contains(Event.PressureInDone) ||
!e.Contains(Event.PressureOutDone) ||
(realTest && !e.Contains(Event.BalanceDone)) ||
!e.Contains(Event.ReadAllRegistersDone));
return Event.Done;
}
/// <summary>
/// Prepares 'TestProgressEventArgs' object that update screens during the test
/// </summary>
/// <param name="test">Current 'Test' entity</param>
/// <param name="tstRslt">Current 'TestResult' entity</param>
/// <param name="currentRefPulses">Current number of reference pulses</param>
/// <param name="freq">Curent reference frequency in [Hz]</param>
/// <param name="time">Current test time in [s]</param>
/// <param name="progress">Current progress 0 .. 1.0f</param>
/// <returns>Data for the UI</returns>
protected TestProgressEventArgs GetTestProgressData(Entities.Test test, Entities.TestResult tstRslt, Elde.ControlBoardDev cBrd, float time, float progress)
{
TestProgressEventArgs data = new TestProgressEventArgs();
data.TestResult = tstRslt;
//float ltrPerRefPulse = outPath.FlowMeter.NominalFlow / 7200.0f; /// [ltr/pulse]
float refPulsesPerLtr = 7200.0f / outPath.FlowMeter.NominalFlow; /// [pulse/ltr]
data.RefPulses = cBrd.EtPulses(0);
refFreq.Val = cBrd.ReferenceFreq;
data.FlowMtrFreq = refFreq;
data.Flow = refFlow;
data.Volume = new FloatBox() { Name = "Volume", Format = "F1", Val = Formulas.VolumeFromPulses(data.RefPulses, refPulsesPerLtr) };
data.Time = time;
data.StartMass = startMass;
data.Mass = mass;
data.Progress = progress;
float estCurrentTime = TimeEstimateBeginRpts + ((float)(tstRslt.RepetitionNr - 1) + progress) * TimeEstimateOneTest;
data.OveralProgress = estCurrentTime / TimeEstimateTotal;
data.Tin = tempIn;
data.Tout = tempOut;
data.Tdiv = tempDiv;
data.Pin = pressIn;
data.Pout = pressOut;
data.AmbientTemp = airTemperature;
data.AmbientPressure = airPressure;
data.AmbientHumidity = airHumidity;
for (int i = 0; i < Program.WMsCount; i++)
{
if (sensPath.RegisterReaders[i] != null)
{
data.WmPulses[i] = WMPulses[i];
data.WmRefPulses[i] = WMRefPulses[i];
data.WmVolume[i] = Formulas.VolumeFromPulses(WMPulses[i], sensPath.RegisterReaders[i].PulsesPerLtr);
if (data.Volume.Valid) { data.WmErrPct[i] = Formulas.ErrorFromVolumes(data.WmVolume[i], data.Volume.Val); }
}
}
return data;
}
protected string TestResult2CsvLine(Entities.TestResult tstRslt, int currentRefPulses)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append(tstRslt.TimeStart);
sb.Append(";"); sb.Append(tstRslt.TestName);
sb.Append(";"); sb.Append(tstRslt.RepetitionNr);
sb.Append(";"); sb.Append("1");
sb.Append(";"); sb.Append(tstRslt.Method);
sb.Append(";"); sb.Append(tstRslt.Volume);
sb.Append(";"); sb.Append(tstRslt.Qfrom);
sb.Append(";"); sb.Append(tstRslt.Qto);
sb.Append(";"); sb.Append(tstRslt.ErrLimLo);
sb.Append(";"); sb.Append(tstRslt.ErrLimHi);
sb.Append(";"); sb.Append("0");
sb.Append(";"); sb.Append("60");
sb.Append(";"); sb.Append("0");
sb.Append(";"); sb.Append("0");
sb.Append(";"); sb.Append("2");
sb.Append(";"); sb.Append(" ");
sb.Append(";"); sb.Append(outPath.Balance.Cfg.Name);
sb.Append(";"); sb.Append(tstRslt.AmbientTempAve);
sb.Append(";"); sb.Append(tstRslt.AmbientPressAve);
sb.Append(";"); sb.Append(tstRslt.AmbientHumiAve);
sb.Append(";"); sb.Append(tstRslt.PressInAvrg);
sb.Append(";"); sb.Append(tstRslt.PressOutAvrg);
sb.Append(";"); sb.Append(tstRslt.PressInStart);
sb.Append(";"); sb.Append(tstRslt.PressOutStart);
sb.Append(";"); sb.Append(tstRslt.PressInEnd);
sb.Append(";"); sb.Append(tstRslt.PressOutEnd);
sb.Append(";"); sb.Append(tstRslt.TempInAvrg);
sb.Append(";"); sb.Append(tstRslt.TempOutAvrg);
sb.Append(";"); sb.Append(tstRslt.TempDivAvrg);
sb.Append(";"); sb.Append(tstRslt.TempInStart);
sb.Append(";"); sb.Append(tstRslt.TempOutStart);
sb.Append(";"); sb.Append(tstRslt.TempDivStart);
sb.Append(";"); sb.Append(tstRslt.TempInEnd);
sb.Append(";"); sb.Append(tstRslt.TempOutEnd);
sb.Append(";"); sb.Append(tstRslt.TempDivEnd);
sb.Append(";"); sb.Append(tstRslt.MassStartRaw);
sb.Append(";"); sb.Append(tstRslt.MassStart);
sb.Append(";"); sb.Append(tstRslt.MassEndRaw);
sb.Append(";"); sb.Append(tstRslt.MassEnd);
sb.Append(";"); sb.Append(tstRslt.MassDiff);
sb.Append(";"); sb.Append(tstRslt.DensityDiv);
sb.Append(";"); sb.Append(tstRslt.DensityIn);
sb.Append(";"); sb.Append(tstRslt.DensityOut);
sb.Append(";"); sb.Append(" "); /// d_air: Hustota vzduchu: Sheet1 - K9
sb.Append(";"); sb.Append(" "); /// Buoyancy: Sheet1 - X9
sb.Append(";"); sb.Append(" "); /// Exp T: teraz vynechat
sb.Append(";"); sb.Append(" "); /// Exp P: teraz vynechat
sb.Append(";"); sb.Append(" "); /// pipe expansion: teraz vynechat
sb.Append(";"); sb.Append(tstRslt.FlowMass); /// Qm [kg/h]
sb.Append(";"); sb.Append(tstRslt.FlowVolume); /// Qv [l/h]
sb.Append(";"); sb.Append(tstRslt.VolumeCTV); /// Vet . . . komercne prava hodnota - podla vahy
sb.Append(";"); sb.Append(tstRslt.VolumeMaster); /// Velm . . . . objem podla etalonu
sb.Append(";"); sb.Append(" "); /// Vmass . . . objem podla druheho etalonu / prietokomeru pred tratou (teraz vynechavame)
sb.Append(";"); sb.Append(tstRslt.Time); /// t
sb.Append(";"); sb.Append(tstRslt.ErrorMaster); /// Eelm . . . chyba etalonu voci komercne pravej hodnote
sb.Append(";"); sb.Append(" "); /// Emass . . . chyba druheho etalonu voci komercne pravej hodnote (teraz vynechavame)
sb.Append(";"); sb.Append(7200.0f / outPath.FlowMeter.NominalFlow);
/// Const.MID . konstanta eatlonu
sb.Append(";"); sb.Append(" "); /// Const.MA . . konstanta druheho etalonu
sb.Append(";"); sb.Append(tstRslt.TimeDivStart0); /// Time Div Start celkovy cas v [ms]
sb.Append(";"); sb.Append(tstRslt.TimeDivStart1); /// Time Div Start1
sb.Append(";"); sb.Append(tstRslt.TimeDivStart2); /// Time Div Start2
sb.Append(";"); sb.Append(tstRslt.TimeDivStart3); /// Time Div Start3
sb.Append(";"); sb.Append(tstRslt.TimeDivStart4); /// Time Div Start4
sb.Append(";"); sb.Append(tstRslt.TimeDivStart5); /// Time Div Start5
sb.Append(";"); sb.Append(tstRslt.TimeDivEnd0); /// Time Div End celkovy cas v [ms]
sb.Append(";"); sb.Append(tstRslt.TimeDivEnd1); /// Time Div End1
sb.Append(";"); sb.Append(tstRslt.TimeDivEnd2); /// Time Div End2
sb.Append(";"); sb.Append(tstRslt.TimeDivEnd3); /// Time Div End3
sb.Append(";"); sb.Append(tstRslt.TimeDivEnd4); /// Time Div End4
sb.Append(";"); sb.Append(tstRslt.TimeDivEnd5); /// Time Div End5
sb.Append(";"); sb.Append(currentRefPulses); /// Celkovy pocet et. pulzov skusky
sb.Append(";"); sb.Append(" "); /// - '' - pre druhy
for (int i = 0; i < tstRslt.Meters.Count; i++)
{
Entities.MeterTestResult mtrRslt = tstRslt.Meters[i];
sb.Append(";"); sb.Append(mtrRslt.SerialNr); /// WM Ser.No.
sb.Append(";"); sb.Append(mtrRslt.VolumeStart); /// WM Vinit - pri pevnom starte pociatocny stav natukany alebo cez inteligentny system
sb.Append(";"); sb.Append(mtrRslt.VolumeEnd); /// WM Vfin - pri pevnom starte konecny stav natukany alebo cez inteligentny system
sb.Append(";"); sb.Append(mtrRslt.VolumeMeter); /// WM Vmer - objem namerany vodomerom
sb.Append(";"); sb.Append(mtrRslt.VolumeRef); /// WM Vet - objem namerany stanicou
sb.Append(";"); sb.Append(mtrRslt.VolumeErrorPct); /// WM Emt - chyba vodomerom nameraneho objemu
sb.Append(";"); sb.Append(" "); /// WM U - neistota (zatial nechat prazdne)
sb.Append(";"); sb.Append(mtrRslt.PulsesMeter); /// WM Np met - pocet impulzov zo skusaneho meradla
sb.Append(";"); sb.Append(mtrRslt.PulsesMaster); /// WM Np elm - pocet impulzov etalonu pocas merania pre prislusny vodomer
sb.Append(";"); sb.Append(mtrRslt.Time); /// WM Tmet - cas merania (obmedzany pri synchro skuske)
bool ok = (mtrRslt.VolumeErrorPct >= tstRslt.ErrLimLo) && (mtrRslt.VolumeErrorPct <= tstRslt.ErrLimHi);
sb.Append(";"); sb.Append(ok ? "OK" : "NOK"); /// WM Vysledok (t.j. ci je v hraniciach chyb) - OK/NOK
sb.Append(";"); sb.Append(" "); /// WM AN value - hodnota z analogoveho prevodnika (teraz nic)
sb.Append(";"); sb.Append(" "); /// WM Vinit - pri datastreamovych hodnotach (alebo kamera)
sb.Append(";"); sb.Append(" "); /// WM Time init ???
sb.Append(";"); sb.Append(" "); /// WM Vend ???
sb.Append(";"); sb.Append(" "); /// WM Time end ???
}
for (int i = 0; i < tstRslt.CombinedMeters.Count; i++)
{
Entities.MeterTestResult mtrRslt = tstRslt.CombinedMeters[i];
sb.Append(";"); sb.Append(mtrRslt.SerialNr); /// WM Ser.No.
sb.Append(";"); sb.Append(mtrRslt.VolumeStart); /// WM Vinit - pri pevnom starte pociatocny stav natukany alebo cez inteligentny system
sb.Append(";"); sb.Append(mtrRslt.VolumeEnd); /// WM Vfin - pri pevnom starte konecny stav natukany alebo cez inteligentny system
sb.Append(";"); sb.Append(mtrRslt.VolumeMeter); /// WM Vmer - objem namerany vodomerom
sb.Append(";"); sb.Append(mtrRslt.VolumeRef); /// WM Vet - objem namerany stanicou
sb.Append(";"); sb.Append(mtrRslt.VolumeErrorPct); /// WM Emt - chyba vodomerom nameraneho objemu
sb.Append(";"); sb.Append(" "); /// WM U - neistota (zatial nechat prazdne)
sb.Append(";"); sb.Append(mtrRslt.PulsesMeter); /// WM Np met - pocet impulzov zo skusaneho meradla
sb.Append(";"); sb.Append(mtrRslt.PulsesMaster); /// WM Np elm - pocet impulzov etalonu pocas merania pre prislusny vodomer
sb.Append(";"); sb.Append(mtrRslt.Time); /// WM Tmet - cas merania (obmedzany pri synchro skuske)
bool ok = (mtrRslt.VolumeErrorPct >= tstRslt.ErrLimLo) && (mtrRslt.VolumeErrorPct <= tstRslt.ErrLimHi);
sb.Append(";"); sb.Append(ok ? "OK" : "NOK"); /// WM Vysledok (t.j. ci je v hraniciach chyb) - OK/NOK
sb.Append(";"); sb.Append(" "); /// WM AN value - hodnota z analogoveho prevodnika (teraz nic)
sb.Append(";"); sb.Append(" "); /// WM Vinit - pri datastreamovych hodnotach (alebo kamera)
sb.Append(";"); sb.Append(" "); /// WM Time init ???
sb.Append(";"); sb.Append(" "); /// WM Vend ???
sb.Append(";"); sb.Append(" "); /// WM Time end ???
}
sb.Append(";");
return sb.ToString();
}
}
}