Initial version with config UI, w/o functionality, added to the project
This commit is contained in:
parent
0c9408ff64
commit
ab8aa61a29
22
TODO.txt
22
TODO.txt
@ -2,28 +2,26 @@
|
||||
- brat desatinnu bodku aj ciarku
|
||||
- dat zapamatanie polohy RV do Parametrov
|
||||
|
||||
BUGS HI – High importance
|
||||
- Transitions sa nedaju vymazat
|
||||
- kroky v transitions sa nedaju vymazat
|
||||
- END nefunguje vzdy
|
||||
|
||||
LO – Low importance
|
||||
MI – Medium importance
|
||||
- ked sa vazenie neukonci do 60sec, zobra 5 okamzitych merani
|
||||
- strankovanie vysledkov
|
||||
- poslat meno dokumentu PDF Creatorovi (job name?)
|
||||
- Summary results do adresara mesiaca/dna
|
||||
- editor s/n: Tab -> Enter, +/- = ukonci
|
||||
|
||||
2. MI Bolo by dobré mať count down pri zavodnení napriklad ako pri skuške
|
||||
4. HI chýba procedúra pre reguláciu vodomerov
|
||||
6. LI Zobrazovanie stavu čo sa deje bude treba modifikovať keď za pozrieme na obrazovku nevieme kde sa nachádzame
|
||||
7. MI Vysledky by mali byť v poradí Nazov skúšky, Flow, Error, Vet, Vetmet, Vmeter, Tupa, Tdwa, Pupa, Pdwa
|
||||
- Bolo by dobré mať count down pri zavodnení napriklad ako pri skuške
|
||||
- Zobrazovanie stavu čo sa deje bude treba modifikovať keď za pozrieme na obrazovku nevieme kde sa nachádzame
|
||||
|
||||
|
||||
= ked dam na DN100 zdruzeny test tak na konci testu pri prepisovani vysledkov padne:
|
||||
pouzije sa index vodomera 2 (treti), pricom su ale iba 2 vodomery
|
||||
= vyriesit znovunacitanie procedury po zmene
|
||||
|
||||
-----
|
||||
Nove:
|
||||
-----
|
||||
- nezobrazit DebugLevel Inherit pre componenty ktore nemaju parenta
|
||||
- ako osetrit nepodarenu detekciu (retry / continue) ?
|
||||
- RefPulses pre camery
|
||||
- Transitions sa nedaju vymazat
|
||||
|
||||
------
|
||||
Stare:
|
||||
|
||||
@ -16,7 +16,7 @@ namespace TBF.BenchControl.Elde.RegulValve
|
||||
IDictionary<float, float> dict;
|
||||
public IDictionary<float, float> Dict { get { return dict; } }
|
||||
|
||||
readonly ControlBoardDev controlBoard;
|
||||
public readonly ControlBoardDev ControlBoard;
|
||||
|
||||
public int Idx1 { get { return RegulValveCfg.Idx1; } } /// 1..7
|
||||
public int DacValueClosed { get { return RegulValveCfg.DacValueClosed; } } /// 0..1023
|
||||
@ -26,7 +26,7 @@ namespace TBF.BenchControl.Elde.RegulValve
|
||||
///
|
||||
public float Position
|
||||
{
|
||||
get { return controlBoard.RValvePosition(Idx1); }
|
||||
get { return ControlBoard.RValvePosition(Idx1); }
|
||||
}
|
||||
|
||||
|
||||
@ -55,19 +55,19 @@ namespace TBF.BenchControl.Elde.RegulValve
|
||||
}
|
||||
else if (args.Command == CfgChangeCmd.RVOpenStep)
|
||||
{
|
||||
controlBoard.ValveMove(Idx1, RegulValveMode.PulseWidth, new float[2] { 0.05f, 0.05f }, StableTime);
|
||||
ControlBoard.ValveMove(Idx1, RegulValveMode.PulseWidth, new float[2] { 0.05f, 0.05f }, StableTime);
|
||||
// TODO: avoid conflicts
|
||||
// TOTEST
|
||||
}
|
||||
else if (args.Command == CfgChangeCmd.RVCloseStep)
|
||||
{
|
||||
controlBoard.ValveMove(Idx1, RegulValveMode.PulseWidth, new float[2] { -0.05f, -0.05f }, StableTime);
|
||||
ControlBoard.ValveMove(Idx1, RegulValveMode.PulseWidth, new float[2] { -0.05f, -0.05f }, StableTime);
|
||||
// TODO: avoid conflicts
|
||||
// TOTEST
|
||||
}
|
||||
else if (args.Command == CfgChangeCmd.GetRVAdc1 || args.Command == CfgChangeCmd.GetRVAdc2)
|
||||
{
|
||||
int adc = (int)controlBoard.AnalogInputRaw(Idx1, 0);
|
||||
int adc = (int)ControlBoard.AnalogInputRaw(Idx1, 0);
|
||||
// TOTEST
|
||||
RegulValveCfgCtrl.OnCmdResponse(this, new CmdResponseArgs(args.Command, adc));
|
||||
}
|
||||
@ -83,13 +83,13 @@ namespace TBF.BenchControl.Elde.RegulValve
|
||||
{
|
||||
RegulValveCfg = cfg;
|
||||
|
||||
controlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
|
||||
if (controlBoard == null) throw new Exception("Cannot find " + Name + " parent");
|
||||
ControlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
|
||||
if (ControlBoard == null) throw new Exception("Cannot find " + Name + " parent");
|
||||
|
||||
this.dict = new Dictionary<float, float>();
|
||||
|
||||
this.controlBoard.RegValveCalib[Idx1 - 1, 0] = (uint)DacValueClosed;
|
||||
this.controlBoard.RegValveCalib[Idx1 - 1, 1] = (uint)DacValueOpen;
|
||||
this.ControlBoard.RegValveCalib[Idx1 - 1, 0] = (uint)DacValueClosed;
|
||||
this.ControlBoard.RegValveCalib[Idx1 - 1, 1] = (uint)DacValueOpen;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
@ -107,7 +107,7 @@ namespace TBF.BenchControl.Elde.RegulValve
|
||||
/// <returns>SetFlowOp instance</returns>
|
||||
public IOperation SetFlowOp(GenericDevices.IFlowMeter flowMeter, float requiredFlowLo, float requiredFlowHi, float pidCoef, FloatBox measuredFlow, int timeout)
|
||||
{
|
||||
return new SetFlowOp(controlBoard, this, flowMeter, requiredFlowLo, requiredFlowHi, pidCoef, measuredFlow, timeout);
|
||||
return new SetFlowOp(ControlBoard, this, flowMeter, requiredFlowLo, requiredFlowHi, pidCoef, measuredFlow, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -122,7 +122,7 @@ namespace TBF.BenchControl.Elde.RegulValve
|
||||
/// <returns>SetFlowOp instance</returns>
|
||||
public IOperation SetFlowAndMeasureOp(GenericDevices.IFlowMeter flowMeter, float requiredFlowLo, float requiredFlowHi, float pidCoef, FloatBox measuredFlow, int timeout, float filterConstant)
|
||||
{
|
||||
return new SetFlowOp(controlBoard, this, flowMeter, requiredFlowLo, requiredFlowHi, pidCoef, measuredFlow, timeout, true);
|
||||
return new SetFlowOp(ControlBoard, this, flowMeter, requiredFlowLo, requiredFlowHi, pidCoef, measuredFlow, timeout, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -134,12 +134,12 @@ namespace TBF.BenchControl.Elde.RegulValve
|
||||
/// <returns>SetPositionOp instance</returns>
|
||||
public IOperation SetRegulValvePositionOp(float pctLo, float pctHi, int timeoutMs)
|
||||
{
|
||||
return new SetRegulValvePositionOp(controlBoard, this, pctLo, pctHi, timeoutMs);
|
||||
return new SetRegulValvePositionOp(ControlBoard, this, pctLo, pctHi, timeoutMs);
|
||||
}
|
||||
|
||||
public IOperation ChangeRegulValvePositionOp(float timePulseSec)
|
||||
{
|
||||
return new ChangeRegulValvePositionOp(controlBoard, this, timePulseSec);
|
||||
return new ChangeRegulValvePositionOp(ControlBoard, this, timePulseSec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using TBF.BenchControl.GenericDevices;
|
||||
|
||||
namespace TBF.BenchControl.Elde.RegulValveTandem
|
||||
{
|
||||
public class ChangeRegulValvePositionOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(ChangeRegulValvePositionOp));
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("ChangeRegulValvePositionOp({0},{1}s)", regulValve.Name, timePulseSec.ToString("F2"));
|
||||
}
|
||||
|
||||
/// Set by the constructor
|
||||
readonly ControlBoardDev controlBoard;
|
||||
readonly RegulValveTandem regulValve;
|
||||
readonly int regulValveNr;
|
||||
readonly float timePulseSec;
|
||||
|
||||
/// <summary>
|
||||
/// Set required water flow.
|
||||
/// Events: FlowSet, FlowTimeOut
|
||||
/// </summary>
|
||||
/// <param name="ControlBoard">Control board device</param>
|
||||
/// <param name="regulValve">Regulation valve component</param>
|
||||
/// <param name="posLoPct">Lower limit of the position to be achieved</param>
|
||||
/// <param name="posHiPct">Upper limit of the position to be achieved</param>
|
||||
/// <param name="timeout">Timeout in sec. for setting the flow</param>
|
||||
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
|
||||
public ChangeRegulValvePositionOp(ControlBoardDev controlBoard, RegulValveTandem regulValve, float timePulseSec)
|
||||
{
|
||||
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
|
||||
this.controlBoard = controlBoard;
|
||||
|
||||
this.regulValve = regulValve as RegulValveTandem;
|
||||
if (regulValve == null) throw new ArgumentNullException("regValve is null or not Elde");
|
||||
this.regulValveNr = this.regulValve.Idx1;
|
||||
|
||||
this.timePulseSec = timePulseSec;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
float positionPct = controlBoard.RValvePosition(regulValveNr);
|
||||
log.WarnFormat("RV#={0}, actPos={1}%", regulValveNr, positionPct.ToString("F1"));
|
||||
|
||||
controlBoard.ValveMove(regulValveNr,
|
||||
RegulValveMode.PulseWidth,
|
||||
new float[2] { timePulseSec, timePulseSec },
|
||||
regulValve.StableTime);
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>
|
||||
/// Event.SetFlowDone
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
float positionPct = controlBoard.RValvePosition(regulValveNr);
|
||||
log.WarnFormat("RV#={0}, actPos={1}%", regulValveNr, positionPct.ToString("F1"));
|
||||
|
||||
return Event.PositionReached;
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using TBF.BenchControl.Generic;
|
||||
using TBF.Boxes;
|
||||
|
||||
namespace TBF.BenchControl.Elde.RegulValveTandem
|
||||
{
|
||||
public class RegulValveTandem : ComponentBase, GenericDevices.IRegulValve
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(RegulValveTandem));
|
||||
public override string ToString() { return string.Format("RegulValve({0})", Cfg.ToString(1)); }
|
||||
|
||||
public readonly RegulValveTandemCfg RegulValveTandemCfg;
|
||||
|
||||
IDictionary<float, float> dict;
|
||||
public IDictionary<float, float> Dict { get { return dict; } }
|
||||
|
||||
ControlBoardDev controlBoard { get { return regulValve.ControlBoard; } }
|
||||
|
||||
readonly RegulValve.RegulValve regulValve;
|
||||
readonly RegulValve.RegulValve fixedRV;
|
||||
|
||||
public int Idx1 { get { return regulValve.Idx1; } } /// 1..7
|
||||
public int DacValueClosed { get { return regulValve.DacValueClosed; } } /// 0..1023
|
||||
public int DacValueOpen { get { return regulValve.DacValueOpen; } } /// 0..1023
|
||||
///
|
||||
public int StableTime { get { return RegulValveTandemCfg.StableTime; } } /// 0=200ms, step=50ms, max. 1500ms (max.26)
|
||||
public int FlowStableSec { get { return RegulValveTandemCfg.FlowStableSec; } } /// 0..60 sec
|
||||
///
|
||||
public float Position
|
||||
{
|
||||
get { return controlBoard.RValvePosition(Idx1); }
|
||||
}
|
||||
|
||||
|
||||
public RegulValveTandem(RegulValveTandemCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
{
|
||||
RegulValveTandemCfg = cfg;
|
||||
|
||||
regulValve = (RegulValve.RegulValve)TbfComponents.FindComponent(RegulValveTandemCfg.RegulValveName, components);
|
||||
if (regulValve == null) throw new Exception("Cannot find regulation valve");
|
||||
|
||||
fixedRV = (RegulValve.RegulValve)TbfComponents.FindComponent(RegulValveTandemCfg.ParentName, components);
|
||||
if (fixedRV == null) throw new Exception("Cannot find fixed RV");
|
||||
|
||||
this.dict = new Dictionary<float, float>();
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
/// <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, FloatBox measuredFlow, int timeout)
|
||||
{
|
||||
return new SetFlowOp(controlBoard, this, flowMeter, requiredFlowLo, requiredFlowHi, pidCoef, measuredFlow, 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, FloatBox measuredFlow, int timeout, float filterConstant)
|
||||
{
|
||||
return new SetFlowOp(controlBoard, this, flowMeter, requiredFlowLo, requiredFlowHi, pidCoef, measuredFlow, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using TBF.BenchControl.Generic;
|
||||
|
||||
namespace TBF.BenchControl.Elde.RegulValveTandem
|
||||
{
|
||||
public class RegulValveTandemCfg : ComponentCfgBase, IChildComponentCfg
|
||||
{
|
||||
public IComponent GetComponent(IList<IComponent> components) { return new RegulValveTandem(this, components); }
|
||||
public IComponentCfgCtrl GetControl() { return new RegulValveTandemCfgCtrl(); }
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public string RegulValveName; /// Name of the regulation valve used to control the flow
|
||||
public string FixedRVName; /// Name of the regulation valve with a fixed position
|
||||
public int StableTimeMs; /// 200..1500 ms
|
||||
public bool StoredPositionReuse; /// true = store and re-use previous regulation valve positions
|
||||
public int FlowStableSec; /// 0..60 sec
|
||||
|
||||
/// <summary>
|
||||
/// Stabilization time when setting the flow: 0=200ms, step 50ms, max. 1.5 sec.
|
||||
/// </summary>
|
||||
public int StableTime { get { return (StableTimeMs - 200) / 50; } }
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
RegulValveTandemCfg()
|
||||
{
|
||||
Name = "RegulationValve";
|
||||
ParentName = string.Empty;
|
||||
|
||||
RegulValveName = "RV1";
|
||||
FixedRVName = "RV2";
|
||||
|
||||
StableTimeMs = 500;
|
||||
StoredPositionReuse = false;
|
||||
FlowStableSec = 5;
|
||||
}
|
||||
|
||||
public RegulValveTandemCfg(IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
this.Factory = factory;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return string.Format("Name={0}, ControlledRVName={1}, ADC-FixedRVName={2}, StabTm={3}ms, PosReuse={4}, FlowStable={5}s",
|
||||
Name,
|
||||
RegulValveName,
|
||||
FixedRVName,
|
||||
StableTimeMs,
|
||||
StoredPositionReuse,
|
||||
FlowStableSec);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,161 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using log4net;
|
||||
using TBF.BenchControl.Generic;
|
||||
|
||||
namespace TBF.BenchControl.Elde.RegulValveTandem
|
||||
{
|
||||
public partial class RegulValveTandemCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
static readonly ILog log = LogManager.GetLogger(typeof(RegulValveTandemCfgCtrl));
|
||||
|
||||
ComponentParametersDlg parent;
|
||||
|
||||
public bool ShowMore { get { return true; } }
|
||||
|
||||
RegulValveTandemCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as RegulValveTandemCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public RegulValveTandemCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void RegulationValveCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
parent = ParentForm as ComponentParametersDlg;
|
||||
if (parent == null) return;
|
||||
|
||||
if (parent.TbfComponents != null)
|
||||
{
|
||||
foreach (var cmpnt in parent.TbfComponents)
|
||||
{
|
||||
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.RegulValve.RegulValveFactory)
|
||||
{
|
||||
regulValveNameComboBox.Items.Add(cmpnt.Name);
|
||||
fixedRVNameComboBox.Items.Add(cmpnt.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Redraw();
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
nameTextBox.Text = config.Name;
|
||||
regulValveNameComboBox.Text = string.IsNullOrEmpty(config.RegulValveName) ? "---" : config.RegulValveName;
|
||||
fixedRVNameComboBox.Text = string.IsNullOrEmpty(config.FixedRVName) ? "---" : config.FixedRVName;
|
||||
stableTimeTextBox.Text = config.StableTimeMs.ToString();
|
||||
storedPosReuseCheckBox.Checked = config.StoredPositionReuse;
|
||||
flowStableSecTextBox.Text = config.FlowStableSec.ToString();
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
regulValveNameComboBox.Enabled = true;
|
||||
fixedRVNameComboBox.Enabled = true;
|
||||
stableTimeTextBox.Enabled = true;
|
||||
storedPosReuseCheckBox.Enabled = true;
|
||||
flowStableSecTextBox.Enabled = true;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
if (!regulValveNameComboBox.Items.Contains(regulValveNameComboBox.Text))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Invalid 'Regulation valve'";
|
||||
}
|
||||
|
||||
if (!fixedRVNameComboBox.Items.Contains(fixedRVNameComboBox.Text))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "Invalid 'Fixed reg. valve'";
|
||||
}
|
||||
|
||||
int dummy;
|
||||
if (!int.TryParse(stableTimeTextBox.Text, out dummy) || dummy < 200 || dummy > 1500 || (dummy % 50) != 0)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Stable time' should be between 200 and 1500 ms in 50 ms steps";
|
||||
}
|
||||
|
||||
if (!int.TryParse(flowStableSecTextBox.Text, out dummy) || dummy < 0 || dummy > 60)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Flow stable' should be between 0 and 60 sec";
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
///
|
||||
if (!config.Name.Equals(nameTextBox.Text))
|
||||
{
|
||||
config.Name = nameTextBox.Text;
|
||||
flags |= CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
|
||||
string str = regulValveNameComboBox.Text.Equals("---") ? string.Empty : regulValveNameComboBox.Text;
|
||||
if (!config.RegulValveName.Equals(str))
|
||||
{
|
||||
config.RegulValveName = str;
|
||||
flags |= CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
|
||||
str = fixedRVNameComboBox.Text.Equals("---") ? string.Empty : fixedRVNameComboBox.Text;
|
||||
if (!config.FixedRVName.Equals(str))
|
||||
{
|
||||
config.FixedRVName = str;
|
||||
flags |= CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
|
||||
int tmp = int.Parse(stableTimeTextBox.Text);
|
||||
if (config.StableTimeMs != tmp)
|
||||
{
|
||||
config.StableTimeMs = tmp;
|
||||
flags |= CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
|
||||
bool btmp = storedPosReuseCheckBox.Checked;
|
||||
if (config.StoredPositionReuse != btmp)
|
||||
{
|
||||
config.StoredPositionReuse = btmp;
|
||||
flags |= CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
|
||||
tmp = int.Parse(flowStableSecTextBox.Text);
|
||||
if (config.FlowStableSec != tmp)
|
||||
{
|
||||
config.FlowStableSec = tmp;
|
||||
flags |= CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
191
TestBenchFramework/BenchControl/Elde/RegulValveTandem/RegulValveTandemCfgCtrl.designer.cs
generated
Normal file
191
TestBenchFramework/BenchControl/Elde/RegulValveTandem/RegulValveTandemCfgCtrl.designer.cs
generated
Normal file
@ -0,0 +1,191 @@
|
||||
namespace TBF.BenchControl.Elde.RegulValveTandem
|
||||
{
|
||||
partial class RegulValveTandemCfgCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.regulValveNameLabel = new System.Windows.Forms.Label();
|
||||
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.regulValveNameComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.storedPosReuseCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.stableTimeTextBox = new System.Windows.Forms.TextBox();
|
||||
this.stableTimeLabel = new System.Windows.Forms.Label();
|
||||
this.flowStableSecTextBox = new System.Windows.Forms.TextBox();
|
||||
this.flowStableSecLabel = new System.Windows.Forms.Label();
|
||||
this.fixedRVNameComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.fixedRVNameLabel = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// regulValveNameLabel
|
||||
//
|
||||
this.regulValveNameLabel.AutoSize = true;
|
||||
this.regulValveNameLabel.Location = new System.Drawing.Point(28, 69);
|
||||
this.regulValveNameLabel.Name = "regulValveNameLabel";
|
||||
this.regulValveNameLabel.Size = new System.Drawing.Size(87, 13);
|
||||
this.regulValveNameLabel.TabIndex = 3;
|
||||
this.regulValveNameLabel.Text = "Regulation valve";
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(138, 41);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
|
||||
this.nameTextBox.TabIndex = 2;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(28, 44);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(35, 13);
|
||||
this.nameLabel.TabIndex = 1;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(135, 14);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(89, 13);
|
||||
this.classNameLabel.TabIndex = 0;
|
||||
this.classNameLabel.Text = "ComponentName";
|
||||
//
|
||||
// regulValveNameComboBox
|
||||
//
|
||||
this.regulValveNameComboBox.Enabled = false;
|
||||
this.regulValveNameComboBox.FormattingEnabled = true;
|
||||
this.regulValveNameComboBox.Location = new System.Drawing.Point(138, 66);
|
||||
this.regulValveNameComboBox.Name = "regulValveNameComboBox";
|
||||
this.regulValveNameComboBox.Size = new System.Drawing.Size(130, 21);
|
||||
this.regulValveNameComboBox.TabIndex = 4;
|
||||
//
|
||||
// storedPosReuseCheckBox
|
||||
//
|
||||
this.storedPosReuseCheckBox.AutoSize = true;
|
||||
this.storedPosReuseCheckBox.Enabled = false;
|
||||
this.storedPosReuseCheckBox.Location = new System.Drawing.Point(31, 170);
|
||||
this.storedPosReuseCheckBox.Name = "storedPosReuseCheckBox";
|
||||
this.storedPosReuseCheckBox.Size = new System.Drawing.Size(162, 17);
|
||||
this.storedPosReuseCheckBox.TabIndex = 13;
|
||||
this.storedPosReuseCheckBox.Text = "Enable stored position re-use";
|
||||
this.storedPosReuseCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// stableTimeTextBox
|
||||
//
|
||||
this.stableTimeTextBox.Enabled = false;
|
||||
this.stableTimeTextBox.Location = new System.Drawing.Point(138, 144);
|
||||
this.stableTimeTextBox.Name = "stableTimeTextBox";
|
||||
this.stableTimeTextBox.Size = new System.Drawing.Size(46, 20);
|
||||
this.stableTimeTextBox.TabIndex = 15;
|
||||
//
|
||||
// stableTimeLabel
|
||||
//
|
||||
this.stableTimeLabel.AutoSize = true;
|
||||
this.stableTimeLabel.Location = new System.Drawing.Point(28, 147);
|
||||
this.stableTimeLabel.Name = "stableTimeLabel";
|
||||
this.stableTimeLabel.Size = new System.Drawing.Size(81, 13);
|
||||
this.stableTimeLabel.TabIndex = 14;
|
||||
this.stableTimeLabel.Text = "Stable time [ms]";
|
||||
//
|
||||
// flowStableSecTextBox
|
||||
//
|
||||
this.flowStableSecTextBox.Enabled = false;
|
||||
this.flowStableSecTextBox.Location = new System.Drawing.Point(138, 193);
|
||||
this.flowStableSecTextBox.Name = "flowStableSecTextBox";
|
||||
this.flowStableSecTextBox.Size = new System.Drawing.Size(46, 20);
|
||||
this.flowStableSecTextBox.TabIndex = 17;
|
||||
//
|
||||
// flowStableSecLabel
|
||||
//
|
||||
this.flowStableSecLabel.AutoSize = true;
|
||||
this.flowStableSecLabel.Location = new System.Drawing.Point(28, 196);
|
||||
this.flowStableSecLabel.Name = "flowStableSecLabel";
|
||||
this.flowStableSecLabel.Size = new System.Drawing.Size(74, 13);
|
||||
this.flowStableSecLabel.TabIndex = 16;
|
||||
this.flowStableSecLabel.Text = "Flow stable [s]";
|
||||
//
|
||||
// fixedRVNameComboBox
|
||||
//
|
||||
this.fixedRVNameComboBox.Enabled = false;
|
||||
this.fixedRVNameComboBox.FormattingEnabled = true;
|
||||
this.fixedRVNameComboBox.Location = new System.Drawing.Point(138, 93);
|
||||
this.fixedRVNameComboBox.Name = "fixedRVNameComboBox";
|
||||
this.fixedRVNameComboBox.Size = new System.Drawing.Size(130, 21);
|
||||
this.fixedRVNameComboBox.TabIndex = 22;
|
||||
//
|
||||
// fixedRVNameLabel
|
||||
//
|
||||
this.fixedRVNameLabel.AutoSize = true;
|
||||
this.fixedRVNameLabel.Location = new System.Drawing.Point(28, 96);
|
||||
this.fixedRVNameLabel.Name = "fixedRVNameLabel";
|
||||
this.fixedRVNameLabel.Size = new System.Drawing.Size(82, 13);
|
||||
this.fixedRVNameLabel.TabIndex = 21;
|
||||
this.fixedRVNameLabel.Text = "Fixed reg. valve";
|
||||
//
|
||||
// RegulValveTandemCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.fixedRVNameComboBox);
|
||||
this.Controls.Add(this.fixedRVNameLabel);
|
||||
this.Controls.Add(this.flowStableSecTextBox);
|
||||
this.Controls.Add(this.flowStableSecLabel);
|
||||
this.Controls.Add(this.stableTimeTextBox);
|
||||
this.Controls.Add(this.stableTimeLabel);
|
||||
this.Controls.Add(this.storedPosReuseCheckBox);
|
||||
this.Controls.Add(this.regulValveNameComboBox);
|
||||
this.Controls.Add(this.regulValveNameLabel);
|
||||
this.Controls.Add(this.nameTextBox);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
this.Controls.Add(this.classNameLabel);
|
||||
this.Name = "RegulValveTandemCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(300, 500);
|
||||
this.Load += new System.EventHandler(this.RegulationValveCfgCtrl_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label regulValveNameLabel;
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
private System.Windows.Forms.ComboBox regulValveNameComboBox;
|
||||
private System.Windows.Forms.CheckBox storedPosReuseCheckBox;
|
||||
private System.Windows.Forms.TextBox stableTimeTextBox;
|
||||
private System.Windows.Forms.Label stableTimeLabel;
|
||||
private System.Windows.Forms.TextBox flowStableSecTextBox;
|
||||
private System.Windows.Forms.Label flowStableSecLabel;
|
||||
private System.Windows.Forms.ComboBox fixedRVNameComboBox;
|
||||
private System.Windows.Forms.Label fixedRVNameLabel;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@ -0,0 +1,18 @@
|
||||
using TBF.BenchControl.Generic;
|
||||
|
||||
namespace TBF.BenchControl.Elde.RegulValveTandem
|
||||
{
|
||||
public class RegulValveTandemFactory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return "RegulationValveTandem"; } }
|
||||
|
||||
public void ResetStaticProperties() { RegulValveTandem.ResetStaticProperties(); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new RegulValveTandemCfg(this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(typeof(RegulValveTandemCfg), component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,311 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using TBF.BenchControl.GenericDevices;
|
||||
using TBF.Boxes;
|
||||
|
||||
namespace TBF.BenchControl.Elde.RegulValveTandem
|
||||
{
|
||||
public class SetFlowOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(SetFlowOp));
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("SetFlowOp({0}, Qfrom={1}, Qto={2}, PID={3})", regulValve.Name, reqFlowLo, reqFlowHi, pidCoef);
|
||||
}
|
||||
|
||||
/// Set by the constructor
|
||||
readonly ControlBoardDev controlBoard;
|
||||
readonly Elde.RegulValve.RegulValve regulValve;
|
||||
readonly int regulValveNr;
|
||||
readonly int flowMeterNr;
|
||||
readonly float reqFlowLo;
|
||||
readonly float reqFlowHi;
|
||||
readonly float reqFlowAve;
|
||||
readonly float pidCoef;
|
||||
readonly int timeout;
|
||||
readonly bool leaveMeasurementRunning;
|
||||
|
||||
readonly float nominalFlow;
|
||||
|
||||
/// Process values
|
||||
enum OpState
|
||||
{
|
||||
Idle = 0,
|
||||
ValveMoveToPosition,
|
||||
SettingPosition,
|
||||
ValveMoveToFlow,
|
||||
SettingFlow,
|
||||
FlowReached,
|
||||
}
|
||||
OpState opState;
|
||||
|
||||
float targetPositionLo;
|
||||
float targetPositionHi;
|
||||
|
||||
int expireTime;
|
||||
FloatBox measuredFlow;
|
||||
int flowWithinBoundsTime;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set required water flow. Conditionally leave the measurement running.
|
||||
/// Events: FlowSet, FlowTimeOut
|
||||
/// </summary>
|
||||
/// <param name="ControlBoard">Control board device</param>
|
||||
/// <param name="regulValve">Regulation valve component</param>
|
||||
/// <param name="flowMeter">Flowmeter component</param>
|
||||
/// <param name="requiredFlowLo">Lower limit of the flow to be achieved in [m3/h]</param>
|
||||
/// <param name="requiredFlowHi">Upper limit of the flow to be achieved in [m3/h]</param>
|
||||
/// <param name="pidCoef">PID coefficient (float)</param>
|
||||
/// <param name="timeout">Timeout for the flow setting in [s]</param>
|
||||
/// <param name="leaveMeasurementRunning">true = Leave the measurement running after op. stop</param>
|
||||
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
|
||||
public SetFlowOp(ControlBoardDev controlBoard, IRegulValve regulValve, IFlowMeter flowMeter,
|
||||
float requiredFlowLo, float requiredFlowHi, float pidCoef, FloatBox measuredFlow,
|
||||
int timeout, bool leaveMeasurementRunning)
|
||||
{
|
||||
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
|
||||
this.controlBoard = controlBoard;
|
||||
|
||||
this.regulValve = regulValve as Elde.RegulValve.RegulValve;
|
||||
if (regulValve == null) throw new ArgumentNullException("regValve is null or not Elde");
|
||||
this.regulValveNr = this.regulValve.Idx1;
|
||||
|
||||
if (flowMeter is Elde.FlowMeter.FlowMeter)
|
||||
{
|
||||
this.flowMeterNr = (flowMeter as Elde.FlowMeter.FlowMeter).Idx1;
|
||||
}
|
||||
else if (flowMeter is Elde.FlowMeterTwins.FlowMeter)
|
||||
{
|
||||
this.flowMeterNr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentNullException("flowMeter is null or not Elde");
|
||||
}
|
||||
|
||||
nominalFlow = flowMeter.NominalFlow;
|
||||
|
||||
this.reqFlowLo = requiredFlowLo;
|
||||
this.reqFlowHi = requiredFlowHi;
|
||||
this.reqFlowAve = (reqFlowLo + reqFlowHi) / 2.0f;
|
||||
this.pidCoef = pidCoef;
|
||||
this.measuredFlow = measuredFlow;
|
||||
|
||||
this.timeout = timeout;
|
||||
|
||||
this.leaveMeasurementRunning = leaveMeasurementRunning;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set required water flow - Do not leave the measurement running.
|
||||
/// Events: FlowSet
|
||||
/// </summary>
|
||||
public SetFlowOp(ControlBoardDev controlBoard, IRegulValve regValve, IFlowMeter flowMeter,
|
||||
float requiredFlowLo, float requiredFlowHi, float pidCoef, FloatBox measuredFlow, int timeout)
|
||||
: this(controlBoard, regValve, flowMeter, requiredFlowLo, requiredFlowHi, pidCoef, measuredFlow, timeout, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set required water flow - No timeout.
|
||||
/// Events: FlowSet
|
||||
/// </summary>
|
||||
public SetFlowOp(ControlBoardDev controlBoard, IRegulValve regValve, IFlowMeter flowMeter,
|
||||
float requiredFlowLo, float requiredFlowHi, float pidCoef, FloatBox measuredFlow)
|
||||
: this(controlBoard, regValve, flowMeter, requiredFlowLo, pidCoef, requiredFlowHi, measuredFlow, int.MaxValue, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetch target position limits from the dictionary or return false
|
||||
/// </summary>
|
||||
/// <param name="avgReqFlow">Average of the flow targer range (input)</param>
|
||||
/// <param name="positionLo">Target valve position low limit (output)</param>
|
||||
/// <param name="positionHi">Target valve position high limit (output)</param>
|
||||
/// <returns>true when positions for the target flow are stored in the memory, otherwise return false</returns>
|
||||
bool FetchTargetPosition(float avgReqFlow, out float positionLo, out float positionHi)
|
||||
{
|
||||
float targetPosition;
|
||||
if (regulValve.Dict.TryGetValue(avgReqFlow, out targetPosition))
|
||||
{
|
||||
positionLo = Math.Max(targetPosition * 0.95f, 0.0f);
|
||||
positionHi = Math.Min(targetPosition * 1.05f, 100.0f);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
positionLo = 0.0f;
|
||||
positionHi = 0.0f;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void StoreTargetPosition(float avgReqFlow, float actPosition)
|
||||
{
|
||||
if (!regulValve.Dict.ContainsKey(reqFlowAve))
|
||||
{
|
||||
regulValve.Dict.Add(new KeyValuePair<float, float>(avgReqFlow, actPosition));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
flowWithinBoundsTime = 0;
|
||||
|
||||
if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi))
|
||||
{
|
||||
log.InfoFormat("Start(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}",
|
||||
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi, targetPositionLo, targetPositionHi);
|
||||
|
||||
opState = OpState.ValveMoveToPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.InfoFormat("Start(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
|
||||
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi);
|
||||
|
||||
opState = OpState.ValveMoveToFlow;
|
||||
}
|
||||
|
||||
expireTime = StateMachine.Time + timeout;
|
||||
if (expireTime < 0) expireTime = int.MaxValue;
|
||||
|
||||
TestMethods tm = 0;
|
||||
StopDevs sd = 0;
|
||||
// 'regulValve.RegulValveTandemCfg.PidCoef' replaced by a casted operation parameter 'pidCoef'
|
||||
controlBoard.SendCommand(Command.Start, flowMeterNr, controlBoard.Route, int.MaxValue, tm,
|
||||
0.0f, (int)pidCoef, 0, sd);
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>
|
||||
/// Event.None, Event.FlowReached, Event.RegulValveTimeOut, Event.OpArgumentError
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
float rvPosition = controlBoard.RValvePosition(regulValveNr);
|
||||
float flowMtrFreq = controlBoard.ReferenceFreq;
|
||||
float flow = flowMtrFreq * nominalFlow / 2000.0f;
|
||||
|
||||
if (measuredFlow != null) measuredFlow.Val = flow;
|
||||
|
||||
log.InfoFormat("Run(): rv#={0} pos={1}% freq={2} flow={3} opState={4}",
|
||||
regulValveNr, rvPosition.ToString("F1"), flowMtrFreq, flow, opState);
|
||||
|
||||
if (opState == OpState.ValveMoveToPosition)
|
||||
{
|
||||
///
|
||||
/// Done once, issues an appropriate ValveMove(...) command
|
||||
///
|
||||
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetPosition,
|
||||
new float[2] { targetPositionLo, targetPositionHi },
|
||||
regulValve.StableTime);
|
||||
|
||||
opState = OpState.SettingPosition;
|
||||
return Event.None;
|
||||
}
|
||||
else if (opState == OpState.SettingPosition)
|
||||
{
|
||||
///
|
||||
/// Repeated untill position is reached
|
||||
///
|
||||
if ((targetPositionLo <= rvPosition) && (rvPosition <= targetPositionHi))
|
||||
{
|
||||
opState = OpState.ValveMoveToFlow;
|
||||
}
|
||||
return Event.None;
|
||||
}
|
||||
else if (opState == OpState.ValveMoveToFlow)
|
||||
{
|
||||
///
|
||||
/// 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.SettingFlow;
|
||||
return Event.None;
|
||||
}
|
||||
else if (opState == OpState.SettingFlow)
|
||||
{
|
||||
///
|
||||
/// Repeated untill the required flow is reached
|
||||
///
|
||||
if ((reqFlowLo <= flow) && (flow <= reqFlowHi))
|
||||
{
|
||||
if (flowWithinBoundsTime++ >= regulValve.FlowStableSec)
|
||||
{
|
||||
if (regulValve.RegulValveCfg.StoredPositionReuse)
|
||||
{
|
||||
float storedPosition;
|
||||
if (regulValve.Dict.TryGetValue(reqFlowAve, out storedPosition))
|
||||
{
|
||||
/// update the stored valve position
|
||||
StoreTargetPosition(reqFlowAve, (rvPosition + storedPosition) / 2.0f);
|
||||
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% stored={3} <--- Updating a stored position",
|
||||
regulValveNr, reqFlowAve, rvPosition.ToString("F1"), storedPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// store the valve position
|
||||
StoreTargetPosition(reqFlowAve, rvPosition);
|
||||
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% <--- Storing a new position",
|
||||
regulValveNr, reqFlowAve, rvPosition.ToString("F1"));
|
||||
}
|
||||
}
|
||||
opState = OpState.FlowReached;
|
||||
return Event.FlowReached;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Event.None;
|
||||
}
|
||||
}
|
||||
else if (StateMachine.Time > expireTime)
|
||||
{
|
||||
return Event.RegulValveTimeOut;
|
||||
}
|
||||
else
|
||||
{
|
||||
flowWithinBoundsTime = 0;
|
||||
return Event.None;
|
||||
}
|
||||
}
|
||||
else /// opState == OpState.FlowReached
|
||||
{
|
||||
return Event.FlowReached;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
opState = OpState.Idle;
|
||||
|
||||
if (leaveMeasurementRunning) return;
|
||||
|
||||
/// Stop measurement
|
||||
TestMethods tm = 0;
|
||||
StopDevs sd = StopDevs.RegValveRegulation;
|
||||
controlBoard.SendCommand(Command.Stop, flowMeterNr, controlBoard.Route, 50000, tm,
|
||||
0.0f, 20, 0, sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using TBF.BenchControl.GenericDevices;
|
||||
|
||||
namespace TBF.BenchControl.Elde.RegulValveTandem
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/// Set by the constructor
|
||||
readonly ControlBoardDev controlBoard;
|
||||
readonly RegulValveTandem regulValve;
|
||||
readonly int regulValveNr;
|
||||
readonly float posLoPct;
|
||||
readonly float posHiPct;
|
||||
readonly int timeout;
|
||||
|
||||
/// Process values
|
||||
bool firstRun;
|
||||
int expireTime;
|
||||
bool positionReached;
|
||||
|
||||
/// <summary>
|
||||
/// Set required water flow.
|
||||
/// Events: FlowSet, FlowTimeOut
|
||||
/// </summary>
|
||||
/// <param name="ControlBoard">Control board device</param>
|
||||
/// <param name="regulValve">Regulation valve component</param>
|
||||
/// <param name="posLoPct">Lower limit of the position to be achieved</param>
|
||||
/// <param name="posHiPct">Upper limit of the position to be achieved</param>
|
||||
/// <param name="timeout">Timeout in sec. for setting the flow</param>
|
||||
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
|
||||
public SetRegulValvePositionOp(ControlBoardDev controlBoard, RegulValveTandem regulValve, float posLoPct, float posHiPct, int timeout)
|
||||
{
|
||||
if (controlBoard == null) throw new ArgumentNullException("ctrlBoard");
|
||||
this.controlBoard = controlBoard;
|
||||
|
||||
this.regulValve = regulValve as RegulValveTandem;
|
||||
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());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set required water flow - no timeout.
|
||||
/// Events: FlowSet
|
||||
/// </summary>
|
||||
public SetRegulValvePositionOp(ControlBoardDev controlBoard, RegulValveTandem regValve, float posLoPct, float posHiPct)
|
||||
: this(controlBoard, regValve, posLoPct, posHiPct, int.MaxValue)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
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"));
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>
|
||||
/// Event.None . . . . . . . busy adjusting position
|
||||
/// Event.PositionReached . . position reached
|
||||
/// Event.OpArgumentError . . invalid required position
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
if (firstRun)
|
||||
{
|
||||
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);
|
||||
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 (posLoPct >= posHiPct || posLoPct >= 100.0f || posHiPct <= 0)
|
||||
{
|
||||
return Event.OpArgumentError;
|
||||
}
|
||||
else if (posLoPct <= positionPct && positionPct <= posHiPct)
|
||||
{
|
||||
positionReached = true;
|
||||
return Event.PositionReached;
|
||||
}
|
||||
else if (StateMachine.Time > expireTime)
|
||||
{
|
||||
return Event.RegulValveTimeOut;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Event.None;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
controlBoard.ValveMove(regulValveNr,
|
||||
RegulValveMode.Stop,
|
||||
new float[2] { posLoPct, posHiPct },
|
||||
regulValve.StableTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,6 +40,7 @@ namespace TBF.BenchControl
|
||||
Factories.Add(new TestMethods.ReferenceFlowmeterCalibration.TestMethodFactory());
|
||||
Factories.Add(new Elde.RegisterReader.RegisterReaderFactory());
|
||||
Factories.Add(new Elde.RegulValve.RegulValveFactory());
|
||||
Factories.Add(new Elde.RegulValveTandem.RegulValveTandemFactory());
|
||||
Factories.Add(new ResultsPrinters.Munich.PrinterFactory());
|
||||
Factories.Add(new TestMethods.CameraRoiDetection.RoiDetectionFactory());
|
||||
Factories.Add(new Elde.TempMeter.TempMeterFactory());
|
||||
|
||||
@ -267,6 +267,18 @@
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\Elde\PumpWithFM\PumpFactory.cs" />
|
||||
<Compile Include="BenchControl\Elde\RegisterReader\RRProcedureParams.cs" />
|
||||
<Compile Include="BenchControl\Elde\RegulValveTandem\ChangeValvePositionOp.cs" />
|
||||
<Compile Include="BenchControl\Elde\RegulValveTandem\RegulValveTandem.cs" />
|
||||
<Compile Include="BenchControl\Elde\RegulValveTandem\RegulValveTandemCfg.cs" />
|
||||
<Compile Include="BenchControl\Elde\RegulValveTandem\RegulValveTandemCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\Elde\RegulValveTandem\RegulValveTandemCfgCtrl.designer.cs">
|
||||
<DependentUpon>RegulValveTandemCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\Elde\RegulValveTandem\RegulValveTandemFactory.cs" />
|
||||
<Compile Include="BenchControl\Elde\RegulValveTandem\SetFlowOp.cs" />
|
||||
<Compile Include="BenchControl\Elde\RegulValveTandem\SetRegulValvePositionOp.cs" />
|
||||
<Compile Include="BenchControl\Elde\RegulValve\ChangeValvePositionOp.cs" />
|
||||
<Compile Include="BenchControl\Elde\UpdateTankWeightOp.cs" />
|
||||
<Compile Include="BenchControl\Formulas.cs" />
|
||||
@ -1032,6 +1044,9 @@
|
||||
<EmbeddedResource Include="BenchControl\Elde\RegisterReader\RegisterReaderCfgCtrl.resx">
|
||||
<DependentUpon>RegisterReaderCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="BenchControl\Elde\RegulValveTandem\RegulValveTandemCfgCtrl.resx">
|
||||
<DependentUpon>RegulValveTandemCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="BenchControl\Elde\RegulValve\RegulValveCfgCtrl.resx">
|
||||
<DependentUpon>RegulValveCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user