2076 lines
109 KiB
C#
2076 lines
109 KiB
C#
///
|
|
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
|
///
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using log4net;
|
|
using Common;
|
|
using Config;
|
|
using Config.Entities;
|
|
using TBF.Rig.GenericDevices;
|
|
using TBF.Rig.Operations;
|
|
using TBF.Boxes;
|
|
using TBF.Resources;
|
|
using TBF.UiBridge;
|
|
|
|
namespace TBF.Rig.Sequences
|
|
{
|
|
/// <summary>
|
|
/// Sequence is a group of states that can be dynamically added to
|
|
/// and removed from the state machine
|
|
/// </summary>
|
|
public class SequenceBase : ProcessData
|
|
{
|
|
private static readonly ILog log = LogManager.GetLogger(typeof(SequenceBase));
|
|
|
|
protected static readonly ILog processDataLogger = LogManager.GetLogger("ProcessData");
|
|
protected static readonly ILog allResults = LogManager.GetLogger("AllResults");
|
|
protected static readonly ILog summaryResults = LogManager.GetLogger("SummaryResults");
|
|
|
|
|
|
public const int FlowSettingTimeoutSec = 300; /// Flow setting timeout = 5 min.
|
|
public const int StableMassMsrmntTimeoutSec = 300; /// Stable mass measurement timeout = 5 min.
|
|
public const int CountWhenSendingRdDivCmd = 1; /// Passed to cBrd.ReadDiverterTransitionOp()
|
|
public const int CountWhenReadingDiv = 3; /// Passed to cBrd.ReadDiverterTransitionOp()
|
|
|
|
|
|
///------------------------------------------------------------
|
|
/// Global static variables set only once.
|
|
///------------------------------------------------------------
|
|
public static IList<IFlowMeter> FlowMeters; /// list of reference flowmeters
|
|
public static IList<RegValvePosition> RegVPositions; /// list of regulation valves
|
|
public static IList<IPumpFM> PumpsWithFM; /// list of FM controlled pumps
|
|
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
|
|
///------------------------------------------------------------
|
|
public static int ReferenceFlowmetersCount;
|
|
public static double[] CalibratedLtrPerRefPulse; /// Reference flowmeter coefficients
|
|
public static double Qrise;
|
|
public static double Qfall;
|
|
|
|
|
|
///------------------------------------------------------------
|
|
/// Test related (instance) variables.
|
|
/// Created when test sequence is open.
|
|
/// They persist during all repetitions of the same test
|
|
///------------------------------------------------------------
|
|
protected static Rig.FeedingPath inPath;
|
|
protected static Rig.BenchPath benchPath;
|
|
protected static Rig.OutputPath outPath;
|
|
protected static Rig.MetersPath sensPath;
|
|
protected static Rig.HeatMetersPath heatMetersPath;
|
|
|
|
protected static TransitionSequence transitionBefore;
|
|
protected static TransitionSequence transitionBetween;
|
|
protected static TransitionSequence transitionAfter;
|
|
|
|
/// <summary>
|
|
/// Advanced information about the next test
|
|
/// </summary>
|
|
protected static Rig.FeedingPath nextInPath;
|
|
protected static Rig.BenchPath nextBenchPath;
|
|
protected static Rig.OutputPath nextOutPath;
|
|
protected static Rig.MetersPath nextSensPath;
|
|
protected static Rig.HeatMetersPath nextHeatMetersPath;
|
|
protected static TransitionSequence nextTransitionBefore;
|
|
protected static float nextQfrom;
|
|
protected static float nextQto;
|
|
protected static float nextPumpPower;
|
|
protected static float nextPidCoef;
|
|
protected static double nextTolerRed;
|
|
|
|
|
|
protected IOperation readRegistersOp;
|
|
protected IOperation queryEnd1;
|
|
protected IOperation queryEnd2;
|
|
protected IOperation checkUiOp;
|
|
|
|
protected IOperation processDataLoggingOp;
|
|
protected IOperation enduranceDataLoggingOp;
|
|
|
|
|
|
protected GenericDevices.IDataEntry lastDataEntryCmpnt;
|
|
|
|
|
|
///
|
|
/// Process data logging
|
|
///
|
|
public void LogProcessDataTestInfo(ILog logger, string procedureName, string testName)
|
|
{
|
|
logger.Info(Environment.NewLine);
|
|
logger.InfoFormat("{0}={1:dd.MM.yyyy HH:mm:ss} {2}={3} {4}={5} {6}={7}",
|
|
Strings.Date_and_time, TestStartTime,
|
|
Strings.Batch_nr, BatchRslts.Batch.BatchNr,
|
|
Strings.Procedure, procedureName,
|
|
Strings.Test, testName);
|
|
}
|
|
|
|
public void LogProcessDataHeader(ILog logger)
|
|
{
|
|
LogProcessDataHeader(logger, null);
|
|
}
|
|
|
|
public void LogProcessDataHeader(ILog logger, string sectionName)
|
|
{
|
|
logger.Info(Environment.NewLine);
|
|
if (sectionName != null) logger.Info(sectionName);
|
|
logger.Info("Time Flow TstTime Ref.cnt Ref.vol Tup Tdown Tdiv Pup Pdown Pdelta Mass VolMM Tamb Hamb Pamb Rv");
|
|
logger.Info(Environment.NewLine);
|
|
}
|
|
|
|
public void LogProcessData(ILog logger)
|
|
{
|
|
logger.InfoFormat("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15} {16}",
|
|
DateTime.Now.ToLongTimeString(),
|
|
Utils.DoubleToStr(RefFlow.Val, 4), /// flow measured by the reference flow meter in m3/h
|
|
StateMachine.ControlBoard.TTime.ToString("F3"), /// test time in s
|
|
StateMachine.ControlBoard.RefPulses, /// reference flow meter pulses count
|
|
Formulas.VolumeFromPulses(StateMachine.ControlBoard.RefPulses, 1.0f / LtrPerRefPulse).ToString("F3"), /// volume in l
|
|
TempUp, /// water temperature at the beginning of test line in degree C
|
|
TempDown, /// water temperature at the end of test line in degree C
|
|
TempDiv, /// water temperature at the diverter in degree C
|
|
PressUp, /// water pressure at the beginning of test line in bar (= 100 kPa)
|
|
PressDown, /// water pressure at the end of test line in bar (= 100 kPa)
|
|
PressDelta,
|
|
Mass, /// collected water mass in kg
|
|
"VolMM",
|
|
AmbTemp, /// ambient temperature in degree C
|
|
AmbHumi, /// ambient humidity in R%
|
|
AmbPress, /// ambient pressure in mbar (= 1 hPa)
|
|
outPath.RegulValve.Position.ToString("F1")); /// regulation valve position in % (0=closed / 100=open)
|
|
}
|
|
|
|
public void LogProcessDataHeaderHeatMeters(ILog logger, string sectionName)
|
|
{
|
|
logger.Info(Environment.NewLine);
|
|
if (sectionName != null) logger.Info(sectionName);
|
|
logger.Info("Time Flow TstTime Ref.cnt Ref.vol Tup Tdown Tdiv Pup Pdown Pdelta Mass VolMM Tamb Hamb Pamb Rv Thiac1 Thiac2 Tloac1 Tloac2");
|
|
logger.Info(Environment.NewLine);
|
|
}
|
|
|
|
public void LogProcessDataHeatMeters(ILog logger)
|
|
{
|
|
logger.InfoFormat("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15} {16} {17} {18} {19} {20}",
|
|
DateTime.Now.ToLongTimeString(),
|
|
Utils.DoubleToStr(RefFlow.Val, 4),
|
|
StateMachine.ControlBoard.TTime.ToString("F3"),
|
|
StateMachine.ControlBoard.RefPulses,
|
|
Formulas.VolumeFromPulses(StateMachine.ControlBoard.RefPulses, 1.0f / LtrPerRefPulse).ToString("F3"),
|
|
TempUp,
|
|
TempDown,
|
|
TempDiv,
|
|
PressUp,
|
|
PressDown,
|
|
PressDelta,
|
|
Mass,
|
|
"VolMM",
|
|
AmbTemp,
|
|
AmbHumi,
|
|
AmbPress,
|
|
outPath.RegulValve.Position.ToString("F1"),
|
|
TempRefHi1,
|
|
TempRefHi2,
|
|
TempRefLo1,
|
|
TempRefLo2);
|
|
}
|
|
|
|
///
|
|
/// Endurance data logging
|
|
///
|
|
public void LogEnduranceHeader(System.IO.StreamWriter writer)
|
|
{
|
|
LogEnduranceHeader(writer, null);
|
|
}
|
|
|
|
public void LogEnduranceHeader(System.IO.StreamWriter writer, string sectionName)
|
|
{
|
|
writer.WriteLine();
|
|
if (sectionName != null)
|
|
writer.Write(sectionName);
|
|
writer.WriteLine("Time T_up T_dn Pr_up Pr_dn Flow");
|
|
}
|
|
|
|
public void LogEnduranceData(System.IO.StreamWriter writer)
|
|
{
|
|
|
|
writer.WriteLine(string.Format("{0:dd.MM.yyyy HH:mm.ss} {1} {2} {3} {4} {5}",
|
|
DateTime.Now,
|
|
TempUp,
|
|
TempDown,
|
|
PressUp,
|
|
PressDown,
|
|
RefFlow));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Used in tests in measurement loop to display remaining test time
|
|
/// </summary>
|
|
/// <param name="remainingTime">Remaining time in seconds</param>
|
|
protected void ShowRemainingTime(int remainingTime)
|
|
{
|
|
if (remainingTime > 60)
|
|
{
|
|
Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Test_in_progress, remainingTime / 60, "min", remainingTime % 60, Strings.sec));
|
|
}
|
|
else
|
|
{
|
|
Bridge.OnActivity(this, string.Format("{0} ... {1} s", Strings.Test_in_progress, remainingTime));
|
|
}
|
|
}
|
|
|
|
protected Event DrainTheTank(IScaleOrTank tank)
|
|
{
|
|
return DrainTheTank(tank, new List<IOperation>());
|
|
}
|
|
|
|
protected Event DrainTheTank(IScaleOrTank tank, IOperation extraOperation)
|
|
{
|
|
IList<IOperation> extraOperations = new List<IOperation>();
|
|
extraOperations.Add(extraOperation);
|
|
return DrainTheTank(tank, extraOperations);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Empties the tank: opens the emptying valve and measures the weight.
|
|
/// </summary>
|
|
/// <param name="drainValve">Valve to empty the tank</param>
|
|
/// <param name="tank">Scale underneath the tank</param>
|
|
/// <returns>Event.Done or Event.Error</returns>
|
|
protected Event DrainTheTank(IScaleOrTank tank, IList<IOperation> extraOperations)
|
|
{
|
|
IList<Event> e;
|
|
bool stopped = false;
|
|
Bridge.Bench2UI(ButtonsEtc.StopBtnEn);
|
|
IntBox remainingTimeSec = new IntBox();
|
|
|
|
Bridge.OnActivity(this, TBF.Resources.Strings.Emptying_tank);
|
|
|
|
if (tank.DrainValve2 == null)
|
|
{
|
|
///
|
|
/// Draining with 1 valve 'DrainValve'
|
|
///
|
|
State.Create("SequenceBase : Open the drain valve")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(tank.DrainValve, null))
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
}
|
|
while (!e.Contains(Event.ValvesSet));
|
|
|
|
IOperation timer = new TimerOp(tank.EmptyTimeSec, remainingTimeSec);
|
|
do
|
|
{
|
|
State.Create("SequenceBase : Draining the tank")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(timer)
|
|
.AddOperation((tank is IScale) ? (tank as IScale).ReadMassOp(ref Mass) : null)
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error)) return Event.Error;
|
|
if (TestAndLogUiCmdStop(e))
|
|
{
|
|
stopped = true;
|
|
break;
|
|
}
|
|
if (e.Contains(Event.BalanceOverload)) { }; /// Tank should be emptying now
|
|
///
|
|
if (!(tank is IScale))
|
|
{
|
|
Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}",
|
|
Strings.Emptying_tank,
|
|
remainingTimeSec.Val / 60, "min",
|
|
remainingTimeSec.Val % 60, Strings.sec));
|
|
}
|
|
}
|
|
while ((tank is IScale) && !e.Contains(Event.BalanceDone));
|
|
|
|
if (stopped) break;
|
|
}
|
|
while (!tank.IsEmpty() && !e.Contains(Event.TimerExpired));
|
|
}
|
|
else
|
|
{
|
|
///
|
|
/// Draining with 2 valves: 'DrainValve' is open in the 2nd half of time, 'DrainValve2' is open all the time
|
|
///
|
|
State.Create("SequenceBase : Open the drain valve")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(tank.DrainValve2, null))
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
}
|
|
while (!e.Contains(Event.ValvesSet));
|
|
|
|
///
|
|
/// 1st half
|
|
///
|
|
IOperation timer1 = new TimerOp(tank.EmptyTimeSec / 2, remainingTimeSec);
|
|
do
|
|
{
|
|
State.Create("SequenceBase : Draining the tank")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(timer1)
|
|
.AddOperation((tank is IScale) ? (tank as IScale).ReadMassOp(ref Mass) : null)
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error)) return Event.Error;
|
|
if (TestAndLogUiCmdStop(e))
|
|
{
|
|
stopped = true;
|
|
break;
|
|
}
|
|
if (e.Contains(Event.BalanceOverload)) { }; /// Tank should be emptying now
|
|
///
|
|
if (!(tank is IScale))
|
|
{
|
|
Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}",
|
|
Strings.Emptying_tank,
|
|
(remainingTimeSec.Val + tank.EmptyTimeSec / 2) / 60, "min",
|
|
(remainingTimeSec.Val + tank.EmptyTimeSec / 2) % 60, Strings.sec));
|
|
}
|
|
}
|
|
while ((tank is IScale) && !e.Contains(Event.BalanceDone));
|
|
|
|
if (stopped) break;
|
|
}
|
|
while (!tank.IsEmpty() && !e.Contains(Event.TimerExpired));
|
|
|
|
///
|
|
/// 2nd half
|
|
///
|
|
if (!tank.IsEmpty())
|
|
{
|
|
State.Create("SequenceBase : Open the 2nd drain valve")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(tank.DrainValve, null))
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
}
|
|
while (!e.Contains(Event.ValvesSet));
|
|
|
|
IOperation timer2 = new TimerOp(tank.EmptyTimeSec / 2, remainingTimeSec);
|
|
do
|
|
{
|
|
State.Create("SequenceBase : Draining the tank")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(timer2)
|
|
.AddOperation((tank is IScale) ? (tank as IScale).ReadMassOp(ref Mass) : null)
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error)) return Event.Error;
|
|
if (TestAndLogUiCmdStop(e))
|
|
{
|
|
stopped = true;
|
|
break;
|
|
}
|
|
if (e.Contains(Event.BalanceOverload)) { }; /// Tank should be emptying now
|
|
///
|
|
if (!(tank is IScale))
|
|
{
|
|
Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}",
|
|
Strings.Emptying_tank,
|
|
remainingTimeSec.Val / 60, "min",
|
|
remainingTimeSec.Val % 60, Strings.sec));
|
|
}
|
|
|
|
}
|
|
while ((tank is IScale) && !e.Contains(Event.BalanceDone));
|
|
|
|
if (stopped) break;
|
|
}
|
|
while (!tank.IsEmpty() && !e.Contains(Event.TimerExpired));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Quit emptying, close the drain valve
|
|
//
|
|
State.Create("SequenceBase : Closing the drain valve")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation((tank is IScale) ? (tank as IScale).ReadMassOp(ref Mass) : null)
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(null, tank.DrainValve))
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error)) return Event.Error;
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
}
|
|
while (!e.Contains(Event.ValvesSet) || ((tank is IScale) && !e.Contains(Event.BalanceDone)));
|
|
|
|
if (tank.DrainValve2 != null)
|
|
{
|
|
State.Create("SequenceBase : Closing the 2nd drain valve")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation((tank is IScale) ? (tank as IScale).ReadMassOp(ref Mass) : null)
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(null, tank.DrainValve2))
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error)) return Event.Error;
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
}
|
|
while (!e.Contains(Event.ValvesSet) || ((tank is IScale) && !e.Contains(Event.BalanceDone)));
|
|
}
|
|
|
|
if (tank is IScale)
|
|
{
|
|
State.Create("SequenceBase : Updating the mass")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation((tank as IScale).ReadMassOp(ref Mass))
|
|
.AddOperation(new Operations.TimerOp(5))
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error)) return Event.Error;
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
}
|
|
while (!e.Contains(Event.BalanceDone) || !e.Contains(Event.TimerExpired));
|
|
}
|
|
|
|
if (stopped)
|
|
return Event.UiCmdStop;
|
|
else
|
|
return Event.Done;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Passed as an argument to Transition(sequence, context)
|
|
/// </summary>
|
|
public enum TransitionContext
|
|
{
|
|
PurgeBegin,
|
|
BeforeTest, /// Before starting a test, paths are always applied aftr this sequence
|
|
BetweenTests, /// Between two repetitions of the same test
|
|
AfterTest, /// After completing a test
|
|
AfterTestWithOverlap, /// After completing transition sequence paths of the next test are selected and flow setting starts
|
|
PurgeEnd,
|
|
Stop,
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Calculates the estimate of transition sequence execution time
|
|
/// </summary>
|
|
/// <param name="transitionSequence">TransitionSequence entity</param>
|
|
/// <returns>Time in seconds</returns>
|
|
protected int GetTransitionTimeEst(TransitionSequence transitionSequence)
|
|
{
|
|
if (transitionSequence == null) return 1;
|
|
|
|
return 30; /// TODO: Implement time estimte calculation
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Returns a list of reg.valve positioning operations
|
|
/// </summary>
|
|
/// <param name="regVPositions">List of reg.valve/position pairs, position is in %, position LT 0 ... no operation</param>
|
|
/// <returns>List of reg.valve positioning operations</returns>
|
|
List<IOperation> GetRegVPositioningOps(IList<RegValvePosition> regVPositions)
|
|
{
|
|
List<IOperation> rvPosOps = new List<IOperation>();
|
|
|
|
if (regVPositions == null) return rvPosOps;
|
|
|
|
foreach (var rvp in regVPositions)
|
|
{
|
|
if (rvp.Position >= 0) /// Negative value means no position change
|
|
{
|
|
if (rvp.RegValve.IsCoax)
|
|
{
|
|
rvPosOps.Add(rvp.RegValve.SetRegulValvePositionOp(rvp.Position, -1, 60));
|
|
}
|
|
else
|
|
{
|
|
rvPosOps.Add(rvp.RegValve.SetRegulValvePositionOp(rvp.Position - 3.0f, rvp.Position + 3.0f, 60));
|
|
}
|
|
}
|
|
}
|
|
|
|
return rvPosOps;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Executes steps of a transition sequence
|
|
/// </summary>
|
|
/// <param name="transitionSequence">TransitionSequence entity</param>
|
|
/// <param name="context">Calling context (see above)</param>
|
|
/// <returns>
|
|
/// Event.Done Transition sequence completed OK
|
|
/// Event.UiCmdStop Transition sequence interrupted by the STOP on-screen button
|
|
/// Event.Error Error (e.g. RegulValveTimeOut returned by Run() of SetRegulValvePositionOp)
|
|
/// </returns>
|
|
protected Event Transition(TransitionSequence transitionSequence, TransitionContext context)
|
|
{
|
|
bool stopFlag = false;
|
|
bool errorFlag = false;
|
|
IList<Event> e;
|
|
string message;
|
|
///
|
|
switch (context)
|
|
{
|
|
case TransitionContext.PurgeBegin: message = Strings.Purging_i_n; break;
|
|
case TransitionContext.BeforeTest: message = Strings.Test_start_sequence_i_n; break;
|
|
case TransitionContext.BetweenTests: message = Strings.Between_tests_sequence_i_n; break;
|
|
|
|
case TransitionContext.AfterTestWithOverlap:
|
|
case TransitionContext.AfterTest:
|
|
message = Strings.Test_stop_sequence_i_n;
|
|
break;
|
|
|
|
case TransitionContext.PurgeEnd: message = Strings.Emptying_i_n; break;
|
|
case TransitionContext.Stop: message = Strings.Test_stop_sequence_i_n; break;
|
|
default: message = "Transition"; break;
|
|
}
|
|
|
|
if (context == TransitionContext.PurgeBegin && FillState != FillState.Full) FillState = FillState.Unknown;
|
|
if (context == TransitionContext.PurgeEnd && FillState != FillState.Empty) FillState = FillState.Unknown;
|
|
|
|
if (transitionSequence == null)
|
|
{
|
|
///
|
|
/// No transition sequence defined --> Default action
|
|
///
|
|
if ((context == TransitionContext.AfterTest) || (context == TransitionContext.AfterTestWithOverlap))
|
|
{
|
|
log.WarnFormat("Transition(null, context={0}), turning FM pump off and setting valves to defaults", context);
|
|
|
|
if (inPath.Pump is GenericDevices.IPumpFM) (inPath.Pump as GenericDevices.IPumpFM).TurnOff();
|
|
|
|
State.Create("SequenceBase : Transition : TestEnd - Default action")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(StateMachine.DefaultValvesOpen, StateMachine.DefaultValvesClose))
|
|
.EnterState();
|
|
do {
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
}
|
|
while (!e.Contains(Event.ValvesSet));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
///
|
|
/// Fetch and execute the transition sequence, it is guaranteed (transitionSequence != null)
|
|
///
|
|
IList<TransitionStep> transitionSteps = new List<TransitionStep>();
|
|
if (StateMachine.TransitionSteps != null)
|
|
{
|
|
foreach (var step in StateMachine.TransitionSteps)
|
|
{
|
|
if ((step.TransitionSequence != null) && (step.TransitionSequence.Id == transitionSequence.Id))
|
|
{
|
|
transitionSteps.Add(step);
|
|
}
|
|
}
|
|
}
|
|
|
|
int stepsCount = transitionSteps.Count;
|
|
|
|
log.WarnFormat("Transition(sequence={0} ({1} steps), context={2})", transitionSequence.Name, stepsCount, context);
|
|
|
|
foreach (var step in transitionSteps)
|
|
{
|
|
//------------------------------------------------
|
|
string activity = string.Format(message, transitionSequence.Name, step.ItemNr + 1, stepsCount);
|
|
Bridge.OnActivity(this, activity);
|
|
Bridge.OnMessage(this, step.Message);
|
|
log.InfoFormat("{0} {1}", activity, step.Message);
|
|
//------------------------------------------------
|
|
|
|
/// Prepare operation to switch valves
|
|
IOperation setValvesOp = StateMachine.ControlBoard.SetValvesOp(Utils.ValvesOpen(step), Utils.ValvesClose(step));
|
|
|
|
/// Fetch the condition operation, null value is allowed if there is no condition
|
|
IOperation conditionOperation = null;
|
|
if (step.EndCondition != "None")
|
|
{
|
|
string[] fields = step.EndCondition.Split(new char[]{'~'});
|
|
if (fields.Length == 2)
|
|
{
|
|
ISequenceCondition seqCondition = TbfComponents.FindComponent(fields[0]) as ISequenceCondition;
|
|
int condID;
|
|
if ((seqCondition != null) && int.TryParse(fields[1], out condID))
|
|
{
|
|
conditionOperation = seqCondition.ConditionOp(condID);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// FM controlled pumps are canged imediately without using any state operations
|
|
log.DebugFormat("step.PumpWithFMPcts = {0}", step.PumpWithFMPcts);
|
|
float[] allFMPumpPcts = Utils.GetPumpWithFMPcts(step.PumpWithFMPcts);
|
|
for (int i = 0; i < allFMPumpPcts.Length; i++)
|
|
{
|
|
float pwr = allFMPumpPcts[i];
|
|
if (pwr > 0) /// Negative value means no power change
|
|
{
|
|
PumpsWithFM[i].TurnOn(pwr);
|
|
}
|
|
else if (pwr == 0)
|
|
{
|
|
PumpsWithFM[i].TurnOff();
|
|
}
|
|
}
|
|
|
|
|
|
Utils.UpdateRegVPositionsFromStr(ref RegVPositions, step.RegulValvesPct);
|
|
IList<IOperation> rvPosOps = GetRegVPositioningOps(RegVPositions);
|
|
|
|
/// Max. one SetRegulValvePositionOp can be started or stopped in one sub-step.
|
|
/// Therefore SetRegulValvePositionOp operations are added and removed to subsequent states one by one.
|
|
int delay = Math.Max(2, step.Duration - rvPosOps.Count + 2);
|
|
|
|
///
|
|
int lastStartedRV = -1;
|
|
for (int i = 0; i < rvPosOps.Count; i++)
|
|
{
|
|
log.DebugFormat("SequenceBase.Transition() : Step {0} start, opening={1}, closing={2}", step.ItemNr + 1, step.ValvesOpen, step.ValvesClose);
|
|
State stepStrt = State
|
|
.Create(string.Format("SequenceBase.Transition() : Step {0} start, opening={1}, closing={2}", step.ItemNr + 1, step.ValvesOpen, step.ValvesClose))
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(conditionOperation)
|
|
.AddOperation(setValvesOp);
|
|
for (int j = 0; j <= i; j++)
|
|
{
|
|
stepStrt.AddOperation(rvPosOps[j]);
|
|
}
|
|
lastStartedRV = i;
|
|
stepStrt.EnterState();
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error) || e.Contains(Event.RegulValveTimeOut)) { errorFlag = true; break; }
|
|
if (TestAndLogUiCmdStop(e)) { stopFlag = true; break; }
|
|
}
|
|
/// Max. valaue of lastStartedRV after exitting the loop is (rvPosOps.Count - 1)
|
|
|
|
if (!stopFlag && !errorFlag)
|
|
{
|
|
log.DebugFormat("SequenceBase.Transition() : Step {0} delay {1}s, opening={2}, closing={3}", step.ItemNr + 1, delay, step.ValvesOpen, step.ValvesClose);
|
|
State stepDelay = State
|
|
.Create(string.Format("SequenceBase.Transition() : Step {0} delay {1}s, opening={2}, closing={3}", step.ItemNr + 1, delay, step.ValvesOpen, step.ValvesClose))
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(conditionOperation)
|
|
.AddOperation(setValvesOp)
|
|
.AddOperation(new TimerOp(delay));
|
|
for (int j = 0; j <= lastStartedRV; j++)
|
|
{
|
|
stepDelay.AddOperation(rvPosOps[j]);
|
|
}
|
|
stepDelay.EnterState();
|
|
bool endContitionFulfilled = false;
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error) || e.Contains(Event.RegulValveTimeOut)) { errorFlag = true; break; }
|
|
if (TestAndLogUiCmdStop(e)) { stopFlag = true; break; }
|
|
|
|
if (e.Contains(Event.ConditionMet)) endContitionFulfilled = true; ;
|
|
/*
|
|
switch (step.EndCondition)
|
|
{
|
|
case StepCondition.Scale1Empty:
|
|
endContitionFulfilled = (StateMachine.Scale1 == null) || StateMachine.Scale1.IsEmpty();
|
|
break;
|
|
case StepCondition.Scale2Empty:
|
|
endContitionFulfilled = (StateMachine.Scale2 == null) || StateMachine.Scale2.IsEmpty();
|
|
break;
|
|
case StepCondition.Scale3Empty:
|
|
endContitionFulfilled = (StateMachine.Scale3 == null) || StateMachine.Scale3.IsEmpty();
|
|
break;
|
|
case StepCondition.AllScalesEmpty:
|
|
endContitionFulfilled = ((StateMachine.Scale1 == null) || StateMachine.Scale1.IsEmpty()) &&
|
|
((StateMachine.Scale2 == null) || StateMachine.Scale2.IsEmpty()) &&
|
|
((StateMachine.Scale3 == null) || StateMachine.Scale3.IsEmpty());
|
|
break;
|
|
}
|
|
*/
|
|
}
|
|
while (e.Contains(Event.ValvesBusy) || (!endContitionFulfilled && e.Contains(Event.TimerBusy) && !e.Contains(Event.Next)));
|
|
}
|
|
|
|
for (int first = 1; first <= lastStartedRV; first++)
|
|
{
|
|
log.DebugFormat("SequenceBase.Transition() : Step {0} stop, opening={1}, closing={2}", step.ItemNr + 1, step.ValvesOpen, step.ValvesClose);
|
|
State stepStop = State
|
|
.Create(string.Format("SequenceBase.Transition() : Step {0} stop, opening={1}, closing={2}", step.ItemNr + 1, step.ValvesOpen, step.ValvesClose))
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(conditionOperation)
|
|
.AddOperation(setValvesOp);
|
|
for (int j = first; j <= lastStartedRV; j++)
|
|
{
|
|
stepStop.AddOperation(rvPosOps[j]);
|
|
}
|
|
stepStop.EnterState();
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error) || e.Contains(Event.RegulValveTimeOut)) { errorFlag = true; }
|
|
if (TestAndLogUiCmdStop(e)) { stopFlag = true; }
|
|
}
|
|
|
|
if (errorFlag || stopFlag) break;
|
|
}
|
|
|
|
Bridge.OnMessage(this, string.Empty); /// Clear the last step message
|
|
}
|
|
|
|
///
|
|
/// Do this after executing the transition sequence
|
|
///
|
|
if (context == TransitionContext.Stop || errorFlag || stopFlag)
|
|
{
|
|
log.ErrorFormat("Transition({0}, context={1}) errorFlag={2} stopFlag={3} ... stoppng all pumps off",
|
|
(transitionSequence != null) ? transitionSequence.Name : "null", context, errorFlag, stopFlag);
|
|
|
|
///
|
|
/// On error or when STOP pressed
|
|
///
|
|
foreach (var fmPump in PumpsWithFM) fmPump.TurnOff();
|
|
|
|
if (inPath != null)
|
|
{
|
|
///
|
|
/// Stop the pump
|
|
///
|
|
State.Create("SequenceBase.Transition() : Test stopped -> Stopping the pump")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(null, inPath.Pump))
|
|
.EnterState();
|
|
do {
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error)) return Event.Error;
|
|
}
|
|
while (!e.Contains(Event.ValvesSet));
|
|
}
|
|
}
|
|
else if (context == TransitionContext.BeforeTest && inPath != null && benchPath != null && outPath != null)
|
|
{
|
|
log.WarnFormat("Transition(any, context={0}), setting the required route before a test", context);
|
|
|
|
///
|
|
/// Always set route at the beginning of this test
|
|
///
|
|
List<IOperation> regVPosOps = GetRegVPositioningOps(inPath.RegVPositions);
|
|
regVPosOps.AddRange(GetRegVPositioningOps(outPath.RegVPositions));
|
|
Event evnt = PerformSteps(GenericDevices.ValveBase.Merge(inPath.ValvesOpen, benchPath.ValvesOpen, outPath.ValvesOpen),
|
|
GenericDevices.ValveBase.Merge(inPath.ValvesClose, benchPath.ValvesClose, outPath.ValvesClose),
|
|
regVPosOps,
|
|
"SequenceBase : Transition : TestStart - Default action");
|
|
|
|
if (evnt == Event.Error || evnt == Event.UiCmdStop) return evnt;
|
|
}
|
|
else if (context == TransitionContext.AfterTestWithOverlap && nextInPath != null && nextBenchPath != null && nextOutPath != null)
|
|
{
|
|
log.WarnFormat("Transition(., context={0}), overlapped action (next flow regulation)", context);
|
|
|
|
///
|
|
/// Set route for the next test
|
|
///
|
|
List<IOperation> regVPosOps = GetRegVPositioningOps(nextInPath.RegVPositions);
|
|
regVPosOps.AddRange(GetRegVPositioningOps(nextOutPath.RegVPositions));
|
|
Event evnt = PerformSteps(GenericDevices.ValveBase.Merge(nextInPath.ValvesOpen, nextBenchPath.ValvesOpen, nextOutPath.ValvesOpen),
|
|
GenericDevices.ValveBase.Merge(nextInPath.ValvesClose, nextBenchPath.ValvesClose, nextOutPath.ValvesClose),
|
|
regVPosOps,
|
|
"SequenceBase : AfterTestWithOverlap : Default action");
|
|
|
|
if (evnt == Event.Error || evnt == Event.UiCmdStop) return evnt;
|
|
|
|
/// Set PID coefficient, etc.
|
|
int[] filters = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
StateMachine.ControlBoard.SetFiltersPidShortPulses(filters, nextPidCoef, (nextTolerRed == 0) ? 0 : 1);
|
|
|
|
/// Set pump power
|
|
if (nextInPath.Pump is GenericDevices.IPumpFM) (nextInPath.Pump as GenericDevices.IPumpFM).TurnOn(nextPumpPower);
|
|
|
|
//------------------------------------------------
|
|
Bridge.OnActivity(this, Strings.Setting_the_flow);
|
|
//------------------------------------------------
|
|
/// Set flow for the next test
|
|
State.Create(string.Format("SequenceBase : AfterTestWithOverlap - Setting the flow to {0} - {1} m3/h", nextQfrom, nextQto))
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(nextOutPath.RegulValve.SetFlowAndMeasureOp(nextOutPath.FlowMeter, nextQfrom, nextQto, RefFlow, FlowSettingTimeoutSec, 0))
|
|
.EnterState();
|
|
do {
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
|
|
if (e.Contains(Event.OpArgumentError)) return Event.Error;
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
if (e.Contains(Event.RegulValveTimeOut))
|
|
{
|
|
Bridge.OnError(this, Strings.Flow_adjustment_failed);
|
|
return Event.UiCmdStop;
|
|
}
|
|
}
|
|
while (!e.Contains(Event.Busy) && !e.Contains(Event.FlowReached));
|
|
}
|
|
|
|
if (errorFlag)
|
|
return Event.Error;
|
|
else if (stopFlag)
|
|
return Event.UiCmdStop;
|
|
else
|
|
{
|
|
if (context == TransitionContext.PurgeBegin) FillState = FillState.Full;
|
|
if (context == TransitionContext.PurgeEnd) FillState = FillState.Empty;
|
|
return Event.Done;
|
|
}
|
|
}
|
|
|
|
|
|
Event PerformSteps(IList<IValve> valvesToOpen, IList<IValve> valvesToClose, IList<IOperation> rvPosOps, string stateTitle)
|
|
{
|
|
bool stopFlag = false;
|
|
bool errorFlag = false;
|
|
IList<Event> e;
|
|
|
|
IOperation setValvesOp = StateMachine.ControlBoard.SetValvesOp(valvesToOpen, valvesToClose);
|
|
|
|
int lastStartedRV = -1;
|
|
for (int i = 0; i < rvPosOps.Count; i++)
|
|
{
|
|
State stepStrt = State.Create(stateTitle)
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(setValvesOp);
|
|
for (int j = 0; j <= i; j++) stepStrt.AddOperation(rvPosOps[j]);
|
|
lastStartedRV = i;
|
|
stepStrt.EnterState();
|
|
|
|
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error) || e.Contains(Event.RegulValveTimeOut)) { errorFlag = true; break; }
|
|
if (TestAndLogUiCmdStop(e)) { stopFlag = true; break; }
|
|
}
|
|
/// Max. valaue of lastStartedRV after exitting the loop is (rvPosOps.Count - 1)
|
|
|
|
|
|
if (!stopFlag && !errorFlag)
|
|
{
|
|
State stepRegul = State.Create(stateTitle)
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(setValvesOp);
|
|
for (int j = 0; j <= lastStartedRV; j++) stepRegul.AddOperation(rvPosOps[j]);
|
|
stepRegul.EnterState();
|
|
|
|
do {
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error) || e.Contains(Event.RegulValveTimeOut)) { errorFlag = true; break; }
|
|
if (TestAndLogUiCmdStop(e)) { stopFlag = true; break; }
|
|
}
|
|
while (e.Contains(Event.ValvesBusy) && !e.Contains(Event.Next));
|
|
}
|
|
|
|
|
|
for (int first = 1; first <= lastStartedRV; first++)
|
|
{
|
|
State stepStop = State.Create(stateTitle)
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(setValvesOp);
|
|
for (int j = first; j <= lastStartedRV; j++) stepStop.AddOperation(rvPosOps[j]);
|
|
stepStop.EnterState();
|
|
|
|
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error) || e.Contains(Event.RegulValveTimeOut)) { errorFlag = true; }
|
|
if (TestAndLogUiCmdStop(e)) { stopFlag = true; }
|
|
}
|
|
|
|
if (stopFlag) return Event.UiCmdStop;
|
|
if (errorFlag) return Event.Error;
|
|
return Event.Done;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Opens a modeless dialog for entering data at the beginning of a procedure (serial numbers)
|
|
/// </summary>
|
|
/// <returns>true = OK, false = stop pressed</returns>
|
|
protected bool OpenCycleBeginForm()
|
|
{
|
|
lastDataEntryCmpnt = TbfComponents.FindComponent(StateMachine.Procedure.DataEntry) as GenericDevices.IDataEntry;
|
|
|
|
if (lastDataEntryCmpnt is IHasCycleBeginForm)
|
|
{
|
|
Bridge.OnActivity(this, Strings.Enter_water_meter_data);
|
|
State.Create("MainSeq : Enter begin data")
|
|
.AddPermanentOperation((lastDataEntryCmpnt as IHasCycleBeginForm).ShowCycleBeginFormOp())
|
|
.AddOperation(checkUiOp)
|
|
.EnterState();
|
|
|
|
if (TestAndLogUiCmdStop(StateMachine.WaitRunDevsRunOps())) return false; /// Return false when STOP pressed
|
|
}
|
|
|
|
return true; /// OK (=either a cycle beginning form is open or DataEntry component is not IHasCycleBeginForm)
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Waits until a modeless dialog for entering data at the beginnig of a procedure is closed.
|
|
/// This function is typically called at the end of the first test of the procedure.
|
|
/// </summary>
|
|
/// <returns>false = OK, true = stop pressed</returns>
|
|
protected UIFlowControl WaitBeginFormClosed()
|
|
{
|
|
GenericDevices.IDataEntry dataEntryCmpnt =
|
|
TbfComponents.FindComponent(StateMachine.Procedure.DataEntry) as GenericDevices.IDataEntry;
|
|
|
|
bool stopPressed = false; /// true when STOP button pressed
|
|
|
|
if (dataEntryCmpnt is IHasCycleBeginForm)
|
|
{
|
|
IList<Event> e;
|
|
|
|
///
|
|
/// Wait until modeless form is closed by the user if it is stil open
|
|
///
|
|
if ( State.LastEvents.Contains(Event.ModelessFormIsOpen))
|
|
{
|
|
State.Create("MainSeq : Wait until the entry form is closed")
|
|
.AddOperation(checkUiOp)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (TestAndLogUiCmdStop(e))
|
|
{
|
|
stopPressed = true;
|
|
break;
|
|
}
|
|
}
|
|
while (!e.Contains(Event.ModelessFormClosed));
|
|
}
|
|
|
|
///
|
|
/// A state without any dataEntryCmpnt operation so that Stop() when entering
|
|
/// this state and Start() when entering the following state are executed.
|
|
///
|
|
State.Create("MainSeq : Stopping modeless form")
|
|
.AddOperation(checkUiOp)
|
|
.RemovePermanentOperation(dataEntryCmpnt as IOperation)
|
|
.EnterState();
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
|
|
if (TestAndLogUiCmdStop(e)) { stopPressed = true; }
|
|
}
|
|
|
|
return stopPressed ? UIFlowControl.Stop : UIFlowControl.Continue;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Forces closing of a modeless dialog for entering data at the beginnig of a procedure.
|
|
/// This function is typically called before starting a new cycle
|
|
/// in case previous cycle was aborted.
|
|
/// </summary>
|
|
protected void CloseBeginForm()
|
|
{
|
|
if (StateMachine.Procedure == null || StateMachine.Procedure.DataEntry == null) return;
|
|
|
|
GenericDevices.IDataEntry dataEntryCmpnt =
|
|
TbfComponents.FindComponent(StateMachine.Procedure.DataEntry) as GenericDevices.IDataEntry;
|
|
|
|
if ((dataEntryCmpnt is IHasCycleBeginForm) &&
|
|
(State.LastEvents.Contains(Event.ModelessFormIsOpen) || State.LastEvents.Contains(Event.ModelessFormClosed)))
|
|
{
|
|
IList<Event> e;
|
|
|
|
/// A state without any dataEntryCmpnt operation so that Stop() when entering
|
|
/// this state and Start() when entering the following state are executed.
|
|
State.Create("MainSeq : Stopping modeless form")
|
|
.RemovePermanentOperation(dataEntryCmpnt as IOperation)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
}
|
|
while (e.Contains(Event.ModelessFormIsOpen));
|
|
}
|
|
}
|
|
|
|
|
|
protected Event SetFlowEtc(Test test, IFlowMeter flowMeter, IRegValve regulValve, IValve pump, IValve stopBFValve, IList<IOperation> extraOperations, bool doNotWait)
|
|
{
|
|
IList<Event> e;
|
|
Event retVal = Event.Done;
|
|
|
|
if (pump is GenericDevices.IPumpFM) (pump as GenericDevices.IPumpFM).TurnOn(test.PumpPower);
|
|
///
|
|
State.Create(string.Format("{0}({1}) : Starting the pump", test.Method, test.Name))
|
|
.AddOperation(checkUiOp)
|
|
.AddOperations(extraOperations)
|
|
.AddOperation(pump != null ? StateMachine.ControlBoard.SetValvesOp(pump, null) : null)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
//Bridge.OnProcessData(this, new ProcessDataEventArgs(test, repetitionNr, Progress.FlowSetting));
|
|
//Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
|
|
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
if (e.Contains(Event.Error)) return Event.Error;
|
|
}
|
|
while (e.Contains(Event.ValvesBusy) /* || !e.Contains(Event.AllPositionsReached)*/);
|
|
|
|
|
|
if (test.TimePump2StartV > 0)
|
|
{
|
|
State.Create(string.Format("{0}({1}) : Waiting after the pump started", test.Method, test.Name))
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(new Operations.TimerOp(test.TimePump2StartV))
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
//Bridge.OnProcessData(this, new ProcessDataEventArgs(test, repetitionNr, Progress.FlowSetting));
|
|
//Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
|
|
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
}
|
|
while (!e.Contains(Event.TimerExpired));
|
|
}
|
|
|
|
|
|
if (stopBFValve != null)
|
|
{
|
|
State.Create(string.Format("{0}({1}) : Opening the stop backflow valve", test.Method, test.Name))
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(StateMachine.ControlBoard.SetValvesOp(stopBFValve, null))
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
if (e.Contains(Event.Error)) return Event.Error;
|
|
}
|
|
while (!e.Contains(Event.ValvesSet));
|
|
}
|
|
|
|
|
|
if (test.TimeBeforeFlow > 0)
|
|
{
|
|
State.Create(string.Format("{0}({1}) : Waiting before flow setting process starts", test.Method, test.Name))
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(new Operations.TimerOp(test.TimeBeforeFlow))
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
//Bridge.OnProcessData(this, new ProcessDataEventArgs(test, repetitionNr, Progress.FlowSetting));
|
|
//Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
|
|
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
}
|
|
while (!e.Contains(Event.TimerExpired));
|
|
}
|
|
|
|
//------------------------------------------------
|
|
Bridge.OnActivity(this, Strings.Setting_the_flow);
|
|
//------------------------------------------------
|
|
State.Create(string.Format("{0}({1}) : Setting the flow", test.Method, test.Name))
|
|
.AddOperation(checkUiOp)
|
|
.AddOperation(doNotWait ? regulValve.SetFlowAndMeasureOp(flowMeter, test.Qfrom, test.Qto, RefFlow, FlowSettingTimeoutSec, 0)
|
|
: regulValve.SetFlowOp(flowMeter, test.Qfrom, test.Qto, RefFlow, FlowSettingTimeoutSec))
|
|
.AddOperations(extraOperations)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
//Bridge.OnProcessData(this, new ProcessDataEventArgs(test, repetitionNr, Progress.FlowSetting));
|
|
//Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
|
|
|
|
if (e.Contains(Event.OpArgumentError)) return Event.OpArgumentError;
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
if (e.Contains(Event.RegulValveTimeOut))
|
|
{
|
|
Bridge.OnError(this, Strings.Flow_adjustment_failed);
|
|
return Event.RecoverableError;
|
|
}
|
|
if (e.Contains(Event.Next)) return Event.Done;
|
|
}
|
|
while (!(e.Contains(Event.FlowReached) || (doNotWait && e.Contains(Event.Busy)))); /// Stay in the loop while e.Contains(Event.Starting)
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
/// <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;
|
|
|
|
State.Create("Read water meters")
|
|
.AddOperation(checkUiOp)
|
|
.AddOperations(measureOperations)
|
|
.AddOperation(readRegistersOp)
|
|
.AddOperation(benchPath.TempMtrUp == null ? null : benchPath.TempMtrUp.ReadTempOp(ref TempUp))
|
|
.AddOperation(benchPath.TempMtrDown == null ? null : benchPath.TempMtrDown.ReadTempOp(ref TempDown))
|
|
.AddOperation(outPath.TempDiv == null ? null : outPath.TempDiv.ReadTempOp(ref TempDiv))
|
|
.AddOperation(benchPath.PressMtrUp == null ? null : benchPath.PressMtrUp.ReadPressureOp(ref PressUp))
|
|
.AddOperation(benchPath.PressMtrDown == null ? null : benchPath.PressMtrDown.ReadPressureOp(ref PressDown))
|
|
.AddOperation(benchPath.PressMtrDelta == null ? null : benchPath.PressMtrDelta.ReadPressureOp(ref PressDelta))
|
|
.AddOperation(heatMetersPath == null ? null : heatMetersPath.TMeterRefWarm1.ReadTempOp(ref TempRefHi1))
|
|
.AddOperation(heatMetersPath == null ? null : heatMetersPath.TMeterRefWarm2.ReadTempOp(ref TempRefHi2))
|
|
.AddOperation(heatMetersPath == null ? null : heatMetersPath.TMeterRefCold1.ReadTempOp(ref TempRefLo1))
|
|
.AddOperation(heatMetersPath == null ? null : heatMetersPath.TMeterRefCold2.ReadTempOp(ref TempRefLo2))
|
|
.AddOperation((realTest && (outPath.Scale is IScale)) ? (outPath.Scale as IScale).ReadMassOp(ref Mass) : null)
|
|
//.AddOperation(realTest ? (ticTac ? queryEnd1 : queryEnd2) : null)
|
|
.AddOperation(realTest ? queryEnd1 : null)
|
|
.AddOperation(realTest ? processDataLoggingOp : null)
|
|
.EnterState();
|
|
do
|
|
{
|
|
e = StateMachine.WaitRunDevsRunOps();
|
|
if (e.Contains(Event.Error)) return Event.Error;
|
|
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
|
|
if (e.Contains(Event.MeasurementCompleted) || e.Contains(Event.Next)) return Event.MeasurementCompleted;
|
|
}
|
|
while ( (realTest && (outPath.Scale is IScale) && !e.Contains(Event.BalanceDone)) ||
|
|
!e.Contains(Event.ReadAllRegistersDone));
|
|
|
|
return Event.Done;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Update temperature, pressure, water density and ambient values
|
|
/// including their statistics in the test results structure.
|
|
/// </summary>
|
|
/// <param name="tstRslt">Test results</param>
|
|
protected void UpdateTempPressDensAmb(Results.Entities.TestRslt tstRslt)
|
|
{
|
|
tstRslt.AmbTempMean = (float)AmbTempStat.Average;
|
|
tstRslt.AmbTempStart = (float)AmbTempStat.First;
|
|
tstRslt.AmbTempEnd = (float)AmbTempStat.Last;
|
|
tstRslt.AmbTempMin = (float)AmbTempStat.Min;
|
|
tstRslt.AmbTempMax = (float)AmbTempStat.Max;
|
|
tstRslt.AmbPressMean = (float)AmbPressStat.Average;
|
|
tstRslt.AmbPressStart = (float)AmbPressStat.First;
|
|
tstRslt.AmbPressEnd = (float)AmbPressStat.Last;
|
|
tstRslt.AmbPressMin = (float)AmbPressStat.Min;
|
|
tstRslt.AmbPressMax = (float)AmbPressStat.Max;
|
|
tstRslt.AmbHumiMean = (float)AmbHumiStat.Average;
|
|
tstRslt.AmbHumiStart = (float)AmbHumiStat.First;
|
|
tstRslt.AmbHumiEnd = (float)AmbHumiStat.Last;
|
|
tstRslt.AmbHumiMin = (float)AmbHumiStat.Min;
|
|
tstRslt.AmbHumiMax = (float)AmbHumiStat.Max;
|
|
tstRslt.PressUpMean = (float)PressUpStat.Average;
|
|
tstRslt.PressUpStart = (float)PressUpStat.First;
|
|
tstRslt.PressUpEnd = (float)PressUpStat.Last;
|
|
tstRslt.PressUpMin = (float)PressUpStat.Min;
|
|
tstRslt.PressUpMax = (float)PressUpStat.Max;
|
|
tstRslt.PressDownMean = (float)PressDownStat.Average;
|
|
tstRslt.PressDownStart = (float)PressDownStat.First;
|
|
tstRslt.PressDownEnd = (float)PressDownStat.Last;
|
|
tstRslt.PressDownMin = (float)PressDownStat.Min;
|
|
tstRslt.PressDownMax = (float)PressDownStat.Max;
|
|
tstRslt.PressDeltaMean = (float)PressDeltaStat.Average;
|
|
tstRslt.PressDeltaStart = (float)PressDeltaStat.First;
|
|
tstRslt.PressDeltaEnd = (float)PressDeltaStat.Last;
|
|
tstRslt.PressDeltaMin = (float)PressDeltaStat.Min;
|
|
tstRslt.PressDeltaMax = (float)PressDeltaStat.Max;
|
|
tstRslt.ConductMean = (float)ConductStat.Average;
|
|
tstRslt.ConductStart = (float)ConductStat.First;
|
|
tstRslt.ConductEnd = (float)ConductStat.Last;
|
|
tstRslt.ConductMin = (float)ConductStat.Min;
|
|
tstRslt.ConductMax = (float)ConductStat.Max;
|
|
tstRslt.TempUpMean = (float)TempUpStat.Average;
|
|
tstRslt.TempUpStart = (float)TempUpStat.First;
|
|
tstRslt.TempUpEnd = (float)TempUpStat.Last;
|
|
tstRslt.TempUpMin = (float)TempUpStat.Min;
|
|
tstRslt.TempUpMax = (float)TempUpStat.Max;
|
|
tstRslt.TempDownMean = (float)TempDownStat.Average;
|
|
tstRslt.TempDownStart = (float)TempDownStat.First;
|
|
tstRslt.TempDownEnd = (float)TempDownStat.Last;
|
|
tstRslt.TempDownMin = (float)TempDownStat.Min;
|
|
tstRslt.TempDownMax = (float)TempDownStat.Max;
|
|
tstRslt.TempDivMean = (float)TempDivStat.Average;
|
|
tstRslt.TempDivStart = (float)TempDivStat.First;
|
|
tstRslt.TempDivEnd = (float)TempDivStat.Last;
|
|
tstRslt.TempDivMin = (float)TempDivStat.Min;
|
|
tstRslt.TempDivMax = (float)TempDivStat.Max;
|
|
tstRslt.DensityIn = Formulas.WaterDensityFromTempPress(tstRslt.TempUpMean, tstRslt.PressUpMean);
|
|
tstRslt.DensityDiv = Formulas.WaterDensityFromTempPress(tstRslt.TempDivMean, 0);
|
|
tstRslt.DensityLine = Formulas.WaterDensityFromTempPress((tstRslt.TempUpMean + tstRslt.TempDownMean) / 2,
|
|
(tstRslt.PressUpMean + tstRslt.PressDownMean) / 2);
|
|
}
|
|
|
|
|
|
protected string TestResult2CsvLine(string testName, int part)
|
|
{
|
|
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(testName, part);
|
|
if (tstRslt == null) return string.Empty;
|
|
return TestResult2CsvLine(tstRslt);
|
|
}
|
|
|
|
|
|
protected string TestResult2CsvLine(Results.Entities.TestRslt tstRslt)
|
|
{
|
|
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
|
|
|
try
|
|
{
|
|
bool isPMaxTest = tstRslt.IsPMaxTest();
|
|
bool isStartStop = tstRslt.IsStartStop();
|
|
bool isDiverter = tstRslt.IsDiverter();
|
|
bool isVolumeMethod = tstRslt.IsVolumeMethod();
|
|
|
|
sb.Append(tstRslt.StartTime); /// A
|
|
sb.Append(";"); sb.Append(tstRslt.Batch.BatchNr); /// B
|
|
|
|
/// Test information, target values, etc.
|
|
sb.Append(";"); sb.Append(tstRslt.Name()); /// C
|
|
sb.Append(";"); sb.Append(tstRslt.Repeats()); /// D
|
|
sb.Append(";"); sb.Append(tstRslt.RepetitionNr); /// E
|
|
sb.Append(";"); sb.Append(tstRslt.Method()); /// F
|
|
sb.Append(";"); sb.Append(tstRslt.TargetVolume()); /// G
|
|
sb.Append(";"); sb.Append(tstRslt.Qfrom()); /// H
|
|
sb.Append(";"); sb.Append(tstRslt.Qto()); /// I
|
|
sb.Append(";"); sb.Append(tstRslt.ErrLimLo() + tstRslt.ErrLimMargin()); /// J
|
|
sb.Append(";"); sb.Append(tstRslt.ErrLimHi() - tstRslt.ErrLimMargin()); /// K
|
|
sb.Append(";"); sb.AppendFormat("{0:F1}", tstRslt.TempLimLo()); /// L
|
|
sb.Append(";"); sb.AppendFormat("{0:F1}", tstRslt.TempLimHi()); /// M
|
|
sb.Append(";"); sb.Append("0"); /// N
|
|
sb.Append(";"); sb.Append("16"); /// O
|
|
sb.Append(";"); sb.Append(tstRslt.RefFlowmeter()); /// P
|
|
sb.Append(";"); sb.AppendFormat("{0:F4}", Formulas.DistilledWaterDensityFromTemp(tstRslt.AmbTempMean)); /// Q [kg/m3] hustota vody pri teplote okolia z priemernej teploty okolia bez korekcie na realnu hustotu vody
|
|
sb.Append(";"); sb.Append((tstRslt.Components != null) ? tstRslt.Components.Scale : string.Empty); /// R
|
|
|
|
/// Ambient
|
|
sb.Append(";"); sb.AppendFormat("{0:F1}", Units.ConvertTo(Unit.C, tstRslt.AmbTempStart)); /// S [°C]
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", Units.ConvertTo(Unit.mbar, tstRslt.AmbPressStart)); /// T [mbar]
|
|
sb.Append(";"); sb.AppendFormat("{0:F1}", Units.ConvertTo(Unit.RPct, tstRslt.AmbHumiStart)); /// U [R%]
|
|
|
|
/// Pressure
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", Units.ConvertTo(Unit.kPa, tstRslt.PressUpMean)); /// V [kPa]
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", Units.ConvertTo(Unit.kPa, tstRslt.PressDownMean)); /// W [kPa]
|
|
sb.Append(";"); sb.AppendFormat("{0:F1}", Units.ConvertTo(Unit.kPa, tstRslt.PressDeltaMean)); /// X [kPa]
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", Units.ConvertTo(Unit.kPa, tstRslt.PressUpStart)); /// Y [kPa]
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", Units.ConvertTo(Unit.kPa, tstRslt.PressDownStart)); /// Z [kPa]
|
|
sb.Append(";"); sb.AppendFormat("{0:F1}", Units.ConvertTo(Unit.kPa, tstRslt.PressDeltaStart)); /// AA [kPa]
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", Units.ConvertTo(Unit.kPa, tstRslt.PressUpEnd)); /// AB [kPa]
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", Units.ConvertTo(Unit.kPa, tstRslt.PressDownEnd)); /// AC [kPa]
|
|
sb.Append(";"); sb.AppendFormat("{0:F1}", Units.ConvertTo(Unit.kPa, tstRslt.PressDeltaEnd)); /// AD [kPa]
|
|
|
|
/// Temperature
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.TempUpMean)); /// AE [°C]
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.TempDownMean)); /// AF [°C]
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.TempDivMean)); /// AG [°C]
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.Custom1)); /// AH [°C] T hi mean
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.Custom6)); /// AI [°C] T lo mean
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.TempUpStart)); /// AJ [°C]
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.TempDownStart)); /// AK [°C]
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.TempDivStart)); /// AL [°C]
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.Custom2)); /// AM [°C] T hi start
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.Custom7)); /// AN [°C] T lo start
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.TempUpEnd)); /// AO [°C]
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.TempDownEnd)); /// AP [°C]
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.TempDivEnd)); /// AQ [°C]
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.Custom3)); /// AR [°C] T hi end
|
|
sb.Append(";"); sb.Append(Units.ConvertTo(Unit.C, tstRslt.Custom8)); /// AS [°C] T lo end
|
|
|
|
/// Mass
|
|
sb.Append(";"); sb.Append(tstRslt.MassStartRaw); /// AT [kg]
|
|
sb.Append(";"); sb.Append(tstRslt.MassStart); /// AU [kg]
|
|
sb.Append(";"); sb.Append(tstRslt.MassEndRaw); /// AV [kg]
|
|
sb.Append(";"); sb.Append(tstRslt.MassEnd); /// AW [kg]
|
|
sb.Append(";"); sb.Append(tstRslt.MassEnd - tstRslt.MassStart); /// AX [kg]
|
|
|
|
/// Density and buoyancy
|
|
sb.Append(";"); sb.Append(tstRslt.DensityDiv); /// AY [kg/m3]
|
|
sb.Append(";"); sb.Append((tstRslt.TempUpMean + tstRslt.TempDownMean) / 2); /// AZ [°C] Tline ... priemerna teplota v linii
|
|
sb.Append(";"); sb.Append(tstRslt.DensityLine); /// BA [kg/m3]
|
|
sb.Append(";"); sb.Append(tstRslt.MassOfEvapWater); /// BB [kg] mass of evaporated water
|
|
sb.Append(";"); sb.Append(tstRslt.Batch.Buoyancy); /// BC Buoyancy: Sheet1 - X9
|
|
|
|
sb.Append(";"); sb.Append(tstRslt.Batch.RealDensity); /// BD
|
|
sb.Append(";"); sb.Append(tstRslt.Batch.AtTemperature); /// BE
|
|
sb.Append(";"); sb.Append(tstRslt.FlowMax); /// BF pipe expansion: teraz vynechat
|
|
sb.Append(";"); sb.Append(tstRslt.FlowMin); /// BG [kg/h] Qm
|
|
sb.Append(";"); sb.Append(tstRslt.FlowVolume); /// BH [l/h] Qv
|
|
sb.Append(";"); sb.Append(tstRslt.VolumeCTV); /// BI [l] Vet .... komercne prava hodnota objemu - podla vahy
|
|
sb.Append(";"); sb.Append(tstRslt.VolumeMaster); /// BJ [l] Velm ... objem podla etalonu (Prolonged: objem do vahy podla impulzov hradlovanych klapkou)
|
|
sb.Append(";"); sb.Append(tstRslt.TestTimeCorrection); /// BK [s] test time correction (diverter correction)
|
|
/// (ori.) BK [l] Vmass .. objem podla druheho etalonu / prietokomeru pred tratou (teraz vynechavame)
|
|
sb.Append(";"); sb.Append(tstRslt.TestTime); /// BL [s]
|
|
|
|
sb.Append(";"); sb.Append(isVolumeMethod ? Config.Formulas.ErrorFromVolumes(tstRslt.ConstMasterCorr, tstRslt.ConstMasterRaw) : tstRslt.ErrorMaster);
|
|
/// BM [%] Eelm .... chyba etalonu voci komercne pravej hodnote
|
|
sb.Append(";"); sb.Append(" "); /// BN [%] Emass ... chyba druheho etalonu voci komercne pravej hodnote (teraz vynechavame)
|
|
sb.Append(";"); sb.Append((tstRslt.ConstMasterRaw != 0) ? (1 / tstRslt.ConstMasterRaw) : 0); /// BO [pls/l] Const.MID .. konstanta etalonu
|
|
sb.Append(";"); sb.Append(" "); /// BP [pls/l] Const.MA ... konstanta druheho etalonu
|
|
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", isDiverter ? 1000.0F * tstRslt.DiverterStart : 0); /// BQ [ms] Diverter start time
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", isDiverter ? 1000.0F * tstRslt.DiverterEnd : 0); /// BR [ms] Diverter end time
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", isStartStop ? 1000.0F * tstRslt.DiverterStart : 0); /// BS [ms] Start valve open time
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", isStartStop ? 1000.0F * tstRslt.DiverterEnd : 0); /// BT [ms] Start valve close time
|
|
sb.Append(";"); sb.Append(tstRslt.TempUpMax); /// BU [°C]
|
|
sb.Append(";"); sb.Append(tstRslt.TempDownMax); /// BV [°C]
|
|
sb.Append(";"); sb.Append(tstRslt.TempUpMin); /// BW [°C]
|
|
sb.Append(";"); sb.Append(tstRslt.TempDownMin); /// BX [°C]
|
|
sb.Append(";"); sb.Append(isPMaxTest ? tstRslt.TestTime : 0); /// BY [s] Duration of the pressure test
|
|
sb.Append(";"); sb.AppendFormat("{0:F1}", Units.ConvertTo(Unit.C, tstRslt.AmbTempEnd)); /// BZ [°C]
|
|
sb.Append(";"); sb.AppendFormat("{0:F0}", Units.ConvertTo(Unit.mbar, tstRslt.AmbPressEnd)); /// CA [mbar]
|
|
sb.Append(";"); sb.AppendFormat("{0:F1}", Units.ConvertTo(Unit.RPct, tstRslt.AmbHumiEnd)); /// CB [R%]
|
|
|
|
sb.Append(";"); sb.Append(tstRslt.PulsesMaster); /// CC Celkovy pocet et. pulzov skusky (Prolonged : do vahy)
|
|
//sb.Append(";"); sb.Append((tstRslt.TotalPulsesMstr != 0) ? tstRslt.TotalPulsesMstr.ToString() : " "); /// CD - '' - pre druhy (Prolonged : celkovy pocet)
|
|
sb.Append(";"); sb.Append(1000 * tstRslt.TestTimeCorrection); /// CD [ms] Diverter test time correction
|
|
|
|
for (int i = 0; i < ProcessData.BatchRslts.WMPositionsCount; i++)
|
|
{
|
|
if (ProcessData.BatchRslts.Batch.WaterMeters != null &&
|
|
ProcessData.BatchRslts.Batch.WaterMeters.Count > i &&
|
|
ProcessData.BatchRslts.Batch.WaterMeters[i] != null &&
|
|
!ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled)
|
|
{
|
|
if (!ProcessData.BatchRslts.Batch.WaterMeters[i].Compound() && !ProcessData.BatchRslts.Batch.WaterMeters[i].HeatMeter())
|
|
{
|
|
/// If this is a single meter
|
|
|
|
Results.Entities.MeterTestRslt mtrRslt = ProcessData.BatchRslts.GetMeterTestRslt(tstRslt.Name(), i, CompoundMeterId.Single);
|
|
|
|
if (mtrRslt != null)
|
|
{
|
|
bool isCamera = (mtrRslt.RegReaderType == (int)RegisterReaderType.Camera);
|
|
|
|
sb.Append(";"); sb.Append(ProcessData.BatchRslts.Batch.WaterMeters[i].SerialNr);/// CE WM Ser.No.
|
|
sb.Append(";"); sb.Append(mtrRslt.VolumeStart); /// CF WM Vstart - pociatocny stav pri pevnom starte alebo zachyteny pri data streame
|
|
sb.Append(";"); sb.Append(mtrRslt.VolumeEnd); /// CG WM Vend - konecny stav pri pevnom starte alebo zachyteny pri data streame
|
|
sb.Append(";"); sb.Append(mtrRslt.VolumeMeter); /// CH WM Vmer - objem namerany vodomerom
|
|
sb.Append(";"); sb.Append(mtrRslt.VolumeRef); /// CI WM Vref - objem namerany stanicou
|
|
sb.Append(";"); sb.Append(mtrRslt.Error); /// CJ WM Emt - chyba vodomerom nameraneho objemu
|
|
#if IPERL
|
|
sb.Append(";"); sb.Append(ProcessData.BatchRslts.Batch.WaterMeters[i].CalibFactor); /// CK iPerl calibration factor used during the test / ...
|
|
#else
|
|
sb.Append(";"); sb.Append(" "); /// CK nechat prazdne
|
|
#endif
|
|
sb.Append(";"); sb.Append(mtrRslt.PulsesMeter); /// CL WM Np met - pocet impulzov zo skusaneho meradla
|
|
sb.Append(";"); sb.Append(mtrRslt.PulsesMaster); /// CM WM Np elm - pocet impulzov etalonu pocas merania pre prislusny vodomer
|
|
sb.Append(";"); sb.Append(mtrRslt.TestTime); /// CN WM Tmet - cas merania (obmedzany pri synchro skuske)
|
|
sb.Append(";"); sb.Append(mtrRslt.Passed ? "OK" : "NOK"); /// CO WM Vysledok (t.j. ci je v hraniciach chyb) - OK/NOK
|
|
#if IPERL
|
|
sb.Append(";"); sb.Append(mtrRslt.WaterMeter.Q2CorrRL); /// CP iPerl Q2 correction factor used during the test / AN value - hodnota z analogoveho prevodnika
|
|
#else
|
|
sb.Append(";"); sb.Append(mtrRslt.PulsesPerLiter); /// CP Pulses per liter
|
|
#endif
|
|
sb.Append(";"); sb.Append(isCamera
|
|
? mtrRslt.VolumeStart * mtrRslt.PulsesPerLiter /// CQ WM Phi_start (pri hodnotach z kamery)
|
|
: ProcessData.BatchRslts.Batch.WaterMeters[i].WMPosition); /// CQ WMPosition (normalne)
|
|
sb.Append(";"); sb.Append(isCamera
|
|
? mtrRslt.VolumeEnd * mtrRslt.PulsesPerLiter /// CR WM Phi_end (pri hodnotach z kamery)
|
|
: 0); /// CR not used/spare (normalne)
|
|
|
|
sb.Append(";"); sb.Append(mtrRslt.TimestampStart); /// CS WM Time_start - ' ' -
|
|
sb.Append(";"); sb.Append(mtrRslt.TimestampEnd); /// CT WM Time_end - ' ' -
|
|
|
|
sb.Append(";"); sb.Append(isCamera ? mtrRslt.PulsesPerLiter : 0); /// CU WM Degree per liter
|
|
|
|
sb.Append(";"); sb.Append(0); /// CV Analog out 1 (max mA)
|
|
sb.Append(";"); sb.Append(0); /// CW Analog out 2 (V)
|
|
sb.Append(";"); sb.Append(0); /// CX Analog out 3 (min mA)
|
|
sb.Append(";"); sb.Append(0); /// CY Analog out 4 (max Q)
|
|
}
|
|
}
|
|
else if (ProcessData.BatchRslts.Batch.WaterMeters[i].Compound())
|
|
{
|
|
/// Else if this is a compound meter
|
|
|
|
for (byte b = (byte)CompoundMeterId.CompoundMain; b <= (byte)CompoundMeterId.Compound; b++)
|
|
{
|
|
Results.Entities.MeterTestRslt mtrRslt = ProcessData.BatchRslts.GetMeterTestRslt(tstRslt.Name(), i, (CompoundMeterId)b);
|
|
|
|
if (mtrRslt != null)
|
|
{
|
|
sb.Append(";");
|
|
switch ((CompoundMeterId)b)
|
|
{
|
|
case CompoundMeterId.CompoundMain:
|
|
sb.Append(ProcessData.BatchRslts.Batch.WaterMeters[i].SerialNr); /// CE
|
|
break;
|
|
case CompoundMeterId.CompoundAux:
|
|
sb.Append(ProcessData.BatchRslts.Batch.WaterMeters[i].SerialNrAux); /// CE
|
|
break;
|
|
case CompoundMeterId.Compound:
|
|
sb.Append(ProcessData.BatchRslts.Batch.WaterMeters[i].SerialNr); /// CE
|
|
break;
|
|
}
|
|
sb.Append(";"); sb.Append(mtrRslt.VolumeStart); /// CF WM Vinit - pri pevnom starte pociatocny stav natukany alebo cez inteligentny system
|
|
sb.Append(";"); sb.Append(mtrRslt.VolumeEnd); /// CG WM Vfin - pri pevnom starte konecny stav natukany alebo cez inteligentny system
|
|
sb.Append(";"); sb.Append(mtrRslt.VolumeMeter); /// CH WM Vmer - objem namerany vodomerom
|
|
sb.Append(";"); sb.Append(mtrRslt.VolumeRef); /// CI WM Vet - objem namerany stanicou
|
|
sb.Append(";"); sb.Append(mtrRslt.Error); /// CJ WM Emt - chyba vodomerom nameraneho objemu
|
|
sb.Append(";"); sb.Append(" "); /// CK WM U - neistota (zatial nechat prazdne)
|
|
sb.Append(";"); sb.Append(mtrRslt.PulsesMeter); /// CL WM Np met - pocet impulzov zo skusaneho meradla
|
|
sb.Append(";"); sb.Append(mtrRslt.PulsesMaster); /// CM WM Np elm - pocet impulzov etalonu pocas merania pre prislusny vodomer
|
|
sb.Append(";"); sb.Append(mtrRslt.TestTime); /// CN WM Tmet - cas merania (obmedzany pri synchro skuske)
|
|
sb.Append(";"); sb.Append(mtrRslt.Passed ? "OK" : "NOK"); /// CO WM Vysledok (t.j. ci je v hraniciach chyb) - OK/NOK
|
|
sb.Append(";"); sb.Append(" "); /// CP WM AN value - hodnota z analogoveho prevodnika (teraz nic)
|
|
|
|
bool isCamera = mtrRslt.IsCamera();
|
|
sb.Append(";"); sb.Append(isCamera ? mtrRslt.VolumeStart * mtrRslt.PulsesPerLiter : 0); /// CQ WM Phi_start - pri hodnotach z kamery
|
|
sb.Append(";"); sb.Append(isCamera ? mtrRslt.VolumeEnd * mtrRslt.PulsesPerLiter : 0); /// CR WM Phi_end - ' ' -
|
|
sb.Append(";"); sb.Append(isCamera ? mtrRslt.TimestampStart : 0); /// CS WM Time_start - ' ' -
|
|
sb.Append(";"); sb.Append(isCamera ? mtrRslt.TimestampEnd : 0); /// CT WM Time_end - ' ' -
|
|
sb.Append(";"); sb.Append(isCamera ? mtrRslt.PulsesPerLiter : 0); /// CU WM Degree per liter
|
|
|
|
sb.Append(";"); sb.Append(0); /// CV Analog out 1 (max mA)
|
|
sb.Append(";"); sb.Append(0); /// CW Analog out 2 (V)
|
|
sb.Append(";"); sb.Append(0); /// CX Analog out 3 (min mA)
|
|
sb.Append(";"); sb.Append(0); /// CY Analog out 4 (max Q)
|
|
}
|
|
}
|
|
}
|
|
else /// if (ProcessData.BatchRslts.WaterMeters[i].HeatMeter())
|
|
{
|
|
/// Else this is a heat meter
|
|
|
|
Results.Entities.MeterTestRslt volumeMtr = ProcessData.BatchRslts.GetMeterTestRslt(tstRslt.Name(), i, CompoundMeterId.HeatMeterVolume);
|
|
Results.Entities.MeterTestRslt energyMtr = ProcessData.BatchRslts.GetMeterTestRslt(tstRslt.Name(), i, CompoundMeterId.HeatMeterEnergy);
|
|
|
|
if (volumeMtr != null)
|
|
{
|
|
sb.Append(";"); sb.Append(ProcessData.BatchRslts.Batch.WaterMeters[i].SerialNr); /// WM Ser.No.
|
|
sb.Append(";"); sb.Append(volumeMtr.VolumeStart); /// WM Vstart - pociatocny stav pri pevnom starte alebo zachyteny pri data streame
|
|
sb.Append(";"); sb.Append(volumeMtr.VolumeEnd); /// WM Vend - konecny stav pri pevnom starte alebo zachyteny pri data streame
|
|
sb.Append(";"); sb.Append(volumeMtr.VolumeMeter); /// WM Vmer - objem namerany vodomerom
|
|
sb.Append(";"); sb.Append(volumeMtr.VolumeRef); /// WM Vref - objem namerany stanicou
|
|
sb.Append(";"); sb.Append(volumeMtr.Error); /// WM Emt - chyba vodomerom nameraneho objemu
|
|
#if IPERL
|
|
sb.Append(";"); sb.Append(ProcessData.BatchRslts.Batch.WaterMeters[i].CalibFactor); /// iPerl calibration factor used during the test / ...
|
|
#else
|
|
sb.Append(";"); sb.Append(" "); /// nechat prazdne
|
|
#endif
|
|
sb.Append(";"); sb.Append(volumeMtr.PulsesMeter); /// WM Np met - pocet impulzov zo skusaneho meradla
|
|
sb.Append(";"); sb.Append(volumeMtr.PulsesMaster); /// WM Np elm - pocet impulzov etalonu pocas merania pre prislusny vodomer
|
|
sb.Append(";"); sb.Append(volumeMtr.TestTime); /// WM Tmet - cas merania (obmedzany pri synchro skuske)
|
|
sb.Append(";"); sb.Append(volumeMtr.Passed ? "OK" : "NOK"); /// WM Vysledok (t.j. ci je v hraniciach chyb) - OK/NOK
|
|
#if IPERL
|
|
sb.Append(";"); sb.Append(volumeMtr.WaterMeter.Q2CorrRL); /// iPerl Q2 correction factor used during the test / AN value - hodnota z analogoveho prevodnika
|
|
#else
|
|
sb.Append(";"); sb.Append(" "); /// nechat prazdne
|
|
#endif
|
|
sb.Append(";"); sb.Append(volumeMtr.VolumeStart); /// WM Volume_start - pri datastreamovych hodnotach (alebo kamera)
|
|
sb.Append(";"); sb.Append(volumeMtr.TimestampStart); /// WM Time_start - ' ' -
|
|
sb.Append(";"); sb.Append(volumeMtr.VolumeEnd); /// WM Volume_end - ' ' -
|
|
sb.Append(";"); sb.Append(volumeMtr.TimestampEnd); /// WM Time_end - ' ' -
|
|
}
|
|
|
|
if (energyMtr != null)
|
|
{
|
|
sb.Append(";"); sb.Append(ProcessData.BatchRslts.Batch.WaterMeters[i].SerialNr); /// WM Ser.No.
|
|
sb.Append(";"); sb.Append(energyMtr.VolumeStart); /// WM Vstart - pociatocny stav pri pevnom starte alebo zachyteny pri data streame
|
|
sb.Append(";"); sb.Append(energyMtr.VolumeEnd); /// WM Vend - konecny stav pri pevnom starte alebo zachyteny pri data streame
|
|
sb.Append(";"); sb.Append(energyMtr.VolumeMeter); /// WM Vmer - objem namerany vodomerom
|
|
sb.Append(";"); sb.Append(energyMtr.VolumeRef); /// WM Vref - objem namerany stanicou
|
|
sb.Append(";"); sb.Append(energyMtr.Error); /// WM Emt - chyba vodomerom nameraneho objemu
|
|
#if IPERL
|
|
sb.Append(";"); sb.Append(ProcessData.BatchRslts.Batch.WaterMeters[i].CalibFactor); /// iPerl calibration factor used during the test / ...
|
|
#else
|
|
sb.Append(";"); sb.Append(" "); /// nechat prazdne
|
|
#endif
|
|
sb.Append(";"); sb.Append(energyMtr.PulsesMeter); /// WM Np met - pocet impulzov zo skusaneho meradla
|
|
sb.Append(";"); sb.Append(energyMtr.PulsesMaster); /// WM Np elm - pocet impulzov etalonu pocas merania pre prislusny vodomer
|
|
sb.Append(";"); sb.Append(energyMtr.TestTime); /// WM Tmet - cas merania (obmedzany pri synchro skuske)
|
|
sb.Append(";"); sb.Append(energyMtr.Passed ? "OK" : "NOK"); /// WM Vysledok (t.j. ci je v hraniciach chyb) - OK/NOK
|
|
#if IPERL
|
|
sb.Append(";"); sb.Append(energyMtr.WaterMeter.Q2CorrRL); /// iPerl Q2 correction factor used during the test / AN value - hodnota z analogoveho prevodnika
|
|
#else
|
|
sb.Append(";"); sb.Append(" "); /// nechat prazdne
|
|
#endif
|
|
sb.Append(";"); sb.Append(energyMtr.VolumeStart); /// WM Volume_start - pri datastreamovych hodnotach (alebo kamera)
|
|
sb.Append(";"); sb.Append(energyMtr.TimestampStart); /// WM Time_start - ' ' -
|
|
sb.Append(";"); sb.Append(energyMtr.VolumeEnd); /// WM Volume_end - ' ' -
|
|
sb.Append(";"); sb.Append(energyMtr.TimestampEnd); /// WM Time_end - ' ' -
|
|
}
|
|
}
|
|
}
|
|
}
|
|
sb.Append(";");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
log.ErrorFormat("Preparinging SummaryResults B{0}/{1} failed: {2}", tstRslt.Batch.BatchNr, tstRslt.Name(), exc.Message);
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Create a simulated test result (single meter).
|
|
/// </summary>
|
|
/// <param name="test">Test to be simulated</param>
|
|
/// <returns>Test result</returns>
|
|
public void MakeSimulatedTrivial(Config.Entities.Test test, int repetitionNr, int part)
|
|
{
|
|
string fullTestName = Common.Utils.GetTestName(test.Name, test.Repeats, repetitionNr);
|
|
|
|
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(fullTestName, part);
|
|
Results.Utils.GetCounterStates(tstRslt, Program.LocalSettings.Counters);
|
|
|
|
if (tstRslt == null) return; /// Prevent program crash in certain cases
|
|
|
|
tstRslt.AmbTempMean = 20.0f;
|
|
tstRslt.AmbPressMean = 1.0f;
|
|
tstRslt.AmbHumiMean = 50.0f;
|
|
tstRslt.PressUpStart = 1.0f;
|
|
tstRslt.PressDownStart = 1.0f;
|
|
tstRslt.TempUpStart = 20.0f;
|
|
tstRslt.TempDownStart = 20.0f;
|
|
tstRslt.TempDivStart = 20.0f;
|
|
tstRslt.PressUpEnd = 1.0f;
|
|
tstRslt.PressDownEnd = 1.0f;
|
|
tstRslt.TempUpEnd = 20.0f;
|
|
tstRslt.TempDownEnd = 20.0f;
|
|
tstRslt.TempDivEnd = 20.0f;
|
|
tstRslt.PressUpMean = 1.0f;
|
|
tstRslt.PressDownMean = 1.0f;
|
|
tstRslt.TempUpMean = 20.0f;
|
|
tstRslt.TempDownMean = 20.0f;
|
|
tstRslt.TempDivMean = 20.0f;
|
|
tstRslt.PressUpMin = 1.0f;
|
|
tstRslt.PressDownMin = 1.0f;
|
|
tstRslt.TempUpMin = 20.0f;
|
|
tstRslt.TempDownMin = 20.0f;
|
|
tstRslt.TempDivMin = 20.0f;
|
|
tstRslt.PressUpMax = 1.0f;
|
|
tstRslt.PressDownMax = 1.0f;
|
|
tstRslt.TempUpMax = 20.0f;
|
|
tstRslt.TempDownMax = 20.0f;
|
|
tstRslt.TempDivMax = 20.0f;
|
|
tstRslt.ConductMin = Conductivity.Val;
|
|
tstRslt.ConductMax = Conductivity.Val;
|
|
|
|
tstRslt.DensityIn = Config.Formulas.RealDensity();
|
|
tstRslt.DensityLine = Config.Formulas.RealDensity();
|
|
tstRslt.DensityDiv = Config.Formulas.RealDensity();
|
|
|
|
tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName;
|
|
tstRslt.StartTime = DateTime.Now;
|
|
tstRslt.EndTime = DateTime.Now + new TimeSpan(0, 0, 1);
|
|
tstRslt.FlowSetTime = 10;
|
|
tstRslt.TestTime = tstRslt.TargetTime();
|
|
if (outPath != null)
|
|
{
|
|
tstRslt.PulsesMaster = (outPath.FlowMeter.LtrPerPulse > 1E-6) ? (1.0075 * tstRslt.TargetVolume() / outPath.FlowMeter.LtrPerPulse) : 1;
|
|
tstRslt.MassStartRaw = 0;
|
|
tstRslt.MassStart = Config.Entities.MeasurementCorrection.CorrectedValue(tstRslt.MassStartRaw, outPath.Scale.Corrections);
|
|
tstRslt.MassEndRaw = tstRslt.TargetVolume() * Config.Formulas.RealDensity() / 1000.0f;
|
|
tstRslt.MassEnd = Config.Entities.MeasurementCorrection.CorrectedValue(tstRslt.MassEndRaw, outPath.Scale.Corrections);
|
|
tstRslt.FlowMass = 3600.0 * (tstRslt.MassEnd - tstRslt.MassStart) / tstRslt.TestTime;
|
|
tstRslt.FlowVolume = 3.6 * outPath.FlowMeter.LtrPerPulse * tstRslt.PulsesMaster / tstRslt.TestTime;
|
|
tstRslt.MassOfEvapWater = 0;
|
|
tstRslt.VolumeCTV = 1000 * tstRslt.Batch.Buoyancy * (tstRslt.MassEnd - tstRslt.MassStart) / tstRslt.DensityLine; /// [l] commercially true volume
|
|
tstRslt.VolumeMaster = outPath.FlowMeter.LtrPerPulse * tstRslt.PulsesMaster; /// [l] volume from the master flow meter
|
|
tstRslt.ConstMasterRaw = outPath.FlowMeter.LtrPerPulse; /// Uncorrected master flowmeter coefficient
|
|
tstRslt.ConstMasterCorr = outPath.FlowMeter.LtrPerPulseCorrected(tstRslt.FlowVolume, 0); /// Corrected master pulses per liter
|
|
tstRslt.ConstMaster = (tstRslt.VolumeMaster == 0) ? tstRslt.ConstMasterCorr : (outPath.FlowMeter.LtrPerPulse * tstRslt.VolumeCTV / tstRslt.VolumeMaster);
|
|
}
|
|
tstRslt.ErrorMaster = Config.Formulas.ErrorFromVolumes(tstRslt.VolumeMaster, tstRslt.VolumeCTV);
|
|
|
|
tstRslt.FlowMean = (float)RefFlowStat.Average;
|
|
tstRslt.FlowStart = (float)RefFlowStat.First;
|
|
tstRslt.FlowEnd = (float)RefFlowStat.Last;
|
|
tstRslt.FlowMin = (float)RefFlowStat.Min;
|
|
tstRslt.FlowMax = (float)RefFlowStat.Max;
|
|
|
|
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
|
|
{
|
|
double errorPct = Convert.ToDouble((i % 10) - 5) / 2.0;
|
|
|
|
Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(fullTestName, i, CompoundMeterId.Single);
|
|
IRegReader regReader = sensPath.RegisterReaders[i];
|
|
|
|
if (meterRslt != null && regReader != null)
|
|
{
|
|
meterRslt.VolumeMeter = tstRslt.TargetVolume() * (1.0 + 0.01 * errorPct);
|
|
|
|
meterRslt.PulsesMeter = regReader.PulsesPerLtr * meterRslt.VolumeMeter;
|
|
meterRslt.PulsesMaster = tstRslt.PulsesMaster;
|
|
meterRslt.PulsesPerLiter = regReader.PulsesPerLtr;
|
|
meterRslt.VolumeStart = 0;
|
|
meterRslt.VolumeEnd = meterRslt.VolumeMeter;
|
|
meterRslt.VolumeRef = tstRslt.TargetVolume();
|
|
meterRslt.TimestampStart = 0;
|
|
meterRslt.TimestampEnd = tstRslt.TargetTime();
|
|
meterRslt.TestTime = tstRslt.TargetTime();
|
|
meterRslt.Error = errorPct;
|
|
meterRslt.Passed = errorPct >= test.ErrLimLo + test.Uncertainty && errorPct <= test.ErrLimHi - test.Uncertainty;
|
|
meterRslt.TestDone = true;
|
|
tstRslt.TestDone = true;
|
|
}
|
|
}
|
|
|
|
tstRslt.Components = Results.Entities.Components
|
|
.UpdateList(BatchRslts.ComponentsList,
|
|
new Results.Entities.Components((BenchInfo != null) ? BenchInfo.TestBenchId : 1,
|
|
(BenchInfo != null) ? BenchInfo.TestBenchName : "testbench",
|
|
(inPath != null && inPath.Pump != null) ? inPath.Pump.Name : string.Empty,
|
|
(outPath != null && outPath.FlowMeter != null) ? outPath.FlowMeter.Name : string.Empty,
|
|
(outPath != null && outPath.Scale != null) ? outPath.Scale.Name : string.Empty,
|
|
(outPath != null && outPath.RegulValve != null) ? outPath.RegulValve.Name : string.Empty,
|
|
(outPath != null && outPath.Diverter != null) ? outPath.Diverter.Name : string.Empty));
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Create a simulated test result (single meter).
|
|
/// </summary>
|
|
/// <param name="test">Test to be simulated</param>
|
|
/// <returns>Test result</returns>
|
|
public void MakeSimulated(Config.Entities.Test test, int repetitionNr, int part, float errorPctBase)
|
|
{
|
|
string fullTestName = Common.Utils.GetTestName(test.Name, test.Repeats, repetitionNr);
|
|
|
|
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(fullTestName, part);
|
|
Results.Utils.GetCounterStates(tstRslt, Program.LocalSettings.Counters);
|
|
|
|
if (tstRslt == null) return; /// Prevent program crash in certain cases
|
|
|
|
tstRslt.AmbTempMean = 20.0f;
|
|
tstRslt.AmbPressMean = 1.0f;
|
|
tstRslt.AmbHumiMean = 50.0f;
|
|
tstRslt.PressUpStart = 1.0f;
|
|
tstRslt.PressDownStart = 1.0f;
|
|
tstRslt.TempUpStart = 20.0f;
|
|
tstRslt.TempDownStart = 20.0f;
|
|
tstRslt.TempDivStart = 20.0f;
|
|
tstRslt.PressUpEnd = 1.0f;
|
|
tstRslt.PressDownEnd = 1.0f;
|
|
tstRslt.TempUpEnd = 20.0f;
|
|
tstRslt.TempDownEnd = 20.0f;
|
|
tstRslt.TempDivEnd = 20.0f;
|
|
tstRslt.PressUpMean = 1.0f;
|
|
tstRslt.PressDownMean = 1.0f;
|
|
tstRslt.TempUpMean = 20.0f;
|
|
tstRslt.TempDownMean = 20.0f;
|
|
tstRslt.TempDivMean = 20.0f;
|
|
tstRslt.PressUpMin = 1.0f;
|
|
tstRslt.PressDownMin = 1.0f;
|
|
tstRslt.TempUpMin = 20.0f;
|
|
tstRslt.TempDownMin = 20.0f;
|
|
tstRslt.TempDivMin = 20.0f;
|
|
tstRslt.PressUpMax = 1.0f;
|
|
tstRslt.PressDownMax = 1.0f;
|
|
tstRslt.TempUpMax = 20.0f;
|
|
tstRslt.TempDownMax = 20.0f;
|
|
tstRslt.TempDivMax = 20.0f;
|
|
tstRslt.ConductMin = Conductivity.Val;
|
|
tstRslt.ConductMax = Conductivity.Val;
|
|
|
|
tstRslt.DensityIn = Config.Formulas.RealDensity();
|
|
tstRslt.DensityLine = Config.Formulas.RealDensity();
|
|
tstRslt.DensityDiv = Config.Formulas.RealDensity();
|
|
|
|
tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName;
|
|
tstRslt.StartTime = DateTime.Now;
|
|
tstRslt.EndTime = DateTime.Now + new TimeSpan(0,0,1);
|
|
tstRslt.FlowSetTime = 10;
|
|
tstRslt.TestTime = tstRslt.TargetTime();
|
|
tstRslt.PulsesMaster = (outPath.FlowMeter.LtrPerPulse > 1E-6) ? (1.0075 * tstRslt.TargetVolume() / outPath.FlowMeter.LtrPerPulse) : 1;
|
|
tstRslt.MassStartRaw = 0;
|
|
tstRslt.MassStart = Config.Entities.MeasurementCorrection.CorrectedValue(tstRslt.MassStartRaw, outPath.Scale.Corrections);
|
|
tstRslt.MassEndRaw = tstRslt.TargetVolume() * Config.Formulas.RealDensity() / 1000.0f;
|
|
tstRslt.MassEnd = Config.Entities.MeasurementCorrection.CorrectedValue(tstRslt.MassEndRaw, outPath.Scale.Corrections);
|
|
tstRslt.FlowMass = 3600.0 * (tstRslt.MassEnd - tstRslt.MassStart) / tstRslt.TestTime;
|
|
tstRslt.FlowVolume = 3.6 * outPath.FlowMeter.LtrPerPulse * tstRslt.PulsesMaster / tstRslt.TestTime;
|
|
tstRslt.MassOfEvapWater = 0;
|
|
tstRslt.VolumeCTV = 1000 * tstRslt.Batch.Buoyancy * (tstRslt.MassEnd - tstRslt.MassStart) / tstRslt.DensityLine; /// [l] commercially true volume
|
|
tstRslt.VolumeMaster = outPath.FlowMeter.LtrPerPulse * tstRslt.PulsesMaster; /// [l] volume from the master flow meter
|
|
tstRslt.ConstMasterRaw = outPath.FlowMeter.LtrPerPulse; /// Uncorrected master flowmeter coefficient
|
|
tstRslt.ConstMasterCorr = outPath.FlowMeter.LtrPerPulseCorrected(tstRslt.FlowVolume, 0); /// Corrected master pulses per liter
|
|
tstRslt.ConstMaster = (tstRslt.VolumeMaster == 0) ? tstRslt.ConstMasterCorr : (outPath.FlowMeter.LtrPerPulse * tstRslt.VolumeCTV / tstRslt.VolumeMaster);
|
|
|
|
tstRslt.ErrorMaster = Config.Formulas.ErrorFromVolumes(tstRslt.VolumeMaster, tstRslt.VolumeCTV);
|
|
|
|
tstRslt.FlowMean = (float)RefFlowStat.Average;
|
|
tstRslt.FlowStart = (float)RefFlowStat.First;
|
|
tstRslt.FlowEnd = (float)RefFlowStat.Last;
|
|
tstRslt.FlowMin = (float)RefFlowStat.Min;
|
|
tstRslt.FlowMax = (float)RefFlowStat.Max;
|
|
|
|
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
|
|
{
|
|
float errorPct = errorPctBase + 0.05f * i;
|
|
|
|
Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(fullTestName, i, CompoundMeterId.Single);
|
|
IRegReader regReader = sensPath.RegisterReaders[i];
|
|
|
|
if (meterRslt != null && regReader != null)
|
|
{
|
|
meterRslt.VolumeMeter = tstRslt.TargetVolume() * (1.0 + 0.01 * errorPct);
|
|
|
|
meterRslt.PulsesMeter = regReader.PulsesPerLtr * meterRslt.VolumeMeter;
|
|
meterRslt.PulsesMaster = tstRslt.PulsesMaster;
|
|
meterRslt.PulsesPerLiter = regReader.PulsesPerLtr;
|
|
meterRslt.VolumeStart = 0;
|
|
meterRslt.VolumeEnd = meterRslt.VolumeMeter;
|
|
meterRslt.VolumeRef = tstRslt.TargetVolume();
|
|
meterRslt.TimestampStart = 0;
|
|
meterRslt.TimestampEnd = tstRslt.TargetTime();
|
|
meterRslt.TestTime = tstRslt.TargetTime();
|
|
meterRslt.Error = errorPct;
|
|
meterRslt.Passed = (errorPct >= tstRslt.ErrLimLo() + tstRslt.ErrLimMargin())
|
|
&& (errorPct <= tstRslt.ErrLimHi() - tstRslt.ErrLimMargin());
|
|
meterRslt.TestDone = true;
|
|
tstRslt.TestDone = true;
|
|
}
|
|
}
|
|
|
|
tstRslt.Components = Results.Entities.Components
|
|
.UpdateList(BatchRslts.ComponentsList,
|
|
new Results.Entities.Components((BenchInfo != null) ? BenchInfo.TestBenchId : 1,
|
|
(BenchInfo != null) ? BenchInfo.TestBenchName : "testbench",
|
|
(inPath != null && inPath.Pump != null) ? inPath.Pump.Name : string.Empty,
|
|
(outPath != null && outPath.FlowMeter != null) ? outPath.FlowMeter.Name : string.Empty,
|
|
(outPath != null && outPath.Scale != null) ? outPath.Scale.Name : string.Empty,
|
|
(outPath != null && outPath.RegulValve != null) ? outPath.RegulValve.Name : string.Empty,
|
|
(outPath != null && outPath.Diverter != null) ? outPath.Diverter.Name : string.Empty));
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Create a simulated test result (compound meter).
|
|
/// </summary>
|
|
/// <param name="test">Test to be simulated</param>
|
|
/// <returns>Test result</returns>
|
|
protected void MakeSimulatedCompound(Config.Entities.Test test, int repetitionNr, int part, float errorPct, float mainPart)
|
|
{
|
|
string fullTestName = Common.Utils.GetTestName(test.Name, test.Repeats, repetitionNr);
|
|
|
|
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(fullTestName, part);
|
|
|
|
if (tstRslt == null) return; /// Prevent program crash in certain cases
|
|
|
|
tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName;
|
|
tstRslt.StartTime = DateTime.Now;
|
|
tstRslt.EndTime = DateTime.Now + new TimeSpan(0, 0, 1);
|
|
tstRslt.FlowSetTime = 10;
|
|
tstRslt.TestTime = tstRslt.TargetTime();
|
|
/// TODO: Verify whether 'ltrPerRefPulse' is up to date
|
|
tstRslt.PulsesMaster = (LtrPerRefPulse > 1E-6) ? (tstRslt.TargetVolume() / LtrPerRefPulse) : 1;
|
|
tstRslt.ConstMasterRaw = LtrPerRefPulse;
|
|
tstRslt.ConstMaster = LtrPerRefPulse;
|
|
tstRslt.MassStartRaw = 0;
|
|
tstRslt.MassStart = 0;
|
|
tstRslt.MassEndRaw = tstRslt.TargetVolume() * Config.Formulas.RealDensity() / 1000.0f;
|
|
tstRslt.MassEnd = tstRslt.MassEndRaw;
|
|
tstRslt.DensityIn = tstRslt.Batch.RealDensity;
|
|
tstRslt.DensityLine = tstRslt.Batch.RealDensity;
|
|
tstRslt.DensityDiv = tstRslt.Batch.RealDensity;
|
|
tstRslt.MassOfEvapWater = 0;
|
|
tstRslt.FlowMass = tstRslt.MassEnd / tstRslt.TargetTime();
|
|
tstRslt.FlowVolume = tstRslt.TargetVolume() / tstRslt.TargetTime();
|
|
tstRslt.VolumeCTV = tstRslt.TargetVolume();
|
|
tstRslt.VolumeMaster = tstRslt.TargetVolume();
|
|
tstRslt.ErrorMaster = 0;
|
|
|
|
tstRslt.AmbTempMean = 20.0f;
|
|
tstRslt.AmbPressMean = 1.0f;
|
|
tstRslt.AmbHumiMean = 50.0f;
|
|
|
|
tstRslt.PressUpStart = 1.0f;
|
|
tstRslt.PressDownStart = 1.0f;
|
|
tstRslt.TempUpStart = 20.0f;
|
|
tstRslt.TempDownStart = 20.0f;
|
|
tstRslt.TempDivStart = 20.0f;
|
|
tstRslt.PressUpEnd = 1.0f;
|
|
tstRslt.PressDownEnd = 1.0f;
|
|
tstRslt.TempUpEnd = 20.0f;
|
|
tstRslt.TempDownEnd = 20.0f;
|
|
tstRslt.TempDivEnd = 20.0f;
|
|
tstRslt.PressUpMean = 1.0f;
|
|
tstRslt.PressDownMean = 1.0f;
|
|
tstRslt.TempUpMean = 20.0f;
|
|
tstRslt.TempDownMean = 20.0f;
|
|
tstRslt.TempDivMean = 20.0f;
|
|
tstRslt.PressUpMin = 1.0f;
|
|
tstRslt.PressDownMin = 1.0f;
|
|
tstRslt.TempUpMin = 20.0f;
|
|
tstRslt.TempDownMin = 20.0f;
|
|
tstRslt.TempDivMin = 20.0f;
|
|
tstRslt.PressUpMax = 1.0f;
|
|
tstRslt.PressDownMax = 1.0f;
|
|
tstRslt.TempUpMax = 20.0f;
|
|
tstRslt.TempDownMax = 20.0f;
|
|
tstRslt.TempDivMax = 20.0f;
|
|
tstRslt.ConductMin = Conductivity.Val;
|
|
tstRslt.ConductMax = Conductivity.Val;
|
|
|
|
tstRslt.FlowMean = (float)RefFlowStat.Average;
|
|
tstRslt.FlowStart = (float)RefFlowStat.First;
|
|
tstRslt.FlowEnd = (float)RefFlowStat.Last;
|
|
tstRslt.FlowMin = (float)RefFlowStat.Min;
|
|
tstRslt.FlowMax = (float)RefFlowStat.Max;
|
|
|
|
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
|
|
{
|
|
Results.Entities.MeterTestRslt compoundRslt = ProcessData.BatchRslts.GetMeterTestRslt(fullTestName, i, CompoundMeterId.Compound);
|
|
Results.Entities.MeterTestRslt mainRslt = ProcessData.BatchRslts.GetMeterTestRslt(fullTestName, i, CompoundMeterId.CompoundMain);
|
|
Results.Entities.MeterTestRslt auxRslt = ProcessData.BatchRslts.GetMeterTestRslt(fullTestName, i, CompoundMeterId.CompoundAux);
|
|
|
|
double compoundVolume = tstRslt.TargetVolume() * (1.0 + 0.01 * errorPct);
|
|
double mainVolume = compoundVolume * mainPart;
|
|
double auxVolume = compoundVolume * (1.0 - mainPart);
|
|
|
|
for (int isAux = 0; isAux <= 1; isAux++) /// 0=main, 1=aux
|
|
{
|
|
GenericDevices.IRegReader regReader = sensPath.RegisterReaders[2 * i + isAux];
|
|
Results.Entities.MeterTestRslt meterRslt = (isAux == 0) ? mainRslt : auxRslt;
|
|
|
|
if (meterRslt != null && regReader != null)
|
|
{
|
|
meterRslt.VolumeMeter = (isAux == 0) ? mainVolume : auxVolume;
|
|
|
|
meterRslt.PulsesMeter = regReader.PulsesPerLtr * meterRslt.VolumeMeter;
|
|
meterRslt.PulsesMaster = tstRslt.PulsesMaster;
|
|
meterRslt.PulsesPerLiter = regReader.PulsesPerLtr;
|
|
meterRslt.VolumeStart = 0;
|
|
meterRslt.VolumeEnd = meterRslt.VolumeMeter;
|
|
meterRslt.VolumeRef = tstRslt.TargetVolume();
|
|
meterRslt.TimestampStart = 0;
|
|
meterRslt.TimestampEnd = tstRslt.TargetTime();
|
|
meterRslt.TestTime = tstRslt.TargetTime();
|
|
meterRslt.Error = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, tstRslt.VolumeCTV);
|
|
meterRslt.Passed = (errorPct >= tstRslt.ErrLimLo() + tstRslt.ErrLimMargin())
|
|
&& (errorPct <= tstRslt.ErrLimHi() - tstRslt.ErrLimMargin());
|
|
meterRslt.TestDone = true;
|
|
}
|
|
}
|
|
|
|
compoundRslt.VolumeRef = tstRslt.VolumeCTV; /// [l] must be calculated before main & aux. meter error
|
|
compoundRslt.VolumeMeter = mainRslt.VolumeMeter + auxRslt.VolumeMeter;
|
|
|
|
compoundRslt.PulsesMaster = tstRslt.PulsesMaster;
|
|
compoundRslt.TestTime = tstRslt.TargetTime();
|
|
compoundRslt.Error = Formulas.ErrorFromVolumes(compoundRslt.VolumeMeter, tstRslt.VolumeCTV);
|
|
compoundRslt.Passed = (compoundRslt.Error >= tstRslt.ErrLimLo() + tstRslt.ErrLimMargin())
|
|
&& (compoundRslt.Error <= tstRslt.ErrLimHi() - tstRslt.ErrLimMargin());
|
|
compoundRslt.TestDone = true;
|
|
tstRslt.TestDone = true;
|
|
}
|
|
|
|
tstRslt.Components = Results.Entities.Components.UpdateList(BatchRslts.ComponentsList,
|
|
new Results.Entities.Components((BenchInfo != null) ? BenchInfo.TestBenchId : 1,
|
|
(BenchInfo != null) ? BenchInfo.TestBenchName : "testbench",
|
|
(inPath != null && inPath.Pump != null) ? inPath.Pump.Name : string.Empty,
|
|
(outPath != null && outPath.FlowMeter != null) ? outPath.FlowMeter.Name : string.Empty,
|
|
(outPath != null && outPath.Scale != null) ? outPath.Scale.Name : string.Empty,
|
|
(outPath != null && outPath.RegulValve != null) ? outPath.RegulValve.Name : string.Empty,
|
|
(outPath != null && outPath.Diverter != null) ? outPath.Diverter.Name : string.Empty));
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Create a simulated test result (heat meters).
|
|
/// </summary>
|
|
/// <param name="test">Test to be simulated</param>
|
|
/// <returns>Test result</returns>
|
|
protected void MakeSimulatedHeatMeters(Config.Entities.Test test, int repetitionNr, int part, float errorPct, double energy, float energyErrLimLo, float energyErrLimHi, bool evaluateVolume)
|
|
{
|
|
string fullTestName = Common.Utils.GetTestName(test.Name, test.Repeats, repetitionNr);
|
|
|
|
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(fullTestName, part);
|
|
|
|
if (tstRslt == null) return; /// Prevent program crash in certain cases
|
|
|
|
tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName;
|
|
tstRslt.StartTime = DateTime.Now;
|
|
tstRslt.EndTime = DateTime.Now + new TimeSpan(0, 0, 1);
|
|
tstRslt.FlowSetTime = 10;
|
|
tstRslt.TestTime = tstRslt.TargetTime();
|
|
/// TODO: Verify whether 'ltrPerRefPulse' is up to date
|
|
tstRslt.PulsesMaster = (LtrPerRefPulse > 1E-6) ? (tstRslt.TargetVolume() / LtrPerRefPulse) : 1;
|
|
tstRslt.ConstMasterRaw = LtrPerRefPulse;
|
|
tstRslt.ConstMaster = LtrPerRefPulse;
|
|
tstRslt.MassStartRaw = 0;
|
|
tstRslt.MassStart = 0;
|
|
tstRslt.MassEndRaw = tstRslt.TargetVolume() * Config.Formulas.RealDensity() / 1000.0f;
|
|
tstRslt.MassEnd = tstRslt.MassEndRaw;
|
|
tstRslt.DensityIn = tstRslt.Batch.RealDensity;
|
|
tstRslt.DensityLine = tstRslt.Batch.RealDensity;
|
|
tstRslt.DensityDiv = tstRslt.Batch.RealDensity;
|
|
tstRslt.MassOfEvapWater = 0;
|
|
tstRslt.FlowMass = tstRslt.MassEnd / tstRslt.TargetTime();
|
|
tstRslt.FlowVolume = tstRslt.TargetVolume() / tstRslt.TargetTime();
|
|
tstRslt.VolumeCTV = tstRslt.TargetVolume();
|
|
tstRslt.VolumeMaster = tstRslt.TargetVolume();
|
|
tstRslt.ErrorMaster = 0;
|
|
|
|
tstRslt.AmbTempMean = 20.0f;
|
|
tstRslt.AmbPressMean = 1.0f;
|
|
tstRslt.AmbHumiMean = 50.0f;
|
|
|
|
tstRslt.PressUpStart = 1.0f;
|
|
tstRslt.PressDownStart = 1.0f;
|
|
tstRslt.TempUpStart = 20.0f;
|
|
tstRslt.TempDownStart = 20.0f;
|
|
tstRslt.TempDivStart = 20.0f;
|
|
tstRslt.PressUpEnd = 1.0f;
|
|
tstRslt.PressDownEnd = 1.0f;
|
|
tstRslt.TempUpEnd = 20.0f;
|
|
tstRslt.TempDownEnd = 20.0f;
|
|
tstRslt.TempDivEnd = 20.0f;
|
|
tstRslt.PressUpMean = 1.0f;
|
|
tstRslt.PressDownMean = 1.0f;
|
|
tstRslt.TempUpMean = 20.0f;
|
|
tstRslt.TempDownMean = 20.0f;
|
|
tstRslt.TempDivMean = 20.0f;
|
|
tstRslt.PressUpMin = 1.0f;
|
|
tstRslt.PressDownMin = 1.0f;
|
|
tstRslt.TempUpMin = 20.0f;
|
|
tstRslt.TempDownMin = 20.0f;
|
|
tstRslt.TempDivMin = 20.0f;
|
|
tstRslt.PressUpMax = 1.0f;
|
|
tstRslt.PressDownMax = 1.0f;
|
|
tstRslt.TempUpMax = 20.0f;
|
|
tstRslt.TempDownMax = 20.0f;
|
|
tstRslt.TempDivMax = 20.0f;
|
|
tstRslt.ConductMin = Conductivity.Val;
|
|
tstRslt.ConductMax = Conductivity.Val;
|
|
|
|
tstRslt.FlowMean = 0; /// TODO
|
|
tstRslt.FlowMax = 0; /// TODO
|
|
|
|
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
|
|
{
|
|
Results.Entities.MeterTestRslt energyRslt = ProcessData.BatchRslts.GetMeterTestRslt(fullTestName, i, CompoundMeterId.HeatMeterEnergy);
|
|
Results.Entities.MeterTestRslt volumeRslt = ProcessData.BatchRslts.GetMeterTestRslt(fullTestName, i, CompoundMeterId.HeatMeterVolume);
|
|
|
|
GenericDevices.IRegReader volumeRegReader = (sensPath.RegisterReaders.Length > 2 * i) ? sensPath.RegisterReaders[2 * i] : null;
|
|
GenericDevices.IRegReader energyRegReader = (sensPath.RegisterReaders.Length > 2 * i + 1) ? sensPath.RegisterReaders[2 * i + 1] : null;
|
|
|
|
double volumeMeter = tstRslt.TargetVolume() * (1.0 + 0.01 * errorPct);
|
|
double energyMeter = energy * (1.0 + 0.01 * errorPct);
|
|
|
|
if (volumeRslt != null && volumeRegReader != null)
|
|
{
|
|
volumeRslt.VolumeMeter = volumeMeter;
|
|
|
|
volumeRslt.PulsesMeter = volumeRegReader.PulsesPerLtr * volumeMeter;
|
|
volumeRslt.PulsesMaster = tstRslt.PulsesMaster;
|
|
volumeRslt.PulsesPerLiter = volumeRegReader.PulsesPerLtr;
|
|
volumeRslt.VolumeStart = 0;
|
|
volumeRslt.VolumeEnd = volumeMeter;
|
|
volumeRslt.VolumeRef = tstRslt.TargetVolume();
|
|
volumeRslt.TimestampStart = 0;
|
|
volumeRslt.TimestampEnd = tstRslt.TargetTime();
|
|
volumeRslt.TestTime = tstRslt.TargetTime();
|
|
volumeRslt.Error = Formulas.ErrorFromVolumes(volumeMeter, tstRslt.VolumeCTV);
|
|
volumeRslt.Passed = !evaluateVolume ||
|
|
((errorPct >= tstRslt.ErrLimLo() + tstRslt.ErrLimMargin()) &&
|
|
(errorPct <= tstRslt.ErrLimHi() - tstRslt.ErrLimMargin()));
|
|
volumeRslt.TestDone = true;
|
|
tstRslt.TestDone = true;
|
|
}
|
|
|
|
if (energyRslt != null && energyRegReader != null)
|
|
{
|
|
energyRslt.VolumeMeter = energyMeter;
|
|
|
|
energyRslt.PulsesMeter = energyRegReader.PulsesPerLtr * energyMeter;
|
|
energyRslt.PulsesMaster = tstRslt.PulsesMaster;
|
|
energyRslt.PulsesPerLiter = energyRegReader.PulsesPerLtr;
|
|
energyRslt.VolumeStart = 0;
|
|
energyRslt.VolumeEnd = energyMeter;
|
|
energyRslt.VolumeRef = energy;
|
|
energyRslt.TimestampStart = 0;
|
|
energyRslt.TimestampEnd = tstRslt.TargetTime();
|
|
energyRslt.TestTime = tstRslt.TargetTime();
|
|
energyRslt.Error = Formulas.ErrorFromVolumes(energyMeter, energy);
|
|
energyRslt.Passed = (errorPct >= energyErrLimLo) && (errorPct <= energyErrLimHi);
|
|
energyRslt.TestDone = true;
|
|
tstRslt.TestDone = true;
|
|
}
|
|
}
|
|
|
|
tstRslt.Components = Results.Entities.Components
|
|
.UpdateList(BatchRslts.ComponentsList,
|
|
new Results.Entities.Components((BenchInfo != null) ? BenchInfo.TestBenchId : 1,
|
|
(BenchInfo != null) ? BenchInfo.TestBenchName : "testbench",
|
|
(inPath != null && inPath.Pump != null) ? inPath.Pump.Name : string.Empty,
|
|
(outPath != null && outPath.FlowMeter != null) ? outPath.FlowMeter.Name : string.Empty,
|
|
(outPath != null && outPath.Scale != null) ? outPath.Scale.Name : string.Empty,
|
|
(outPath != null && outPath.RegulValve != null) ? outPath.RegulValve.Name : string.Empty,
|
|
(outPath != null && outPath.Diverter != null) ? outPath.Diverter.Name : string.Empty));
|
|
}
|
|
|
|
protected bool TestAndLogUiCmdStop(IList<Event> e)
|
|
{
|
|
return TestAndLogUiCmdStop(null, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true and makes a log when 'e' contains Event.UiCmdStop
|
|
/// </summary>
|
|
/// <param name="test">test or null (only for logs)</param>
|
|
/// <param name="e"></param>
|
|
/// <returns></returns>
|
|
protected bool TestAndLogUiCmdStop(Test test, IList<Event> e)
|
|
{
|
|
if (!e.Contains(Event.UiCmdStop)) return false;
|
|
|
|
log.FatalFormat("STOP pressed: Procedure={0}, Test={1}, State={2}",
|
|
(StateMachine.Procedure == null) ? "?" : StateMachine.Procedure.Name,
|
|
(test == null) ? "?" : test.Name,
|
|
State.CurrentState.Name);
|
|
|
|
if (test != null)
|
|
{
|
|
log.FatalFormat("Process values:");
|
|
log.FatalFormat(" Method: {0}", test.Method);
|
|
log.FatalFormat(" Test start time: {0}", TestStartTime.ToShortTimeString());
|
|
log.FatalFormat(" Feeding path: {0}", (inPath != null) ? inPath.ToString() : "none");
|
|
log.FatalFormat(" Bench path: {0}", (benchPath != null) ? benchPath.ToString() : "none");
|
|
log.FatalFormat(" Output path: {0}", (outPath != null) ? outPath.ToString() : "none");
|
|
if (inPath.Pump is IPump) log.FatalFormat(" Pump power: {0}%", (inPath.Pump as IPump).Power);
|
|
else if (inPath.Pump is IValve) log.FatalFormat(" Feeding valve: {0}", (inPath.Pump as IValve).State ? "open" : "close");
|
|
if (outPath.RegulValve is IRegValve) log.FatalFormat(" Regulation valve position: {0}%", outPath.RegulValve.Position);
|
|
log.FatalFormat(" Flow: {0}", RefFlow);
|
|
log.FatalFormat(" Mass: {0}", Mass);
|
|
log.FatalFormat(" Start mass: {0}", StartMass);
|
|
log.FatalFormat(" Liter/ref.pulse: {0}", LtrPerRefPulse);
|
|
log.FatalFormat(" Reference pulses: {0}", RefPulses);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|