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