tbf/TestBenchFramework/BenchControl/Elde/RegulValve/RegulValve.cs

175 lines
6.8 KiB
C#

///
/// Copyright (c) 2013-2016 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using log4net;
using TBF.BenchControl.Generic;
using TBF.Boxes;
namespace TBF.BenchControl.Elde.RegulValve
{
public class RegulValve : ComponentBase, IDevice, GenericDevices.IRegulValve
{
private static readonly ILog log = LogManager.GetLogger(typeof(RegulValve));
public override string ToString() { return string.Format("RegulValve({0})", Cfg.ToString(1)); }
public readonly RegulValveCfg RegulValveCfg;
IDictionary<float, float> dict;
public IDictionary<float, float> Dict { get { return dict; } }
public readonly ControlBoardDev ControlBoard;
public ValveCategory Category { get { return RegulValveCfg.Category; } }
public int Idx1 { get { return RegulValveCfg.Idx1; } } /// 1..7
public int DacValueClosed { get { return RegulValveCfg.AdcValueClosed; } } /// 0..1023
public int DacValueOpen { get { return RegulValveCfg.AdcValueOpen; } } /// 0..1023
public int StableTime { get { return RegulValveCfg.StableTime; } } /// 0=200ms, step=50ms, max. 1500ms (max.26)
public int FlowStableSec { get { return RegulValveCfg.FlowStableSec; } } /// 0..60 sec
///
public bool IsCoax { get { return false; } }
///
public float Position { get { return ControlBoard.RValvePosition(Idx1); } }
#region Configuration Change Handling
public static void OnCfgChange(object sender, CfgChangeArgs args)
{
if (CfgChangeHandler == null) return;
try { CfgChangeHandler(sender, args); }
catch (Exception e) { log.Error("CfgChangeHandler(...) failed", e); }
}
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
public override void StartChangeHandler()
{
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
{
RegulValveCfg tmpcfg = args.Cfg as RegulValveCfg;
if (tmpcfg != null && tmpcfg.Name.Equals(Name))
{
if (args.Command == CfgChangeCmd.CfgChange)
{
RegulValveCfg.StableTimeMs = tmpcfg.StableTimeMs;
RegulValveCfg.FlowStableSec = tmpcfg.FlowStableSec;
}
else if (args.Command == CfgChangeCmd.RVOpenStep)
{
ControlBoard.ValveMove(Idx1, RegulValveMode.PulseWidth, new float[2] { 2.0f, 2.0f }, StableTime);
// TODO: avoid conflicts
// TOTEST
}
else if (args.Command == CfgChangeCmd.RVCloseStep)
{
ControlBoard.ValveMove(Idx1, RegulValveMode.PulseWidth, new float[2] { -2.0f, -2.0f }, StableTime);
// TODO: avoid conflicts
// TOTEST
}
else if (args.Command == CfgChangeCmd.GetAdc1 || args.Command == CfgChangeCmd.GetAdc2)
{
int adc = (int)ControlBoard.AnalogInputRaw(Idx1 - 1, 0);
RegulValveCfgCtrl.OnCmdResponse(this, new CmdResponseArgs(args.Command, Idx1, adc));
}
}
};
}
#endregion Configuration Change Handling
public RegulValve()
{
}
public RegulValve(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
RegulValveCfg = cfg as RegulValveCfg;
ControlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (ControlBoard == null) throw new Exception("Cannot find " + Name + " parent");
this.dict = new Dictionary<float, float>();
if (Idx1 < ControlBoard.RegValveCalib.GetLength(0))
{
this.ControlBoard.RegValveCalib[Idx1 - 1, 0] = (uint)DacValueClosed;
this.ControlBoard.RegValveCalib[Idx1 - 1, 1] = (uint)DacValueOpen;
}
else
{
log.ErrorFormat("Unable to set {0} ADC levels: RegValveCalib array size={1}, RV Idx1={2}, RV AdcNr={3}",
Name, ControlBoard.RegValveCalib.GetLength(0), Idx1, Idx1 - 1);
}
log.Debug(this.ToString());
}
///
/// IDevice interface implementation
///
public void Initialize() { }
public void RunDeviceBefore()
{
int adc = (int)ControlBoard.AnalogInputRaw(Idx1 - 1, 0);
Handlers.OnAdcChanged(this, new CmdResponseArgs(CfgChangeCmd.GetAdc, Idx1, adc));
}
public void RunDeviceAfter() { }
public void StopDevice() { }
/// <summary>
/// Operation to set the water flow within tolerances
/// Events: Event.None, Event.FlowReached, Event.FlowTimeOut
/// </summary>
/// <param name="flowMeter">Flowmeter component</param>
/// <param name="requiredFlowLo">Lower limit of the required flow [m3/h]</param>
/// <param name="requiredFlowHi">Higher limit of the required flow [m3/h]</param>
/// <param name="pidCoef">PID coefficient (float)</param>
/// <param name="measuredFlow">Measured flow [m3/h]</param>
/// <param name="timeout">Timeout in [s]</param>
/// <returns>SetFlowOp instance</returns>
public IOperation SetFlowOp(GenericDevices.IFlowMeter flowMeter, float requiredFlowLo, float requiredFlowHi, float pidCoef, DoubleBox measuredFlow, int timeout)
{
return new SetFlowOp(ControlBoard, this, flowMeter, requiredFlowLo, requiredFlowHi, pidCoef, measuredFlow, RegulValveCfg.ReTryCommands, timeout);
}
/// <summary>
/// Operation to set the water flow within tolerances. Leave the measurement running.
/// Events: Event.None, Event.FlowReached, Event.FlowTimeOut
/// </summary>
/// <param name="flowMeter">Flowmeter component</param>
/// <param name="requiredFlowLo">Lower limit of the required flow [m3/h]</param>
/// <param name="requiredFlowHi">Higher limit of the required flow [m3/h]</param>
/// <param name="measuredFlow">Measured flow [m3/h]</param>
/// <param name="timeout">Timeout in [s]</param>
/// <returns>SetFlowOp instance</returns>
public IOperation SetFlowAndMeasureOp(GenericDevices.IFlowMeter flowMeter, float requiredFlowLo, float requiredFlowHi, float pidCoef, DoubleBox measuredFlow, int timeout, float filterConstant)
{
return new SetFlowOp(ControlBoard, this, flowMeter, requiredFlowLo, requiredFlowHi, pidCoef, measuredFlow, RegulValveCfg.ReTryCommands, timeout, true);
}
/// <summary>
/// Operation to set the regulation valve to a required position
/// Events: Event.None
/// </summary>
/// <param name="flowLo">Lower limit of the required valve position in [%]</param>
/// <param name="flowLo">Higher limit of the required valve position in [%]</param>
/// <returns>SetPositionOp instance</returns>
public IOperation SetRegulValvePositionOp(float pctLo, float pctHi, int timeoutMs)
{
return new SetRegulValvePositionOp(ControlBoard, this, pctLo, pctHi, timeoutMs);
}
public IOperation ChangeRegulValvePositionOp(float timePulseSec)
{
return new ChangeRegulValvePositionOp(ControlBoard, this, timePulseSec);
}
}
}