/// /// Copyright (c) 2013-2015 Sensus Metering Systems /// using System; using System.Collections.Generic; using log4net; using TBF.BenchControl.GenericDevices; namespace TBF.BenchControl.Elde.RegulValve { public class SetRegulValvePositionOp : IOperation { private static readonly ILog log = LogManager.GetLogger(typeof(SetRegulValvePositionOp)); public override string ToString() { return string.Format("SetRegulValvePositionOp({0},{1},{2})", regulValve.Name, posLoPct, posHiPct); } const int CoaxValveNr = 7; /// Coax. valve has number 7 /// /// Internal states of this operation /// enum OpState { Idle = 0, MoveToPosition, /// Send commend to move to position CheckState, /// Check RV state by reading statos word MovingToPosition, /// Command passed OK, RV is moving to a position } OpState opState; /// Set by the constructor readonly ControlBoardDev controlBoard; readonly RegulValve regulValve; readonly int regulValveNr; readonly float posLoPct; readonly float posHiPct; readonly int timeout; /// Process values bool firstRun; int expireTime; bool positionReached; /// /// Set required water flow. /// Events: FlowSet, FlowTimeOut /// /// Control board device /// Regulation valve component /// Lower limit of the position to be achieved /// Upper limit of the position to be achieved /// Timeout in sec. for setting the flow /// Only Elde.Valve flow are used, other flow on the lists are ignored public SetRegulValvePositionOp(ControlBoardDev controlBoard, RegulValve regulValve, float posLoPct, float posHiPct, int timeout) { if (controlBoard == null) throw new ArgumentNullException("ctrlBoard"); this.controlBoard = controlBoard; this.regulValve = regulValve as RegulValve; if (regulValve == null) throw new ArgumentNullException("regValve is null or not Elde"); this.regulValveNr = this.regulValve.Idx1; this.posLoPct = posLoPct; this.posHiPct = posHiPct; this.timeout = timeout; log.Debug(this.ToString()); } /// /// Set required water flow - no timeout. /// Events: FlowSet /// public SetRegulValvePositionOp(ControlBoardDev controlBoard, RegulValve regValve, float posLoPct, float posHiPct) : this(controlBoard, regValve, posLoPct, posHiPct, int.MaxValue) { } /// Start this operation public void Start() { firstRun = true; positionReached = false; expireTime = StateMachine.Time + timeout; log.InfoFormat("Start(): RV#={0}, reqPosLo={1}%, reqPosHi={2}%", regulValveNr, posLoPct.ToString("F1"), posHiPct.ToString("F1")); opState = OpState.MoveToPosition; } /// Run this operation /// /// Event.None . . . . . . . busy adjusting position /// Event.PositionReached . . position reached /// Event.OpArgumentError . . invalid required position /// public Event Run() { if (opState == OpState.MoveToPosition) { if (posLoPct >= posHiPct || posLoPct > 100.0f || posHiPct < 0) { return Event.OpArgumentError; } firstRun = false; controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetPosition, new float[2] { posLoPct, posHiPct }, regulValve.StableTime); opState = OpState.CheckState; return Event.None; } if (positionReached) return Event.PositionReached; float positionPct = controlBoard.RValvePosition(regulValveNr); log.WarnFormat("Run(): RV#={0}, actPos={1}%", regulValveNr, positionPct.ToString("F1")); if (opState == OpState.CheckState) { if (regulValveNr == CoaxValveNr && ((ulong)controlBoard.StatusP & (ulong)StatusP.CoaxRegValveBusy) == 0) { opState = OpState.MoveToPosition; return Event.None; } else if (posLoPct <= positionPct && positionPct <= posHiPct) { positionReached = true; return Event.PositionReached; } else if ((regulValveNr < 6) && (controlBoard.RegulValveState(regulValveNr) != RegulValveState.DacValueRegul)) { opState = OpState.MoveToPosition; /// Resend move command again in the next run return Event.None; } else { opState = OpState.MovingToPosition; return Event.None; } } else if (StateMachine.Time > expireTime) { return Event.RegulValveTimeOut; } else if (opState == OpState.MovingToPosition) { if (posLoPct <= positionPct && positionPct <= posHiPct) { positionReached = true; return Event.PositionReached; } return Event.None; } return Event.None; } /// Stop this operation public void Stop() { } } }