/// /// Copyright (c) 2013-2019 Sensus Slovensko a.s. /// using System; using log4net; using TBF.BenchControl.GenericDevices; 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, totalRefPulses); } /// Set by the constructor readonly ControlBoardDev controlBoard; readonly IRegulValve regulValve; readonly int regulValveNr; readonly int regulValveStableTime; readonly int flowMeterNr; readonly double nominalFlow; readonly double maximalFlow; readonly double reqFlowLo; readonly double reqFlowHi; readonly int totalRefPulses; /// Number of reference pulses for a complete test readonly int massRefPulses; /// Number of reference pulses for mass collection readonly TestMethods testMethod; readonly int diverterNr; /// /// Internal states of this operation /// enum OpState { StartingTest, ResendCommand, TestStarted, ValveMoveToFlow, OpCompleted, } OpState opState; /// /// Starts the measurement. /// Events: MeasurementStarted /// /// Control board component reference /// Specifies used components /// Test method /// Test duration in number of reference flowmeter pulses /// Specifies filter for watermeter pulses public StartMeasurementOp(ControlBoardDev controlBoard, OutputPath outputPath, TestMethods method, double requiredFlowLo, double requiredFlowHi, int refPulses) : this(controlBoard, outputPath, method, requiredFlowLo, requiredFlowHi, refPulses, refPulses) { } /// /// Starts the measurement. /// Events: MeasurementStarted /// /// Control board component reference /// Specifies used components /// Test method /// Test duration in number of reference flowmeter pulses /// Specifies filter for watermeter pulses public StartMeasurementOp(ControlBoardDev controlBoard, OutputPath outputPath, TestMethods method, double requiredFlowLo, double requiredFlowHi, int totalRefPulses, int massRefPulses) { if (controlBoard == null) throw new ArgumentNullException("controlBoardDev"); this.controlBoard = controlBoard; if (outputPath.FlowMeter == null) throw new ArgumentNullException("Flow meter is missing"); flowMeterNr = outputPath.FlowMeter.Idx1; this.regulValve = outputPath.RegulValve; if (regulValve is Elde.RegulValve.RegulValve) { Elde.RegulValve.RegulValve rv = outputPath.RegulValve as Elde.RegulValve.RegulValve; regulValveNr = rv.Idx1; regulValveStableTime = rv.StableTime; } else if (regulValve is Elde.RegulValveCoax.RegulValve) { Elde.RegulValveCoax.RegulValve rv = outputPath.RegulValve as Elde.RegulValveCoax.RegulValve; regulValveNr = rv.Idx1; regulValveStableTime = rv.StableTime; } else if (!(regulValve is Dummy.RegulValve.RegulValve)) { throw new ArgumentNullException("Regulation valve is not compatible with Elde Control Board"); } if (outputPath.Diverter is Elde.Diverter.Diverter) { diverterNr = (outputPath.Diverter as Elde.Diverter.Diverter).DiverterNr; } nominalFlow = outputPath.FlowMeter.NominalFlow; maximalFlow = 1.25 * nominalFlow; this.reqFlowLo = requiredFlowLo; this.reqFlowHi = requiredFlowHi; this.totalRefPulses = totalRefPulses; this.massRefPulses = massRefPulses; this.testMethod = method; log.Debug(this.ToString()); } void SendStartCommand() { controlBoard.SyncRoute(); #if TURA_IPERL || TURA_IPERL_NEW || TURA_SPECIAL || BADGER_VELKA_TRAT || SLM_50 int flowMeterIdxAndDiv = flowMeterNr + 16 * diverterNr; #elif BADGER_STREDNA_TRAT int flowMeterIdxAndDiv = flowMeterNr + 8 * (diverterNr - 1); #elif FILIPINY_50 int flowMeterIdxAndDiv = flowMeterNr + ((flowMeterNr == 3) ? (4 * (diverterNr - 1)) : 0); #else int flowMeterIdxAndDiv = flowMeterNr; #endif log.InfoFormat("Start() : SendCommand(Cmd.Start, {0}, route, {1}, {1}, {2}, Stop.None)", flowMeterIdxAndDiv, totalRefPulses, testMethod); controlBoard.SendCommand(Command.Start, flowMeterIdxAndDiv, totalRefPulses, massRefPulses, testMethod, StopDevs.None); } /// Start this operation public void Start() { SendStartCommand(); opState = OpState.StartingTest; } /// Run this operation /// /// Event.FlowInDone or Event.FlowOutDone /// 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 ((statusP & StatusP.TestInProgress) != 0) { log.Info("Test started"); opState = OpState.TestStarted; } else { //opState = OpState.ResendCommand; } return Event.None; } else if (opState == OpState.ResendCommand) { SendStartCommand(); opState = OpState.StartingTest; return Event.None; } else if (opState == OpState.TestStarted) { /// /// Done once, issues an appropriate ValveMove(...) command /// if ((reqFlowLo >= reqFlowHi) || (reqFlowLo > maximalFlow) || (reqFlowHi <= 0)) { return Event.OpArgumentError; } log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}", regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi); double freqLo = 2000.0 * reqFlowLo / nominalFlow; double freqHi = 2000.0 * reqFlowHi / nominalFlow; if (regulValve.IsCoax) { controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency, new float[2] { (float)((freqLo + freqHi) / 2), (float)((freqLo + freqHi) / 2) }, regulValveStableTime); } else { controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency, new float[2] { (float)freqLo, (float)freqHi }, regulValveStableTime); } opState = OpState.OpCompleted; return Event.None; } else if (opState == OpState.OpCompleted) { return Event.MeasurementStarted; } return Event.None; } /// Stop this operation public void Stop() { } } }