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 ;
2015-12-04 16:17:20 +00:00
using Config.Entities ;
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>
2015-12-20 19:48:50 +00:00
public class SequenceBase : ProcessData
2014-07-28 07:54:35 +00:00
{
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.
///------------------------------------------------------------
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
///------------------------------------------------------------
2014-09-06 15:34:26 +00:00
public static int ReferenceFlowmetersCount ;
2016-02-10 18:24:10 +00:00
public static float [ ] CalibratedLtrPerRefPulse ; /// Reference flowmeter coefficients
2016-01-03 01:05:35 +00:00
public static double Qrise ;
public static double Qfall ;
2015-08-25 15:02:58 +00:00
2014-07-28 07:54:35 +00:00
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 ( )
{
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 ;
2016-01-19 16:38:09 +00:00
public static BenchControl . MetersPath sensPath ;
2015-12-04 16:17:20 +00:00
protected static TransitionSequence transitionBefore ;
protected static TransitionSequence transitionAfter ;
2014-07-28 07:54:35 +00:00
2014-07-31 20:17:38 +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
2015-12-04 16:17:20 +00:00
protected int [ ] WMPulses = new int [ Config . Data . WMsCount ] ;
protected int [ ] WMRefPulses = new int [ Config . Data . WMsCount ] ;
protected double [ ] WMTimes = new double [ Config . Data . WMsCount ] ;
2014-08-01 06:36:17 +00:00
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-12-20 19:48:50 +00:00
Utils . FloatToStr ( RefFlow . Val , 4 ) ,
2014-09-10 10:05:49 +00:00
StateMachine . ControlBoard . TTime . ToString ( "F3" ) ,
StateMachine . ControlBoard . EtPulses ( 0 ) ,
2016-02-10 18:24:10 +00:00
Formulas . VolumeFromPulses ( StateMachine . ControlBoard . EtPulses ( 0 ) , 1.0f / LtrPerRefPulse ) . ToString ( "F3" ) ,
2015-12-20 19:48:50 +00:00
TempIn ,
TempOut ,
TempDiv ,
PressureUp ,
PressureDown ,
Mass ,
2014-09-09 14:18:23 +00:00
"VolMM" ,
2015-12-20 19:48:50 +00:00
AmbientTemp ,
AmbientHumidity ,
AmbientPressure ,
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 )
2015-12-20 19:48:50 +00:00
. AddOperation ( Balance . ReadMassOp ( ref Mass ) )
2014-07-28 07:54:35 +00:00
. 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 ) ) ;
}
2015-12-20 19:48:50 +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 )
2015-12-20 19:48:50 +00:00
. AddOperation ( Balance . ReadMassOp ( ref Mass ) )
2014-07-28 07:54:35 +00:00
. 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 )
2015-12-20 19:48:50 +00:00
. AddOperation ( Balance . ReadMassOp ( ref Mass ) )
2014-07-28 07:54:35 +00:00
. 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 ,
2015-05-22 08:29:56 +00:00
BeforeTest ,
AfterTest ,
2016-02-07 21:27:32 +00:00
PurgeEnd ,
Stop ,
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>
2015-12-04 16:17:20 +00:00
protected Event Transition ( TransitionSequence transitionSequence , TransitionContext context )
2014-07-28 07:54:35 +00:00
{
2016-02-07 21:27:32 +00:00
bool stopFlag = false ;
bool errorFlag = false ;
2014-08-14 07:05:40 +00:00
IList < Event > e ;
string message ;
2016-02-07 21:27:32 +00:00
///
2014-08-14 07:05:40 +00:00
switch ( context )
{
case TransitionContext . PurgeBegin : message = Strings . Purging_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 ;
2016-02-07 21:27:32 +00:00
case TransitionContext . PurgeEnd : message = Strings . Emptying_i_n ; break ;
case TransitionContext . Stop : message = Strings . Test_stop_sequence_i_n ; break ;
default : message = "Transition" ; break ;
2014-08-14 07:05:40 +00:00
}
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
{
2016-02-07 21:27:32 +00:00
log . WarnFormat ( "Transition(null, context={0})" , context ) ;
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
///
2015-12-04 16:17:20 +00:00
IList < TransitionStep > transitionSteps = StateMachine . WtSession
2014-08-14 07:05:40 +00:00
. CreateQuery ( "FROM TransitionStep WHERE TransitionSequence = :tsId ORDER BY ItemNr" )
. SetParameter ( "tsId" , transitionSequence . Id )
2015-12-04 16:17:20 +00:00
. List < TransitionStep > ( ) ;
2014-08-14 07:05:40 +00:00
int stepsCount = transitionSteps . Count ;
2016-02-07 21:27:32 +00:00
log . WarnFormat ( "Transition(sequence={0} ({1} steps), context={2})" , transitionSequence . Name , stepsCount , context ) ;
2014-08-14 07:05:40 +00:00
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
{
2016-02-07 21:27:32 +00:00
if ( RegulValves [ i ] . IsCoax )
{
rvPosOps . Add ( RegulValves [ i ] . SetRegulValvePositionOp ( allRegvPositions [ i ] , allRegvPositions [ i ] , 60 ) ) ;
rvPosStr . Add ( string . Format ( "RV{0}.SetRegulValvePositionOp({1}, {1}, 60s)" , i , allRegvPositions [ i ] ) ) ;
}
else
{
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 ) ;
///
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
2016-02-07 21:27:32 +00:00
if ( ! stopFlag & & ! errorFlag )
2014-12-13 10:54:35 +00:00
{
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 )
{
2015-12-04 16:17:20 +00:00
case StepCondition . Scale1Empty :
2015-05-22 10:31:10 +00:00
endContitionFulfilled = ( StateMachine . Balance1 = = null ) | | StateMachine . Balance1 . IsEmpty ( ) ;
break ;
2015-12-04 16:17:20 +00:00
case StepCondition . Scale2Empty :
2015-05-22 10:31:10 +00:00
endContitionFulfilled = ( StateMachine . Balance2 = = null ) | | StateMachine . Balance2 . IsEmpty ( ) ;
break ;
2015-12-04 16:17:20 +00:00
case StepCondition . Scale3Empty :
2015-05-22 10:31:10 +00:00
endContitionFulfilled = ( StateMachine . Balance3 = = null ) | | StateMachine . Balance3 . IsEmpty ( ) ;
break ;
2015-12-04 16:17:20 +00:00
case StepCondition . AllScalesEmpty :
2015-05-22 10:31:10 +00:00
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
2016-02-07 21:27:32 +00:00
if ( errorFlag | | stopFlag ) break ;
2014-08-14 07:05:40 +00:00
}
2016-02-07 21:27:32 +00:00
Bridge . OnMessage ( this , string . Empty ) ; /// Clear the last step message
2014-08-14 07:05:40 +00:00
}
2016-02-07 21:27:32 +00:00
if ( context = = TransitionContext . Stop | | errorFlag | | stopFlag )
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 ( ) ;
2016-02-07 21:27:32 +00:00
if ( inPath ! = null )
2014-08-14 07:05:40 +00:00
{
2016-02-07 21:27:32 +00:00
State . Create ( "SequenceBase.Transition() : Test stopped -> Stopping the pump" )
. AddOperation ( checkUiOp )
. AddOperation ( StateMachine . ControlBoard . UpdateTankWeightOp ( ) )
. AddOperation ( ( inPath . Pump is GenericDevices . IPumpFM ) ? ( inPath . Pump as GenericDevices . IPumpFM ) . TurnOffOp ( ) : null )
. 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 ) | | ( ( inPath . Pump is GenericDevices . IPumpFM ) & & ! e . Contains ( Event . TurnPumpOnOffDone ) ) ) ;
2014-07-28 07:54:35 +00:00
}
}
2016-02-07 21:27:32 +00:00
if ( errorFlag )
return Event . Error ;
else if ( stopFlag )
return Event . UiCmdStop ;
else
return Event . Done ;
2014-07-28 07:54:35 +00:00
}
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" )
2016-01-04 16:55:39 +00:00
. AddPermanentOperation ( ( dataEntryCmpnt as IHasCycleBeginForm ) . ShowCycleBeginFormOp ( ) )
2015-01-15 05:34:36 +00:00
. 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 )
2015-12-20 19:48:50 +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 PressureUp ) )
. AddOperation ( benchPath . PressOut . ReadPressureOp ( ref PressureDown ) )
. AddOperation ( realTest ? outPath . Balance . ReadMassOp ( ref Mass ) : null )
2014-07-28 07:54:35 +00:00
. AddOperation ( StateMachine . ControlBoard . UpdateTankWeightOp ( ) )
. AddOperation ( ( StateMachine . Ambient ! = null )
2015-12-20 19:48:50 +00:00
? StateMachine . Ambient . ReadAmbientOp ( AmbientTemp , AmbientPressure , AmbientHumidity )
2015-08-19 11:04:47 +00:00
: 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 ;
}
2016-02-08 22:33:23 +00:00
protected string TestResult2CsvLine ( string testName , int part )
2014-07-28 07:54:35 +00:00
{
2016-01-03 01:05:35 +00:00
Results . Entities . TestRslt tstRslt = ProcessData . BatchRslts . GetTestRslt ( testName , part ) ;
2016-01-08 12:51:54 +00:00
if ( tstRslt = = null ) return string . Empty ;
return TestResult2CsvLine ( tstRslt ) ;
}
protected string TestResult2CsvLine ( Results . Entities . TestRslt tstRslt )
{
2014-07-28 07:54:35 +00:00
System . Text . StringBuilder sb = new System . Text . StringBuilder ( ) ;
2016-01-03 01:05:35 +00:00
sb . Append ( tstRslt . StartTime ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . Batch . BatchNr ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . Name ( ) ) ;
2014-07-28 07:54:35 +00:00
sb . Append ( ";" ) ; sb . Append ( tstRslt . RepetitionNr ) ;
sb . Append ( ";" ) ; sb . Append ( "1" ) ;
2016-01-03 01:05:35 +00:00
sb . Append ( ";" ) ; sb . Append ( tstRslt . Method ( ) ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . TargetVolume ( ) ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . Qfrom ( ) ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . Qto ( ) ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . ErrLimLo ( ) + tstRslt . Uncertainty ( ) ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . ErrLimHi ( ) - tstRslt . Uncertainty ( ) ) ;
2014-07-28 07:54:35 +00:00
sb . Append ( ";" ) ; sb . Append ( "0" ) ;
sb . Append ( ";" ) ; sb . Append ( "60" ) ;
sb . Append ( ";" ) ; sb . Append ( "0" ) ;
sb . Append ( ";" ) ; sb . Append ( "0" ) ;
2015-10-14 17:08:37 +00:00
sb . Append ( ";" ) ; sb . Append ( outPath . FlowMeter . Idx1 ) ;
2014-07-28 07:54:35 +00:00
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 ) ;
2016-01-03 01:05:35 +00:00
sb . Append ( ";" ) ; sb . Append ( tstRslt . PressUpAvrg ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . PressDownAvrg ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . PressUpStart ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . PressDownStart ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . PressUpEnd ) ;
sb . Append ( ";" ) ; sb . Append ( tstRslt . PressDownEnd ) ;
2014-07-28 07:54:35 +00:00
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 ) ;
2016-01-03 01:05:35 +00:00
sb . Append ( ";" ) ; sb . Append ( tstRslt . MassEnd - tstRslt . MassStart ) ;
2014-07-28 07:54:35 +00:00
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
2015-10-14 17:08:37 +00:00
sb . Append ( ";" ) ; sb . Append ( Program . LocalSettings . RealDensity ) ;
sb . Append ( ";" ) ; sb . Append ( Program . LocalSettings . AtTemperature ) ;
2014-07-28 07:54:35 +00:00
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)
2016-01-03 01:05:35 +00:00
sb . Append ( ";" ) ; sb . Append ( tstRslt . TestTime ) ; /// t
2014-07-28 07:54:35 +00:00
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
2016-01-03 01:05:35 +00:00
//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
2016-01-03 01:05:35 +00:00
for ( int i = 0 ; i < ProcessData . BatchRslts . WMPositionsCount ; i + + )
2014-07-28 07:54:35 +00:00
{
2016-01-03 01:05:35 +00:00
if ( ProcessData . BatchRslts . WaterMeters [ i ] ! = null )
{
if ( ! ProcessData . BatchRslts . WaterMeters [ i ] . Compound ( ) )
{
2016-01-08 12:51:54 +00:00
Results . Entities . MeterTestRslt mtrRslt = ProcessData . BatchRslts . GetMeterTestRslt ( tstRslt . Name ( ) , i , CompoundMeterId . Single ) ;
2016-01-03 01:05:35 +00:00
if ( mtrRslt ! = null )
{
sb . Append ( ";" ) ; sb . Append ( ProcessData . BatchRslts . WaterMeters [ i ] . SerialNr ) ; /// WM Ser.No.
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
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeMeter ) ; /// WM Vmer - objem namerany vodomerom
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeRef ) ; /// WM Vref - objem namerany stanicou
sb . Append ( ";" ) ; sb . Append ( mtrRslt . Error ) ; /// WM Emt - chyba vodomerom nameraneho objemu
#if IPERLST
sb . Append ( ";" ) ; sb . Append ( ProcessData . BatchRslts . WaterMeters [ i ] . CalibFactor ) ; /// iPerl calibration factor used during the test / ...
#else
sb . Append ( ";" ) ; sb . Append ( " " ) ; /// nechat prazdne
#endif
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 . TestTime ) ; /// WM Tmet - cas merania (obmedzany pri synchro skuske)
sb . Append ( ";" ) ; sb . Append ( mtrRslt . Passed ? "OK" : "NOK" ) ; /// WM Vysledok (t.j. ci je v hraniciach chyb) - OK/NOK
#if IPERLST
2016-01-08 15:57:37 +00:00
sb . Append ( ";" ) ; sb . Append ( mtrRslt . WaterMeter . Q2Correction . ToString ( "F1" ) ) ; /// iPerl Q2 correction factor used during the test / AN value - hodnota z analogoveho prevodnika
2016-01-03 01:05:35 +00:00
#else
sb . Append ( ";" ) ; sb . Append ( " " ) ; /// nechat prazdne
#endif
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeStart ) ; /// WM Volume_start - pri datastreamovych hodnotach (alebo kamera)
sb . Append ( ";" ) ; sb . Append ( mtrRslt . TimestampStart ) ; /// WM Time_start - ' ' -
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeEnd ) ; /// WM Volume_end - ' ' -
sb . Append ( ";" ) ; sb . Append ( mtrRslt . TimestampEnd ) ; /// WM Time_end - ' ' -
}
}
else
{
for ( byte b = ( byte ) CompoundMeterId . CompoundMain ; b < = ( byte ) CompoundMeterId . Compound ; b + + )
{
2016-01-08 12:51:54 +00:00
Results . Entities . MeterTestRslt mtrRslt = ProcessData . BatchRslts . GetMeterTestRslt ( tstRslt . Name ( ) , i , ( CompoundMeterId ) b ) ;
2016-01-03 01:05:35 +00:00
if ( mtrRslt ! = null )
{
sb . Append ( ";" ) ;
switch ( ( CompoundMeterId ) b )
{
case CompoundMeterId . CompoundMain :
sb . Append ( ProcessData . BatchRslts . WaterMeters [ i ] . SerialNr ) ;
break ;
case CompoundMeterId . CompoundAux :
2016-01-08 15:57:37 +00:00
sb . Append ( ProcessData . BatchRslts . WaterMeters [ i ] . SerialNrAux ) ;
2016-01-03 01:05:35 +00:00
break ;
case CompoundMeterId . Compound :
sb . Append ( ProcessData . BatchRslts . WaterMeters [ i ] . SerialNr ) ;
break ;
}
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 . Error ) ; /// 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 . TestTime ) ; /// WM Tmet - cas merania (obmedzany pri synchro skuske)
sb . Append ( ";" ) ; sb . Append ( mtrRslt . Passed ? "OK" : "NOK" ) ; /// WM Vysledok (t.j. ci je v hraniciach chyb) - OK/NOK
sb . Append ( ";" ) ; sb . Append ( " " ) ; /// WM AN value - hodnota z analogoveho prevodnika (teraz nic)
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeStart ) ; /// WM Volume_start - pri datastreamovych hodnotach (alebo kamera)
sb . Append ( ";" ) ; sb . Append ( mtrRslt . TimestampStart ) ; /// WM Time_start - ' ' -
sb . Append ( ";" ) ; sb . Append ( mtrRslt . VolumeEnd ) ; /// WM Volume_end - ' ' -
sb . Append ( ";" ) ; sb . Append ( mtrRslt . TimestampEnd ) ; /// WM Time_end - ' ' -
}
}
}
}
2014-07-28 07:54:35 +00:00
}
sb . Append ( ";" ) ;
return sb . ToString ( ) ;
}
2015-09-28 20:07:58 +00:00
/// <summary>
/// Create a simulated test result (single meter).
/// </summary>
/// <param name="test">Test to be simulated</param>
/// <returns>Test result</returns>
2016-01-03 01:05:35 +00:00
protected void MakeSimulated ( string testName , int repeats , int repetitionNr , int part , float errorPctBase )
2015-09-28 20:07:58 +00:00
{
2016-01-03 01:05:35 +00:00
string fullTestName = Results . Utils . GetTestName ( testName , repeats , repetitionNr ) ;
Results . Entities . TestRslt tstRslt = ProcessData . BatchRslts . GetTestRslt ( fullTestName , part ) ;
2015-09-28 20:07:58 +00:00
2016-01-03 01:05:35 +00:00
tstRslt . StartTime = DateTime . Now ;
tstRslt . EndTime = DateTime . Now ;
tstRslt . FlowSetTime = 10 ;
tstRslt . TestTime = tstRslt . TargetTime ( ) ;
/// TODO: Verify whether 'ltrPerRefPulse' is up to date
2016-02-10 18:24:10 +00:00
tstRslt . PulsesMaster = ( LtrPerRefPulse > 1E-6 ) ? ( tstRslt . TargetVolume ( ) / LtrPerRefPulse ) : 1 ;
tstRslt . ConstMaster = LtrPerRefPulse ;
2016-01-03 01:05:35 +00:00
tstRslt . MassStartRaw = 0 ;
tstRslt . MassStart = 0 ;
tstRslt . MassEndRaw = tstRslt . TargetVolume ( ) * Program . LocalSettings . RealDensity / 1000.0f ;
tstRslt . MassEnd = tstRslt . MassEndRaw ;
tstRslt . DensityIn = Program . LocalSettings . RealDensity ;
tstRslt . DensityOut = Program . LocalSettings . RealDensity ;
tstRslt . DensityDiv = Program . LocalSettings . RealDensity ;
tstRslt . Buoyancy = 0 ; /// TODO
2016-01-10 00:44:28 +00:00
tstRslt . FlowMass = 3600.0 * tstRslt . MassEnd / tstRslt . TargetTime ( ) ;
tstRslt . FlowVolume = 3.6 * tstRslt . TargetVolume ( ) / tstRslt . TargetTime ( ) ;
2016-01-03 01:05:35 +00:00
tstRslt . VolumeCTV = tstRslt . TargetVolume ( ) ;
tstRslt . VolumeMaster = tstRslt . TargetVolume ( ) ;
tstRslt . ErrorMaster = 0 ;
2015-09-28 20:07:58 +00:00
tstRslt . AmbientTempAve = 20.0f ;
tstRslt . AmbientPressAve = 1000.0f ;
tstRslt . AmbientHumiAve = 50.0f ;
2016-01-03 01:05:35 +00:00
tstRslt . PressUpStart = 1000.0f ;
tstRslt . PressDownStart = 1000.0f ;
2015-09-28 20:07:58 +00:00
tstRslt . TempInStart = 20.0f ;
tstRslt . TempOutStart = 20.0f ;
tstRslt . TempDivStart = 20.0f ;
2016-01-03 01:05:35 +00:00
tstRslt . PressUpEnd = 1000.0f ;
tstRslt . PressDownEnd = 1000.0f ;
2015-09-28 20:07:58 +00:00
tstRslt . TempInEnd = 20.0f ;
tstRslt . TempOutEnd = 20.0f ;
tstRslt . TempDivEnd = 20.0f ;
2016-01-03 01:05:35 +00:00
tstRslt . PressUpAvrg = 1000.0f ;
tstRslt . PressDownAvrg = 1000.0f ;
2015-09-28 20:07:58 +00:00
tstRslt . TempInAvrg = 20.0f ;
tstRslt . TempOutAvrg = 20.0f ;
tstRslt . TempDivAvrg = 20.0f ;
2016-01-03 01:05:35 +00:00
tstRslt . PressUpMin = 1000.0f ;
tstRslt . PressDownMin = 1000.0f ;
tstRslt . TempInMin = 20.0f ;
tstRslt . TempOutMin = 20.0f ;
tstRslt . TempDivMin = 20.0f ;
tstRslt . PressUpMax = 1000.0f ;
tstRslt . PressDownMax = 1000.0f ;
tstRslt . TempInMax = 20.0f ;
tstRslt . TempOutMax = 20.0f ;
tstRslt . TempDivMax = 20.0f ;
tstRslt . FlowMin = 0 ; /// TODO
tstRslt . FlowMax = 0 ; /// TODO
for ( int i = 0 ; i < BatchRslts . WMPositionsCount ; i + + )
2015-09-28 20:07:58 +00:00
{
2015-12-29 09:56:42 +00:00
float errorPct = errorPctBase + 0.05f * i ;
2016-01-03 01:05:35 +00:00
Results . Entities . MeterTestRslt meterRslt = ProcessData . BatchRslts . GetMeterTestRslt ( fullTestName , i , CompoundMeterId . Single ) ;
IRegisterReader regReader = sensPath . RegisterReaders [ i ] ;
2015-09-28 20:07:58 +00:00
2016-01-03 01:05:35 +00:00
if ( meterRslt ! = null & & regReader ! = null )
2015-09-28 20:07:58 +00:00
{
2016-01-03 01:05:35 +00:00
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 . Uncertainty ( ) )
& & ( errorPct < = tstRslt . ErrLimHi ( ) - tstRslt . Uncertainty ( ) ) ;
meterRslt . TestDone = true ;
2015-09-28 20:07:58 +00:00
}
}
2016-01-08 18:18:45 +00:00
tstRslt . Components = Results . Entities . Components
. UpdateList ( BatchRslts . ComponentsList ,
new Results . Entities . Components ( BenchInfo . TestBenchId ,
BenchInfo . TestBenchName ,
inPath . Pump ! = null ? inPath . Pump . Name : string . Empty ,
outPath . FlowMeter ! = null ? outPath . FlowMeter . Name : string . Empty ,
outPath . Balance ! = null ? outPath . Balance . Name : string . Empty ,
outPath . RegulValve ! = null ? outPath . RegulValve . Name : string . Empty ,
outPath . Diverter ! = null ? outPath . Diverter . Name : string . Empty ) ) ;
2015-09-28 20:07:58 +00:00
}
/// <summary>
/// Create a simulated test result (compound meter).
/// </summary>
/// <param name="test">Test to be simulated</param>
/// <returns>Test result</returns>
2016-01-03 01:05:35 +00:00
protected void MakeSimulatedCompound ( string testName , int repeats , int repetitionNr , int part , float errorPct , float mainPart )
2015-09-28 20:07:58 +00:00
{
2016-01-03 01:05:35 +00:00
string fullTestName = Results . Utils . GetTestName ( testName , repeats , repetitionNr ) ;
2015-09-28 20:07:58 +00:00
2016-01-03 01:05:35 +00:00
Results . Entities . TestRslt tstRslt = ProcessData . BatchRslts . GetTestRslt ( fullTestName , part ) ;
tstRslt . StartTime = DateTime . Now ;
tstRslt . EndTime = DateTime . Now ;
tstRslt . FlowSetTime = 10 ;
tstRslt . TestTime = tstRslt . TargetTime ( ) ;
/// TODO: Verify whether 'ltrPerRefPulse' is up to date
2016-02-10 18:24:10 +00:00
tstRslt . PulsesMaster = ( LtrPerRefPulse > 1E-6 ) ? ( tstRslt . TargetVolume ( ) / LtrPerRefPulse ) : 1 ;
tstRslt . ConstMaster = LtrPerRefPulse ;
2016-01-03 01:05:35 +00:00
tstRslt . MassStartRaw = 0 ;
tstRslt . MassStart = 0 ;
tstRslt . MassEndRaw = tstRslt . TargetVolume ( ) * Program . LocalSettings . RealDensity / 1000.0f ;
tstRslt . MassEnd = tstRslt . MassEndRaw ;
tstRslt . DensityIn = Program . LocalSettings . RealDensity ;
tstRslt . DensityOut = Program . LocalSettings . RealDensity ;
tstRslt . DensityDiv = Program . LocalSettings . RealDensity ;
tstRslt . Buoyancy = 0 ; /// TODO
tstRslt . FlowMass = tstRslt . MassEnd / tstRslt . TargetTime ( ) ;
tstRslt . FlowVolume = tstRslt . TargetVolume ( ) / tstRslt . TargetTime ( ) ;
tstRslt . VolumeCTV = tstRslt . TargetVolume ( ) ;
tstRslt . VolumeMaster = tstRslt . TargetVolume ( ) ;
tstRslt . ErrorMaster = 0 ;
2015-09-28 20:07:58 +00:00
tstRslt . AmbientTempAve = 20.0f ;
tstRslt . AmbientPressAve = 1000.0f ;
tstRslt . AmbientHumiAve = 50.0f ;
2016-01-03 01:05:35 +00:00
tstRslt . PressUpStart = 1000.0f ;
tstRslt . PressDownStart = 1000.0f ;
2015-09-28 20:07:58 +00:00
tstRslt . TempInStart = 20.0f ;
tstRslt . TempOutStart = 20.0f ;
tstRslt . TempDivStart = 20.0f ;
2016-01-03 01:05:35 +00:00
tstRslt . PressUpEnd = 1000.0f ;
tstRslt . PressDownEnd = 1000.0f ;
2015-09-28 20:07:58 +00:00
tstRslt . TempInEnd = 20.0f ;
tstRslt . TempOutEnd = 20.0f ;
tstRslt . TempDivEnd = 20.0f ;
2016-01-03 01:05:35 +00:00
tstRslt . PressUpAvrg = 1000.0f ;
tstRslt . PressDownAvrg = 1000.0f ;
2015-09-28 20:07:58 +00:00
tstRslt . TempInAvrg = 20.0f ;
tstRslt . TempOutAvrg = 20.0f ;
tstRslt . TempDivAvrg = 20.0f ;
2016-01-03 01:05:35 +00:00
tstRslt . PressUpMin = 1000.0f ;
tstRslt . PressDownMin = 1000.0f ;
tstRslt . TempInMin = 20.0f ;
tstRslt . TempOutMin = 20.0f ;
tstRslt . TempDivMin = 20.0f ;
tstRslt . PressUpMax = 1000.0f ;
tstRslt . PressDownMax = 1000.0f ;
tstRslt . TempInMax = 20.0f ;
tstRslt . TempOutMax = 20.0f ;
tstRslt . TempDivMax = 20.0f ;
tstRslt . FlowMin = 0 ; /// TODO
tstRslt . FlowMax = 0 ; /// TODO
for ( int i = 0 ; i < BatchRslts . WMPositionsCount ; i + + )
2015-09-28 20:07:58 +00:00
{
2016-01-03 01:05:35 +00:00
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 ) ;
2015-09-28 20:07:58 +00:00
2016-01-03 01:05:35 +00:00
double compoundVolume = tstRslt . TargetVolume ( ) * ( 1.0 + 0.01 * errorPct ) ;
double mainVolume = compoundVolume * mainPart ;
double auxVolume = compoundVolume * ( 1.0 - mainPart ) ;
2015-09-28 20:07:58 +00:00
2016-01-03 01:05:35 +00:00
for ( int isAux = 0 ; isAux < = 1 ; isAux + + ) /// 0=main, 1=aux
{
GenericDevices . IRegisterReader regReader = sensPath . RegisterReaders [ 2 * i + isAux ] ;
Results . Entities . MeterTestRslt meterRslt = ( isAux = = 0 ) ? mainRslt : auxRslt ;
2015-09-28 20:07:58 +00:00
2016-01-03 01:05:35 +00:00
if ( meterRslt ! = null & & regReader ! = null )
2015-09-28 20:07:58 +00:00
{
2016-01-03 01:05:35 +00:00
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 . Uncertainty ( ) )
& & ( errorPct < = tstRslt . ErrLimHi ( ) - tstRslt . Uncertainty ( ) ) ;
meterRslt . TestDone = true ;
2015-09-28 20:07:58 +00:00
}
}
2016-01-03 01:05:35 +00:00
compoundRslt . VolumeRef = tstRslt . VolumeCTV ; /// [l] must be calculated before main & aux. meter error
compoundRslt . VolumeMeter = mainRslt . VolumeMeter + auxRslt . VolumeMeter ;
2015-09-28 20:07:58 +00:00
2016-01-03 01:05:35 +00:00
compoundRslt . PulsesMaster = tstRslt . PulsesMaster ;
compoundRslt . TestTime = tstRslt . TargetTime ( ) ;
compoundRslt . Error = Formulas . ErrorFromVolumes ( compoundRslt . VolumeMeter , tstRslt . VolumeCTV ) ;
compoundRslt . Passed = ( compoundRslt . Error > = tstRslt . ErrLimLo ( ) + tstRslt . Uncertainty ( ) )
& & ( compoundRslt . Error < = tstRslt . ErrLimHi ( ) - tstRslt . Uncertainty ( ) ) ;
compoundRslt . TestDone = true ;
2015-09-28 20:07:58 +00:00
}
2016-01-08 18:18:45 +00:00
tstRslt . Components = Results . Entities . Components
. UpdateList ( BatchRslts . ComponentsList ,
new Results . Entities . Components ( BenchInfo . TestBenchId ,
BenchInfo . TestBenchName ,
inPath . Pump ! = null ? inPath . Pump . Name : string . Empty ,
outPath . FlowMeter ! = null ? outPath . FlowMeter . Name : string . Empty ,
outPath . Balance ! = null ? outPath . Balance . Name : string . Empty ,
outPath . RegulValve ! = null ? outPath . RegulValve . Name : string . Empty ,
outPath . Diverter ! = null ? outPath . Diverter . Name : string . Empty ) ) ;
2015-09-28 20:07:58 +00:00
}
2014-07-28 07:54:35 +00:00
}
}