tbf/TestBenchFramework/BenchControl/Elde/StartMeasurementOp.cs
2016-04-04 11:26:12 +02:00

172 lines
5.1 KiB
C#

///
/// Copyright (c) 2013-2015 Sensus Metering Systems
///
using System;
using log4net;
namespace TBF.BenchControl.Elde
{
public class StartMeasurementOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(StartMeasurementOp));
public override string ToString() { return string.Format("StartMeasurementOp(ref={0},pulses={1})", flowMeterNr, refPulses); }
/// Set by the constructor
readonly ControlBoardDev controlBoard;
readonly Elde.RegulValve.RegulValve regulValve;
readonly int regulValveNr;
readonly int flowMeterNr;
readonly float nominalFlow;
readonly float reqFlowLo;
readonly float reqFlowHi;
readonly float reqFlowAve;
readonly float pidCoef;
readonly int refPulses; /// Number of reference pulses for a complete test
readonly TestMethods testMethod;
readonly float filterConstant;
readonly int diverterNr;
bool started = false;
///
/// Internal states of this operation
///
enum OpState
{
StartingTest,
TestStarted,
ValveMoveToFlow,
OpCompleted,
}
OpState opState;
/// <summary>
/// Starts the measurement.
/// Events: MeasurementStarted
/// </summary>
/// <param name="controlBoard">Control board component reference</param>
/// <param name="outputPath">Specifies used components</param>
/// <param name="method">Test method</param>
/// <param name="refPulses">Test duration in number of reference flowmeter pulses</param>
/// <param name="filterConstant">Specifies filter for watermeter pulses</param>
public StartMeasurementOp(ControlBoardDev controlBoard, OutputPath outputPath, TestMethods method,
float requiredFlowLo, float requiredFlowHi,
int refPulses, float filterConstant)
{
if (controlBoard == null) throw new ArgumentNullException("controlBoardDev");
this.controlBoard = controlBoard;
if (outputPath.FlowMeter is Elde.FlowMeter.FlowMeter)
{
flowMeterNr = (outputPath.FlowMeter as Elde.FlowMeter.FlowMeter).Idx1;
}
else if (outputPath.FlowMeter is Elde.FlowMeterTwins.FlowMeter)
{
flowMeterNr = 0;
}
else
{
throw new ArgumentException("flowMeter is null or is not Elde");
}
regulValve = outputPath.RegulValve as Elde.RegulValve.RegulValve;
if (regulValve == null) throw new ArgumentNullException("regValve is null or not Elde");
regulValveNr = this.regulValve.Idx1;
if (outputPath.Diverter is Elde.Diverter.Diverter)
{
diverterNr = (outputPath.Diverter as Elde.Diverter.Diverter).AdcNr - 4;
}
nominalFlow = outputPath.FlowMeter.NominalFlow;
this.reqFlowLo = requiredFlowLo;
this.reqFlowHi = requiredFlowHi;
this.reqFlowAve = (reqFlowLo + reqFlowHi) / 2.0f;
this.pidCoef = outputPath.PidCoef;
this.refPulses = refPulses;
this.testMethod = method;
this.filterConstant = filterConstant;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start()
{
controlBoard.SyncRoute();
#if IPERLST || BADGER_VELKA_TRAT
int flowMeterIdxAndDiv = flowMeterNr + 16 * diverterNr;
#else
int flowMeterIdxAndDiv = flowMeterNr;
#endif
controlBoard.SendCommand(Command.Start, flowMeterIdxAndDiv, controlBoard.Route,
refPulses, refPulses, testMethod,
filterConstant, 20, 0, StopDevs.None);
opState = OpState.StartingTest;
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.FlowInDone or Event.FlowOutDone
/// </returns>
public Event Run()
{
if (opState == OpState.StartingTest)
{
StatusP statusP = controlBoard.StatusP;
log.DebugFormat("statusP = {0} {1} {2} {3}",
(((ulong)statusP >> 48) & 0xFFFF).ToString("X4"),
(((ulong)statusP >> 32) & 0xFFFF).ToString("X4"),
(((ulong)statusP >> 16) & 0xFFFF).ToString("X4"),
((ulong)statusP & 0xFFFF).ToString("X4"));
if (0 != (statusP & StatusP.TestInProgress))
{
log.Info("Test started");
opState = OpState.TestStarted;
}
return Event.None;
}
else if (opState == OpState.TestStarted)
{
///
/// Done once, issues an appropriate ValveMove(...) command
///
if (reqFlowLo >= reqFlowHi || reqFlowLo > nominalFlow || reqFlowHi <= 0)
{
return Event.OpArgumentError;
}
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi);
float freqLo = 2000.0f * reqFlowLo / nominalFlow;
float freqHi = 2000.0f * reqFlowHi / nominalFlow;
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
new float[2] { freqLo, freqHi },
regulValve.StableTime);
opState = OpState.OpCompleted;
return Event.None;
}
else if (opState == OpState.OpCompleted)
{
return Event.MeasurementStarted;
}
return Event.None;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}