2015-04-15 18:32:56 +00:00
///
/// Copyright (c) 2013-2015 Sensus Metering Systems
///
using System ;
2014-07-28 07:54:35 +00:00
using System.Collections.Generic ;
using System.Linq ;
2014-07-31 15:04:09 +00:00
using log4net ;
2014-07-28 07:54:35 +00:00
using TBF.BenchControl.GenericDevices ;
using TBF.BenchControl.Operations ;
2014-07-31 15:04:09 +00:00
using TBF.Boxes ;
using TBF.Resources ;
using TBF.UiBridge ;
2014-07-28 07:54:35 +00:00
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 ) ) ;
2014-09-09 14:18:23 +00:00
protected static readonly ILog processDataLogger = LogManager . GetLogger ( "ProcessData" ) ;
2014-09-16 10:04:08 +00:00
protected static readonly ILog allResults = LogManager . GetLogger ( "AllResults" ) ;
2015-02-02 10:38:42 +00:00
protected static readonly ILog summaryResults = LogManager . GetLogger ( "SummaryResults" ) ;
2014-07-28 07:54:35 +00:00
///------------------------------------------------------------
/// Global static variables set only once.
///------------------------------------------------------------
2015-08-01 20:21:43 +00:00
public static IBenchInfo BenchInfo ;
2014-09-06 15:34:26 +00:00
public static IList < IFlowMeter > FlowMeters ; /// list of reference flowmeters
public static IList < IRegulValve > RegulValves ; /// list of regulation valves
2014-09-08 11:16:31 +00:00
public static IList < IPumpFM > PumpsWithFM ; /// list of FM controlled pumps
2014-07-28 07:54:35 +00:00
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 ;
2014-09-06 15:34:26 +00:00
public static int ReferenceFlowmetersCount ;
public static float [ ] LtrPerRefPulse ; /// Reference flowmeter coefficients
public static float Qrise ;
2014-07-28 07:54:35 +00:00
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 )
{
2015-08-25 15:02:58 +00:00
if ( newTestResult = = null ) return ;
2015-02-07 20:06:09 +00:00
Entities . TestResult toDelete =
results . FirstOrDefault < Entities . TestResult > ( x = > x . Name . Equals ( newTestResult . Name ) & &
( x . Part = = newTestResult . Part ) & &
( x . TestId = = newTestResult . TestId ) ) ;
if ( toDelete ! = null ) results . Remove ( toDelete ) ;
2014-07-28 07:54:35 +00:00
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 )
{
2014-09-16 14:09:07 +00:00
if ( ! test . Method . Contains ( "RoiDetection" ) ) /// TODO: Use 'DoNotEvaluate' etc.
2014-07-28 07:54:35 +00:00
{
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 > ( ) ;
2014-08-01 06:36:17 +00:00
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" } ;
}
2015-01-15 05:34:36 +00:00
}
2014-08-01 06:36:17 +00:00
///------------------------------------------------------------
/// Test related (instance) variables.
/// Created when test sequence is open.
/// They persist during all repetitions of the same test
///------------------------------------------------------------
2014-08-12 20:21:26 +00:00
protected static BenchControl . FeedingPath inPath ;
protected static BenchControl . BenchPath benchPath ;
protected static BenchControl . OutputPath outPath ;
protected static BenchControl . MetersPath sensPath ;
2015-05-22 08:29:56 +00:00
protected static Entities . TransitionSequence transitionBefore ;
protected static Entities . TransitionSequence transitionAfter ;
2014-07-28 07:54:35 +00:00
2014-07-31 20:17:38 +00:00
2014-08-01 06:36:17 +00:00
#region Temperature_Pressure_Humidity
2014-07-31 20:17:38 +00:00
2014-09-10 10:05:49 +00:00
protected static FloatBox tempIn = new FloatBox ( ) { Name = "Temperature In" , Format = "F2" } ;
protected static FloatBox tempOut = new FloatBox ( ) { Name = "Temperature Out" , Format = "F2" } ;
protected static FloatBox tempDiv = new FloatBox ( ) { Name = "Temperature Div" , Format = "F2" } ;
2014-08-01 06:36:17 +00:00
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" } ;
2014-07-28 07:54:35 +00:00
///
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 ( )
{
2014-07-31 15:04:09 +00:00
tempInSum + = tempIn . Val ;
tempOutSum + = tempOut . Val ;
tempDivSum + = tempDiv . Val ;
pressInSum + = pressIn . Val ;
pressOutSum + = pressOut . Val ;
ambientTempSum + = airTemperature . Val ;
ambientPressSum + = airPressure . Val ;
ambientHumiSum + = airHumidity . Val ;
2014-07-28 07:54:35 +00:00
///
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
2014-09-09 14:18:23 +00:00
protected float ltrPerRefPulse ;
2014-07-28 07:54:35 +00:00
2015-08-19 11:04:47 +00:00
protected IOperation readRegistersOp ;
2014-07-28 07:54:35 +00:00
protected IOperation queryEnd1 ;
protected IOperation queryEnd2 ;
protected IOperation checkUiOp ;
2014-09-09 14:18:23 +00:00
protected IOperation processDataLoggingOp ;
2014-07-31 20:17:38 +00:00
2014-08-01 06:36:17 +00:00
protected int [ ] WMPulses = new int [ Program . WMsCount ] ;
protected int [ ] WMRefPulses = new int [ Program . WMsCount ] ;
2015-08-19 11:04:47 +00:00
protected double [ ] WMTimes = new double [ Program . WMsCount ] ;
2014-08-01 06:36:17 +00:00
protected static FloatBox [ ] WMVolumes ;
protected static FloatBox [ ] WMErrors ;
2014-08-15 12:31:45 +00:00
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" } ;
2015-03-25 09:01:37 +00:00
protected static FloatBox mass = new FloatBox ( ) { Name = "Mass" , Format = "F3" } ;
protected static FloatBox startMass = new FloatBox ( ) { Name = "Start Mass" , Format = "F3" } ;
protected static FloatBox endMass = new FloatBox ( ) { Name = "End Mass" , Format = "F3" } ;
2014-07-31 20:17:38 +00:00
/// <summary>
/// To clear process values at the beginning of each test
/// </summary>
protected void ClearProcessValues ( )
{
2014-08-01 06:36:17 +00:00
//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 ( ) ;
}
2014-07-31 20:17:38 +00:00
refCount . Clear ( ) ;
refFreq . Clear ( ) ;
refFlow . Clear ( ) ;
mass . Clear ( ) ;
startMass . Clear ( ) ;
endMass . Clear ( ) ;
}
2014-09-09 14:18:23 +00:00
///
/// Process data logging
///
public void LogProcessHeader ( ILog logger )
{
LogProcessHeader ( logger , null ) ;
}
public void LogProcessHeader ( ILog logger , string sectionName )
{
logger . Info ( Environment . NewLine ) ;
if ( sectionName ! = null ) logger . Info ( sectionName ) ;
2015-01-15 11:15:36 +00:00
logger . Info ( "Time Flow TstTime Ref.cnt Ref.vol Tin Tout Tdiv Pin Pout Mass VolMM Tamb Hamb Pamb Rv" ) ;
2014-09-09 14:18:23 +00:00
logger . Info ( Environment . NewLine ) ;
}
public void LogProcessData ( ILog logger )
{
2014-09-10 10:05:49 +00:00
logger . InfoFormat ( "{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14} {15}" ,
DateTime . Now . ToLongTimeString ( ) ,
2015-01-15 11:15:36 +00:00
Utils . FloatToStr ( refFlow . Val , 4 ) ,
2014-09-10 10:05:49 +00:00
StateMachine . ControlBoard . TTime . ToString ( "F3" ) ,
StateMachine . ControlBoard . EtPulses ( 0 ) ,
Formulas . VolumeFromPulses ( StateMachine . ControlBoard . EtPulses ( 0 ) , 1.0f / ltrPerRefPulse ) . ToString ( "F3" ) ,
2014-09-09 14:18:23 +00:00
tempIn ,
tempOut ,
2014-09-09 16:29:01 +00:00
tempDiv ,
2014-09-09 14:18:23 +00:00
pressIn ,
pressOut ,
mass ,
"VolMM" ,
airTemperature ,
airHumidity ,
airPressure ,
2014-09-10 10:05:49 +00:00
outPath . RegulValve . Position . ToString ( "F1" ) ) ;
2014-09-09 14:18:23 +00:00
}
2014-07-28 07:54:35 +00:00
/// <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 ) ) ;
}
2014-09-08 15:13:31 +00:00
while ( ! Balance . IsEmpty ( mass . Val ) ) ;
2014-07-28 07:54:35 +00:00
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 ;
}
2014-08-15 12:31:45 +00:00
/// <summary>
/// Passed as an argument to Transition(sequence, context)
/// </summary>
public enum TransitionContext
{
PurgeBegin ,
PurgeEnd ,
2015-05-22 08:29:56 +00:00
BeforeTest ,
AfterTest ,
2014-08-15 12:31:45 +00:00
}
2014-07-28 07:54:35 +00:00
/// <summary>
2014-08-15 12:31:45 +00:00
/// Executes steps of a transition sequence
2014-07-28 07:54:35 +00:00
/// </summary>
/// <param name="transitionSequence">TransitionSequence entity</param>
2014-08-15 12:31:45 +00:00
/// <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>
2014-08-14 07:05:40 +00:00
protected Event Transition ( Entities . TransitionSequence transitionSequence , TransitionContext context )
2014-07-28 07:54:35 +00:00
{
2014-08-14 07:05:40 +00:00
IList < Event > e ;
2014-07-28 07:54:35 +00:00
2014-08-14 07:05:40 +00:00
string message ;
switch ( context )
{
case TransitionContext . PurgeBegin : message = Strings . Purging_i_n ; break ;
case TransitionContext . PurgeEnd : message = Strings . Emptying_i_n ; break ;
2015-05-22 08:29:56 +00:00
case TransitionContext . BeforeTest : message = Strings . Test_start_sequence_i_n ; break ;
case TransitionContext . AfterTest : message = Strings . Test_stop_sequence_i_n ; break ;
2014-08-14 07:05:40 +00:00
default : message = "Transition" ; break ;
}
2014-07-28 07:54:35 +00:00
2014-08-14 07:05:40 +00:00
if ( transitionSequence = = null )
2014-07-28 07:54:35 +00:00
{
2014-08-14 07:05:40 +00:00
///
2014-09-07 15:01:30 +00:00
/// No transition sequence defined --> Default action
2014-08-14 07:05:40 +00:00
///
2015-05-22 08:29:56 +00:00
if ( context = = TransitionContext . BeforeTest )
2014-08-14 07:05:40 +00:00
{
State . Create ( "SequenceBase : Transition : TestStart - Default action" )
2015-05-22 10:31:10 +00:00
. AddOperation ( checkUiOp )
. AddOperation ( new MettlerToledo . KeepReadingMassesOp ( ) )
. AddOperation ( StateMachine . ControlBoard . UpdateTankWeightOp ( ) )
. AddOperation ( StateMachine . ControlBoard
. SetValvesOp ( GenericDevices . ValveBase . Merge ( inPath . ValvesOpen , benchPath . ValvesOpen , outPath . ValvesOpen ) ,
GenericDevices . ValveBase . Merge ( inPath . ValvesClose , benchPath . ValvesClose , outPath . ValvesClose ) ) )
2014-08-14 07:05:40 +00:00
. EnterState ( ) ;
2014-12-13 10:54:35 +00:00
do
{
2014-08-14 07:05:40 +00:00
e = StateMachine . WaitRunDevsRunOps ( ) ;
if ( e . Contains ( Event . UiCmdStop ) ) return Event . UiCmdStop ;
}
2014-12-13 10:54:35 +00:00
while ( e . Contains ( Event . ValvesBusy ) ) ;
2014-08-14 07:05:40 +00:00
}
2015-05-22 08:29:56 +00:00
else if ( context = = TransitionContext . AfterTest )
2014-08-14 07:05:40 +00:00
{
State . Create ( "SequenceBase : Transition : TestEnd - Default action" )
2015-05-22 10:31:10 +00:00
. AddOperation ( checkUiOp )
. AddOperation ( new MettlerToledo . KeepReadingMassesOp ( ) )
. AddOperation ( StateMachine . ControlBoard . UpdateTankWeightOp ( ) )
. AddOperation ( StateMachine . ControlBoard . SetValvesOp ( StateMachine . DefaultValvesOpen ,
StateMachine . DefaultValvesClose ) )
2014-08-14 07:05:40 +00:00
. EnterState ( ) ;
do {
e = StateMachine . WaitRunDevsRunOps ( ) ;
if ( e . Contains ( Event . UiCmdStop ) ) return Event . UiCmdStop ;
}
while ( ! e . Contains ( Event . ValvesSet ) ) ;
}
}
else
{
///
2014-09-07 15:01:30 +00:00
/// Execute the transition sequence
2014-08-14 07:05:40 +00:00
///
IList < Entities . TransitionStep > transitionSteps = StateMachine . WtSession
. CreateQuery ( "FROM TransitionStep WHERE TransitionSequence = :tsId ORDER BY ItemNr" )
. SetParameter ( "tsId" , transitionSequence . Id )
. List < Entities . TransitionStep > ( ) ;
int stepsCount = transitionSteps . Count ;
foreach ( var step in transitionSteps )
{
//------------------------------------------------
2015-04-18 11:31:31 +00:00
string activity = string . Format ( message , transitionSequence . Name , step . ItemNr + 1 , stepsCount ) ;
Bridge . OnActivity ( this , activity ) ;
2015-01-12 03:53:50 +00:00
Bridge . OnMessage ( this , step . Message ) ;
2015-04-18 11:31:31 +00:00
log . Info ( activity + " " + step . Message ) ;
2014-08-14 07:05:40 +00:00
//------------------------------------------------
2014-12-12 12:57:24 +00:00
/// FM controlled pumps are canged imediately without using any state operations
2015-04-18 11:31:31 +00:00
log . DebugFormat ( "step.PumpWithFMPcts = {0}" , step . PumpWithFMPcts ) ;
2014-09-08 11:16:31 +00:00
float [ ] allFMPumpPcts = Utils . GetPumpWithFMPcts ( step ) ;
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 ( ) ;
}
}
2014-12-12 12:57:24 +00:00
/// Get new regulation valve positions,
2014-09-08 11:16:31 +00:00
float [ ] allRegvPositions = Utils . GetRegulValvesPositions ( step ) ;
2014-12-12 12:57:24 +00:00
/// Prepare necessary SetRegValvePositionOp operations for RV-s with changed positions
IList < IOperation > rvPosOps = new List < IOperation > ( ) ;
2015-04-18 11:31:31 +00:00
IList < string > rvPosStr = new List < string > ( ) ;
2014-08-14 07:05:40 +00:00
for ( int i = 0 ; i < allRegvPositions . Length ; i + + )
{
if ( allRegvPositions [ i ] > = 0 ) /// Negative value means no position change
{
2015-04-18 11:31:31 +00:00
float lo = Math . Max ( 0 , allRegvPositions [ i ] - 0.05f ) ;
float hi = Math . Min ( 100.0f , allRegvPositions [ i ] + 0.05f ) ;
rvPosOps . Add ( RegulValves [ i ] . SetRegulValvePositionOp ( lo , hi , 60 ) ) ;
rvPosStr . Add ( string . Format ( "RV{0}.SetRegulValvePositionOp({1}, {2}, 60s)" , i , lo , hi ) ) ;
2014-08-14 07:05:40 +00:00
}
}
2014-12-13 10:54:35 +00:00
/// 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 ) ;
2014-12-12 12:57:24 +00:00
bool stopFlag = false ;
2014-12-13 10:54:35 +00:00
bool errorFlag = false ;
///
2015-01-08 07:05:23 +00:00
int lastStartedRV = - 1 ;
for ( int i = 0 ; i < rvPosOps . Count ; i + + )
{
2015-04-18 11:31:31 +00:00
log . DebugFormat ( "SequenceBase.Transition() : Step {0} start, opening={1}, closing={2}" , step . ItemNr + 1 , step . ValvesOpen , step . ValvesClose ) ;
2015-05-22 10:31:10 +00:00
State stepStrt = State
. Create ( string . Format ( "SequenceBase.Transition() : Step {0} start, opening={1}, closing={2}" , step . ItemNr + 1 , step . ValvesOpen , step . ValvesClose ) )
2015-01-08 07:05:23 +00:00
. AddOperation ( checkUiOp )
2015-05-22 10:31:10 +00:00
. AddOperation ( new MettlerToledo . KeepReadingMassesOp ( ) )
. AddOperation ( StateMachine . ControlBoard . UpdateTankWeightOp ( ) )
2015-01-08 07:05:23 +00:00
. AddOperation ( StateMachine . ControlBoard . SetValvesOp ( Utils . ValvesOpen ( step ) , Utils . ValvesClose ( step ) ) ) ;
2015-04-18 11:31:31 +00:00
for ( int j = 0 ; j < = i ; j + + )
{
stepStrt . AddOperation ( rvPosOps [ j ] ) ;
log . Debug ( rvPosStr [ j ] ) ;
}
2015-01-08 07:05:23 +00:00
lastStartedRV = i ;
stepStrt . EnterState ( ) ;
e = StateMachine . WaitRunDevsRunOps ( ) ;
if ( e . Contains ( Event . Error ) | | e . Contains ( Event . RegulValveTimeOut ) ) { errorFlag = true ; break ; }
if ( e . Contains ( Event . UiCmdStop ) ) { stopFlag = true ; break ; }
}
2014-12-13 10:54:35 +00:00
/// Max. valaue of lastStartedRV after exitting the loop is (rvPosOps.Count - 1)
2014-08-14 07:05:40 +00:00
2014-12-13 10:54:35 +00:00
if ( ! ( stopFlag | | errorFlag ) )
{
2015-04-18 11:31:31 +00:00
log . DebugFormat ( "SequenceBase.Transition() : Step {0} delay {1}s, opening={2}, closing={3}" , step . ItemNr + 1 , delay , step . ValvesOpen , step . ValvesClose ) ;
2015-05-22 10:31:10 +00:00
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 ) )
2014-12-13 10:54:35 +00:00
. AddOperation ( checkUiOp )
2015-05-22 10:31:10 +00:00
. AddOperation ( new MettlerToledo . KeepReadingMassesOp ( ) )
. AddOperation ( StateMachine . ControlBoard . UpdateTankWeightOp ( ) )
. AddOperation ( StateMachine . ControlBoard . SetValvesOp ( Utils . ValvesOpen ( step ) , Utils . ValvesClose ( step ) ) )
2014-12-13 10:54:35 +00:00
. AddOperation ( new TimerOp ( delay ) ) ;
2015-04-18 11:31:31 +00:00
for ( int j = 0 ; j < = lastStartedRV ; j + + )
{
stepDelay . AddOperation ( rvPosOps [ j ] ) ;
log . Debug ( rvPosStr [ j ] ) ;
}
2014-12-13 10:54:35 +00:00
stepDelay . EnterState ( ) ;
2015-05-22 10:31:10 +00:00
bool endContitionFulfilled = false ;
do
2014-12-12 12:57:24 +00:00
{
e = StateMachine . WaitRunDevsRunOps ( ) ;
2014-12-13 10:54:35 +00:00
if ( e . Contains ( Event . Error ) | | e . Contains ( Event . RegulValveTimeOut ) ) { errorFlag = true ; break ; }
if ( e . Contains ( Event . UiCmdStop ) ) { stopFlag = true ; break ; }
2015-05-22 10:31:10 +00:00
switch ( step . EndCondition )
{
case Entities . StepCondition . Scale1Empty :
endContitionFulfilled = ( StateMachine . Balance1 = = null ) | | StateMachine . Balance1 . IsEmpty ( ) ;
break ;
case Entities . StepCondition . Scale2Empty :
endContitionFulfilled = ( StateMachine . Balance2 = = null ) | | StateMachine . Balance2 . IsEmpty ( ) ;
break ;
case Entities . StepCondition . Scale3Empty :
endContitionFulfilled = ( StateMachine . Balance3 = = null ) | | StateMachine . Balance3 . IsEmpty ( ) ;
break ;
case Entities . StepCondition . AllScalesEmpty :
endContitionFulfilled = ( ( StateMachine . Balance1 = = null ) | | StateMachine . Balance1 . IsEmpty ( ) ) & &
( ( StateMachine . Balance2 = = null ) | | StateMachine . Balance2 . IsEmpty ( ) ) & &
( ( StateMachine . Balance3 = = null ) | | StateMachine . Balance3 . IsEmpty ( ) ) ;
break ;
}
2014-12-12 12:57:24 +00:00
}
2015-05-22 10:31:10 +00:00
while ( e . Contains ( Event . ValvesBusy ) | | ( ! endContitionFulfilled & & e . Contains ( Event . TimerBusy ) ) ) ;
2014-12-12 12:57:24 +00:00
}
2014-12-13 10:54:35 +00:00
for ( int first = 1 ; first < = lastStartedRV ; first + + )
{
2015-04-18 11:31:31 +00:00
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 ) )
2014-12-13 10:54:35 +00:00
. AddOperation ( checkUiOp )
2015-05-22 10:31:10 +00:00
. AddOperation ( new MettlerToledo . KeepReadingMassesOp ( ) )
. AddOperation ( StateMachine . ControlBoard . UpdateTankWeightOp ( ) )
. AddOperation ( StateMachine . ControlBoard . SetValvesOp ( Utils . ValvesOpen ( step ) , Utils . ValvesClose ( step ) ) ) ;
2015-04-18 11:31:31 +00:00
for ( int j = first ; j < = lastStartedRV ; j + + )
{
stepStop . AddOperation ( rvPosOps [ j ] ) ;
log . Debug ( rvPosStr [ j ] ) ;
}
2014-12-13 10:54:35 +00:00
stepStop . EnterState ( ) ;
e = StateMachine . WaitRunDevsRunOps ( ) ;
if ( e . Contains ( Event . Error ) | | e . Contains ( Event . RegulValveTimeOut ) ) { errorFlag = true ; }
if ( e . Contains ( Event . UiCmdStop ) ) { stopFlag = true ; }
}
2014-08-14 07:05:40 +00:00
2014-12-13 10:54:35 +00:00
if ( errorFlag ) return Event . Error ;
if ( stopFlag ) return Event . UiCmdStop ;
2014-08-14 07:05:40 +00:00
}
}
2015-05-22 08:29:56 +00:00
if ( context = = TransitionContext . AfterTest )
2014-08-14 07:05:40 +00:00
{
///
/// Stop the pump at the end of test
///
2014-09-08 11:16:31 +00:00
foreach ( var fmPump in PumpsWithFM ) fmPump . TurnOff ( ) ;
2014-08-14 07:05:40 +00:00
State . Create ( "SequenceBase : Test(s) completed -> Stopping the pump" )
. AddOperation ( checkUiOp )
2015-05-22 10:31:10 +00:00
. AddOperation ( StateMachine . ControlBoard . UpdateTankWeightOp ( ) )
2014-09-08 11:16:31 +00:00
. AddOperation ( ( inPath . Pump is GenericDevices . IPumpFM ) ? ( inPath . Pump as GenericDevices . IPumpFM ) . TurnOffOp ( ) : null )
2014-08-14 07:05:40 +00:00
. AddOperation ( StateMachine . ControlBoard . SetValvesOp ( null , inPath . Pump ) )
. EnterState ( ) ;
do
{
2014-07-28 07:54:35 +00:00
e = StateMachine . WaitRunDevsRunOps ( ) ;
if ( e . Contains ( Event . Error ) ) return Event . Error ;
}
2014-08-14 07:05:40 +00:00
while ( ! e . Contains ( Event . ValvesSet ) | | ( ( inPath . Pump is GenericDevices . IPumpFM ) & & ! e . Contains ( Event . TurnPumpOnOffDone ) ) ) ;
2014-07-28 07:54:35 +00:00
}
return Event . Done ;
}
2015-01-15 05:34:36 +00:00
/// <summary>
/// Opens a modeless dialog for entering data at the beginning of a procedure (serial numbers)
/// </summary>
/// <returns>false = OK, true = stop pressed</returns>
protected bool OpenCycleBeginForm ( )
{
IList < Event > e ;
GenericDevices . IDataEntry dataEntryCmpnt =
TbfComponents . FindComponent ( StateMachine . Procedure . DataEntry ) as GenericDevices . IDataEntry ;
if ( dataEntryCmpnt is IHasCycleBeginForm )
{
Bridge . OnActivity ( this , "Enter the water meter data" ) ;
State . Create ( "MainSeq : Enter begin data" )
. AddPermanentOperation ( ( dataEntryCmpnt as IHasCycleBeginForm ) . ShowCycleBeginFormOp ( WaterMeters ) )
. AddOperation ( checkUiOp )
. EnterState ( ) ;
e = StateMachine . WaitRunDevsRunOps ( ) ;
if ( e . Contains ( Event . UiCmdStop ) ) return true ;
}
return false ;
}
/// <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>
2015-06-25 02:45:04 +00:00
protected UIFlowControl WaitBeginFormClosed ( )
2015-01-15 05:34:36 +00:00
{
GenericDevices . IDataEntry dataEntryCmpnt =
TbfComponents . FindComponent ( StateMachine . Procedure . DataEntry ) as GenericDevices . IDataEntry ;
2015-03-01 09:19:00 +00:00
2015-06-25 02:45:04 +00:00
bool stopPressed = false ; /// true when STOP button pressed
2015-04-14 09:20:48 +00:00
if ( dataEntryCmpnt is IHasCycleBeginForm )
2015-01-15 05:34:36 +00:00
{
2015-03-01 09:19:00 +00:00
IList < Event > e ;
2015-04-14 09:20:48 +00:00
///
/// 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 ( e . Contains ( Event . UiCmdStop ) )
{
2015-06-25 02:45:04 +00:00
stopPressed = true ;
2015-04-14 09:20:48 +00:00
break ;
}
}
while ( ! e . Contains ( Event . ModelessFormClosed ) ) ;
}
2015-01-15 05:34:36 +00:00
2015-04-14 09:20:48 +00:00
///
2015-01-15 05:34:36 +00:00
/// A state without any dataEntryCmpnt operation so that Stop() when entering
/// this state and Start() when entering the following state are executed.
2015-04-14 09:20:48 +00:00
///
2015-03-08 14:13:50 +00:00
State . Create ( "MainSeq : Stopping modeless form" )
2015-01-15 05:34:36 +00:00
. AddOperation ( checkUiOp )
. RemovePermanentOperation ( dataEntryCmpnt as IOperation )
. EnterState ( ) ;
e = StateMachine . WaitRunDevsRunOps ( ) ;
2015-03-01 09:19:00 +00:00
2015-06-25 02:45:04 +00:00
if ( e . Contains ( Event . UiCmdStop ) ) { stopPressed = true ; }
2015-01-15 05:34:36 +00:00
}
2015-03-01 09:19:00 +00:00
2015-06-25 02:45:04 +00:00
return stopPressed ? UIFlowControl . Stop : UIFlowControl . Continue ;
2015-01-15 05:34:36 +00:00
}
2015-03-01 09:19:00 +00:00
/// <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 ;
2015-03-08 14:13:50 +00:00
if ( ( dataEntryCmpnt is IHasCycleBeginForm ) & &
( State . LastEvents . Contains ( Event . ModelessFormIsOpen ) | | State . LastEvents . Contains ( Event . ModelessFormClosed ) ) )
2015-03-01 09:19:00 +00:00
{
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.
2015-03-08 14:13:50 +00:00
State . Create ( "MainSeq : Stopping modeless form" )
2015-03-01 09:19:00 +00:00
. RemovePermanentOperation ( dataEntryCmpnt as IOperation )
. EnterState ( ) ;
do
{
e = StateMachine . WaitRunDevsRunOps ( ) ;
}
while ( e . Contains ( Event . ModelessFormIsOpen ) ) ;
}
}
2014-07-28 07:54:35 +00:00
/// <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 ;
2015-08-19 11:04:47 +00:00
2014-07-28 07:54:35 +00:00
State . Create ( "Read water meters" )
. AddOperation ( checkUiOp )
. AddOperations ( measureOperations )
2015-08-19 11:04:47 +00:00
. AddOperation ( readRegistersOp )
2014-09-10 10:05:49 +00:00
. AddOperation ( benchPath . TempIn . ReadTempOp ( ref tempIn ) )
. AddOperation ( benchPath . TempOut . ReadTempOp ( ref tempOut ) )
. AddOperation ( outPath . TempDiv . ReadTempOp ( ref tempDiv ) )
. AddOperation ( benchPath . PressIn . ReadPressureOp ( ref pressIn ) )
. AddOperation ( benchPath . PressOut . ReadPressureOp ( ref pressOut ) )
2014-07-28 07:54:35 +00:00
. AddOperation ( realTest ? outPath . Balance . ReadMassOp ( ref mass ) : null )
. AddOperation ( StateMachine . ControlBoard . UpdateTankWeightOp ( ) )
. AddOperation ( ( StateMachine . Ambient ! = null )
2015-08-19 11:04:47 +00:00
? StateMachine . Ambient . ReadAmbientOp ( airTemperature , airPressure , airHumidity )
: null )
//.AddOperation(realTest ? (ticTac ? queryEnd1 : queryEnd2) : null)
. AddOperation ( realTest ? queryEnd1 : null )
2014-09-10 10:05:49 +00:00
. AddOperation ( realTest ? processDataLoggingOp : null )
. EnterState ( ) ;
2014-07-28 07:54:35 +00:00
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 ;
}
2014-09-10 10:05:49 +00:00
while ( ( realTest & & ! e . Contains ( Event . BalanceDone ) ) | |
2014-07-28 07:54:35 +00:00
! 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>
2014-10-02 18:56:24 +00:00
/// <param name="cBrd">Control board component reference</param>
2014-07-28 07:54:35 +00:00
/// <param name="time">Current test time in [s]</param>
/// <param name="progress">Current progress 0 .. 1.0f</param>
/// <returns>Data for the UI</returns>
2014-10-02 18:56:24 +00:00
protected TestProgressEventArgs GetTestProgressData ( Entities . Test test , Entities . TestResult tstRslt , bool testRunning , Elde . ControlBoardDev cBrd , float time , float progress )
2014-07-28 07:54:35 +00:00
{
TestProgressEventArgs data = new TestProgressEventArgs ( ) ;
data . TestResult = tstRslt ;
2014-08-01 06:36:17 +00:00
refFreq . Val = cBrd . ReferenceFreq ;
data . FlowMtrFreq = refFreq ;
data . Flow = refFlow ;
2014-07-28 07:54:35 +00:00
data . Time = time ;
2014-08-01 06:36:17 +00:00
data . StartMass = startMass ;
data . Mass = mass ;
2014-07-28 07:54:35 +00:00
data . Progress = progress ;
float estCurrentTime = TimeEstimateBeginRpts + ( ( float ) ( tstRslt . RepetitionNr - 1 ) + progress ) * TimeEstimateOneTest ;
data . OveralProgress = estCurrentTime / TimeEstimateTotal ;
2014-08-01 06:36:17 +00:00
data . Tin = tempIn ;
data . Tout = tempOut ;
data . Tdiv = tempDiv ;
data . Pin = pressIn ;
data . Pout = pressOut ;
2014-07-31 15:04:09 +00:00
2014-08-01 06:36:17 +00:00
data . AmbientTemp = airTemperature ;
data . AmbientPressure = airPressure ;
data . AmbientHumidity = airHumidity ;
2014-10-02 18:56:24 +00:00
if ( testRunning )
{
/// Only when test is running
data . RefPulses = cBrd . EtPulses ( 0 ) ;
float refPulsesPerLtr = 1.0f / outPath . FlowMeter . LtrPerPulseCorrected ( refFlow . Val ) ; /// [pulse/ltr]
data . Volume = new FloatBox ( ) { Name = "Volume" , Format = "F1" , Val = Formulas . VolumeFromPulses ( data . RefPulses , refPulsesPerLtr ) } ;
2015-02-18 13:26:33 +00:00
int count = Math . Min ( Program . WMsCount , data . TestResult . Meters . Count ) ;
for ( int i = 0 ; i < count ; i + + )
2014-07-28 07:54:35 +00:00
{
2014-10-02 18:56:24 +00:00
if ( sensPath . RegisterReaders [ i ] ! = null )
{
2015-01-15 02:01:32 +00:00
data . TestResult . Meters [ i ] . PulsesMeter = WMPulses [ i ] ;
data . TestResult . Meters [ i ] . PulsesMaster = WMRefPulses [ i ] ;
data . TestResult . Meters [ i ] . VolumeMeter = Formulas . VolumeFromPulses ( WMPulses [ i ] , sensPath . RegisterReaders [ i ] . PulsesPerLtr ) ;
2015-08-16 16:05:35 +00:00
data . TestResult . Meters [ i ] . VolumeRef = Formulas . VolumeFromPulses ( WMRefPulses [ i ] , refPulsesPerLtr ) ;
data . TestResult . Meters [ i ] . VolumeErrorPct = Formulas . ErrorFromVolumes ( data . TestResult . Meters [ i ] . VolumeMeter , data . TestResult . Meters [ i ] . VolumeRef ) ;
2014-10-02 18:56:24 +00:00
}
}
}
else
{
data . Volume = new FloatBox ( ) { Name = "Volume" , Format = "F1" , Val = 0 } ;
}
2014-07-28 07:54:35 +00:00
return data ;
}
2015-02-02 10:38:42 +00:00
protected string TestResult2CsvLine ( Entities . TestResult tstRslt )
2014-07-28 07:54:35 +00:00
{
System . Text . StringBuilder sb = new System . Text . StringBuilder ( ) ;
sb . Append ( tstRslt . TimeStart ) ;
2015-02-02 17:09:05 +00:00
sb . Append ( ";" ) ; sb . Append ( tstRslt . BatchNr ) ;
2014-07-28 07:54:35 +00:00
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 ( " " ) ;
2015-02-20 10:37:09 +00:00
sb . Append ( ";" ) ; if ( outPath . Balance ! = null ) sb . Append ( outPath . Balance . Name ) ;
2014-07-28 07:54:35 +00:00
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)
2015-02-20 10:37:09 +00:00
sb . Append ( ";" ) ; if ( outPath . FlowMeter ! = null & & outPath . FlowMeter . LtrPerPulse ! = 0 )
{
sb . Append ( 1.0f / outPath . FlowMeter . LtrPerPulse ) ; /// Const.MID . konstanta eatlonu
}
2014-07-28 07:54:35 +00:00
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
2015-02-02 10:38:42 +00:00
sb . Append ( ";" ) ; sb . Append ( tstRslt . PulsesMaster ) ; /// Celkovy pocet et. pulzov skusky
2014-07-28 07:54:35 +00:00
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.
2015-08-24 13:16:14 +00:00
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeStart ) ; /// WM Vstart - pociatocny stav pri pevnom starte alebo zachyteny pri data streame
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeEnd ) ; /// WM Vend - konecny stav pri pevnom starte alebo zachyteny pri data streame
2014-07-28 07:54:35 +00:00
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeMeter ) ; /// WM Vmer - objem namerany vodomerom
2015-08-24 13:16:14 +00:00
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeRef ) ; /// WM Vref - objem namerany stanicou
2014-07-28 07:54:35 +00:00
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeErrorPct ) ; /// WM Emt - chyba vodomerom nameraneho objemu
2015-08-26 16:59:38 +00:00
sb . Append ( ";" ) ; sb . Append ( mtrRslt . CalibFactor ) ; /// iPerl calibration factor used during the test / ...
2014-07-28 07:54:35 +00:00
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
2015-08-26 16:59:38 +00:00
sb . Append ( ";" ) ; sb . Append ( mtrRslt . Q2Correction . ToString ( "F1" ) ) ; /// iPerl Q2 correction factor used during the test / AN value - hodnota z analogoveho prevodnika
2015-08-22 12:28:20 +00:00
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeStart ) ; /// WM Volume_start - pri datastreamovych hodnotach (alebo kamera)
sb . Append ( ";" ) ; sb . Append ( mtrRslt . TimeStart ) ; /// WM Time_start - ' ' -
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeEnd ) ; /// WM Volume_end - ' ' -
sb . Append ( ";" ) ; sb . Append ( mtrRslt . TimeEnd ) ; /// WM Time_end - ' ' -
2014-07-28 07:54:35 +00:00
}
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)
2015-08-22 12:28:20 +00:00
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeStart ) ; /// WM Volume_start - pri datastreamovych hodnotach (alebo kamera)
sb . Append ( ";" ) ; sb . Append ( mtrRslt . TimeStart ) ; /// WM Time_start - ' ' -
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeEnd ) ; /// WM Volume_end - ' ' -
sb . Append ( ";" ) ; sb . Append ( mtrRslt . TimeEnd ) ; /// WM Time_end - ' ' -
2014-07-28 07:54:35 +00:00
}
sb . Append ( ";" ) ;
return sb . ToString ( ) ;
}
}
}