Positions of reg. valves are defined in output path

This commit is contained in:
Milan Hanajik 2020-12-02 13:42:03 +01:00
parent d4ac2453b8
commit 6da5bd92ec
7 changed files with 220 additions and 83 deletions

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2017 Sensus Metering Systems
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@ -21,7 +21,7 @@ namespace Config.Entities
public virtual string Diverter { get; set; }
public virtual string TempDiv { get; set; }
public virtual string Scale { get; set; }
public virtual string EmptyTankValve { get; set; } /// Not used anywhere
public virtual string RegulValvesPct { get; set; } /// Positions of regulation valves in % separated by ';'
/// Valves
public virtual string ValvesOpen { get; set; }
@ -56,7 +56,7 @@ namespace Config.Entities
result.Diverter = Diverter;
result.TempDiv = TempDiv;
result.Scale = Scale;
result.EmptyTankValve = EmptyTankValve;
result.RegulValvesPct = RegulValvesPct;
result.ValvesOpen = ValvesOpen;
result.ValvesClose = ValvesClose;

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2015 Sensus Metering Systems
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
///
using FluentNHibernate.Mapping;
using Config.Entities;
@ -23,7 +23,8 @@ namespace Config.Mappings
Map(x => x.TempDiv);
Map(x => x.Scale)
.Column("Balance");
Map(x => x.EmptyTankValve);
Map(x => x.RegulValvesPct)
.Column("EmptyTankValve");
Map(x => x.ValvesOpen)
.CustomType("StringClob")
.CustomSqlType("varchar(8000)");

View File

@ -26,6 +26,7 @@ namespace TBF.BenchControl
public IValve StartValve3;
public bool InvertSV3;
public int LagSV3;
public float[] RegulValvesPct;
public IList<IValve> ValvesOpen;
public IList<IValve> ValvesClose;
@ -50,7 +51,7 @@ namespace TBF.BenchControl
Diverter = (IDiverter)TbfComponents.FindComponent(entity.Diverter, components);
TempDiv = (ITempMeter)TbfComponents.FindComponent(entity.TempDiv, components);
Scale = (IScaleOrTank)TbfComponents.FindComponent(entity.Scale, components);
RegulValvesPct = string.IsNullOrEmpty(entity.RegulValvesPct) ? new float[0] : Utils.GetRegulValvesPositions(entity.RegulValvesPct);
string[] svs = entity.StartValve != null ? entity.StartValve.Split(new char[] { '~' }) : new string[0];
int iTmp;
///

View File

@ -37,11 +37,12 @@ namespace TBF.BenchControl.Sequences
///------------------------------------------------------------
/// Global static variables set only once.
///------------------------------------------------------------
public static IList<IFlowMeter> FlowMeters; /// list of reference flowmeters
public static IList<IRegulValve> RegulValves; /// list of regulation valves
public static IList<IPumpFM> PumpsWithFM; /// list of FM controlled pumps
public static IList<IWaterMeter> WaterMeters; /// list of water meters
public static IList<ICamera> Cameras; /// list of cameras
public static IList<IFlowMeter> FlowMeters; /// list of reference flowmeters
public static IList<IRegulValve> RegulValves; /// list of regulation valves
public static IList<IRegulValve> OutputRegulValves; /// list of regulation valves
public static IList<IPumpFM> PumpsWithFM; /// list of FM controlled pumps
public static IList<IWaterMeter> WaterMeters; /// list of water meters
public static IList<ICamera> Cameras; /// list of cameras
///------------------------------------------------------------
/// Procedure related (static) variables.
@ -491,6 +492,35 @@ namespace TBF.BenchControl.Sequences
}
/// return SetRegValvePositionOp operations for RV-s with changed positions
IList<IOperation> GetRegValvePositioningOps(IList<IRegulValve> regValves, float[] regValvePositions)
{
IList<IOperation> rvPosOps = new List<IOperation>();
if (regValves != null && regValvePositions != null)
{
for (int i = 0; i < Math.Min(regValves.Count, regValvePositions.Length); i++)
{
if (regValvePositions[i] >= 0) /// Negative value means no position change
{
if (RegulValves[i].IsCoax)
{
rvPosOps.Add(regValves[i].SetRegulValvePositionOp(regValvePositions[i], regValvePositions[i], 60));
}
else
{
float lo = Math.Max(0, regValvePositions[i] - 3.0f);
float hi = Math.Min(100.0f, regValvePositions[i] + 3.0f);
rvPosOps.Add(regValves[i].SetRegulValvePositionOp(lo, hi, 60));
}
}
}
}
return rvPosOps;
}
/// <summary>
/// Executes steps of a transition sequence
/// </summary>
@ -612,30 +642,8 @@ namespace TBF.BenchControl.Sequences
}
}
/// Get new regulation valve positions,
float[] allRegvPositions = Utils.GetRegulValvesPositions(step.RegulValvesPct);
/// Prepare necessary SetRegValvePositionOp operations for RV-s with changed positions
IList<IOperation> rvPosOps = new List<IOperation>();
IList<string> rvPosStr = new List<string>();
for (int i = 0; i < allRegvPositions.Length; i++)
{
if (allRegvPositions[i] >= 0) /// Negative value means no position change
{
if (RegulValves[i].IsCoax)
{
rvPosOps.Add(RegulValves[i].SetRegulValvePositionOp(allRegvPositions[i], allRegvPositions[i], 60));
rvPosStr.Add(string.Format("RV{0}.SetRegulValvePositionOp({1}, {1}, 60s)", i, allRegvPositions[i]));
}
else
{
float lo = Math.Max(0, allRegvPositions[i] - 3.0f);
float hi = Math.Min(100.0f, allRegvPositions[i] + 3.0f);
rvPosOps.Add(RegulValves[i].SetRegulValvePositionOp(lo, hi, 60));
rvPosStr.Add(string.Format("RV{0}.SetRegulValvePositionOp({1}, {2}, 60s)", i, lo, hi));
}
}
}
/// Get regulation valve positioning operations
IList<IOperation> rvPosOps = GetRegValvePositioningOps(RegulValves, Utils.GetRegulValvesPositions(step.RegulValvesPct));
/// Max. one SetRegulValvePositionOp can be started or stopped in one sub-step.
/// Therefore SetRegulValvePositionOp operations are added and removed to subsequent states one by one.
@ -654,7 +662,6 @@ namespace TBF.BenchControl.Sequences
for (int j = 0; j <= i; j++)
{
stepStrt.AddOperation(rvPosOps[j]);
log.Debug(rvPosStr[j]);
}
lastStartedRV = i;
stepStrt.EnterState();
@ -676,7 +683,6 @@ namespace TBF.BenchControl.Sequences
for (int j = 0; j <= lastStartedRV; j++)
{
stepDelay.AddOperation(rvPosOps[j]);
log.Debug(rvPosStr[j]);
}
stepDelay.EnterState();
bool endContitionFulfilled = false;
@ -721,7 +727,6 @@ namespace TBF.BenchControl.Sequences
for (int j = first; j <= lastStartedRV; j++)
{
stepStop.AddOperation(rvPosOps[j]);
log.Debug(rvPosStr[j]);
}
stepStop.EnterState();
e = StateMachine.WaitRunDevsRunOps();
@ -764,47 +769,31 @@ namespace TBF.BenchControl.Sequences
while (!e.Contains(Event.ValvesSet));
}
}
else if (context == TransitionContext.BeforeTest)
else if (context == TransitionContext.BeforeTest && inPath != null && benchPath != null && outPath != null)
{
log.WarnFormat("Transition(any, context={0}), setting the required route before a test", context);
///
/// Always set route at the beginning of this test
///
if (inPath != null && benchPath != null && outPath != null)
{
State.Create("SequenceBase : Transition : TestStart - Default action")
.AddOperation(checkUiOp)
.AddOperation(StateMachine.ControlBoard
.SetValvesOp(GenericDevices.ValveBase.Merge(inPath.ValvesOpen, benchPath.ValvesOpen, outPath.ValvesOpen),
GenericDevices.ValveBase.Merge(inPath.ValvesClose, benchPath.ValvesClose, outPath.ValvesClose)))
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) return Event.Error;
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
}
while (e.Contains(Event.ValvesBusy));
}
Event evnt = PerformSteps(GenericDevices.ValveBase.Merge(inPath.ValvesOpen, benchPath.ValvesOpen, outPath.ValvesOpen),
GenericDevices.ValveBase.Merge(inPath.ValvesClose, benchPath.ValvesClose, outPath.ValvesClose),
GetRegValvePositioningOps(OutputRegulValves, outPath.RegulValvesPct),
"SequenceBase : Transition : TestStart - Default action");
if (evnt == Event.Error || evnt == Event.UiCmdStop) return evnt;
}
else if ((context == TransitionContext.AfterTestWithOverlap) && (nextInPath != null) && (nextBenchPath != null) && (nextOutPath != null))
else if (context == TransitionContext.AfterTestWithOverlap && nextInPath != null && nextBenchPath != null && nextOutPath != null)
{
log.WarnFormat("Transition(., context={0}), overlapped action (next flow regulation)", context);
///
/// Set route for the next test
State.Create("SequenceBase : AfterTestWithOverlap : Default action")
.AddOperation(checkUiOp)
.AddOperation(StateMachine.ControlBoard
.SetValvesOp(GenericDevices.ValveBase.Merge(nextInPath.ValvesOpen, nextBenchPath.ValvesOpen, nextOutPath.ValvesOpen),
GenericDevices.ValveBase.Merge(nextInPath.ValvesClose, nextBenchPath.ValvesClose, nextOutPath.ValvesClose)))
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) return Event.Error;
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
}
while (e.Contains(Event.ValvesBusy));
///
Event evnt = PerformSteps(GenericDevices.ValveBase.Merge(nextInPath.ValvesOpen, nextBenchPath.ValvesOpen, nextOutPath.ValvesOpen),
GenericDevices.ValveBase.Merge(nextInPath.ValvesClose, nextBenchPath.ValvesClose, nextOutPath.ValvesClose),
GetRegValvePositioningOps(OutputRegulValves, outPath.RegulValvesPct),
"SequenceBase : AfterTestWithOverlap : Default action");
/// Set PID coefficient, etc.
int[] filters = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
@ -844,6 +833,68 @@ namespace TBF.BenchControl.Sequences
}
Event PerformSteps(IList<IValve> valvesToOpen, IList<IValve> valvesToClose, IList<IOperation> rvPosOps, string stateTitle)
{
bool stopFlag = false;
bool errorFlag = false;
IList<Event> e;
int lastStartedRV = -1;
for (int i = 0; i < rvPosOps.Count; i++)
{
State stepStrt = State.Create(stateTitle)
.AddOperation(checkUiOp)
.AddOperation(StateMachine.ControlBoard.SetValvesOp(valvesToOpen, valvesToClose));
for (int j = 0; j <= i; j++) stepStrt.AddOperation(rvPosOps[j]);
lastStartedRV = i;
stepStrt.EnterState();
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error) || e.Contains(Event.RegulValveTimeOut)) { errorFlag = true; break; }
if (TestAndLogUiCmdStop(e)) { stopFlag = true; break; }
}
/// Max. valaue of lastStartedRV after exitting the loop is (rvPosOps.Count - 1)
if (!stopFlag && !errorFlag)
{
State stepRegul = State.Create(stateTitle)
.AddOperation(checkUiOp)
.AddOperation(StateMachine.ControlBoard.SetValvesOp(valvesToOpen, valvesToClose));
for (int j = 0; j <= lastStartedRV; j++) stepRegul.AddOperation(rvPosOps[j]);
stepRegul.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error) || e.Contains(Event.RegulValveTimeOut)) { errorFlag = true; break; }
if (TestAndLogUiCmdStop(e)) { stopFlag = true; break; }
}
while (e.Contains(Event.ValvesBusy) && !e.Contains(Event.Next));
}
for (int first = 1; first <= lastStartedRV; first++)
{
State stepStop = State.Create(stateTitle)
.AddOperation(checkUiOp)
.AddOperation(StateMachine.ControlBoard.SetValvesOp(valvesToOpen, valvesToClose));
for (int j = first; j <= lastStartedRV; j++) stepStop.AddOperation(rvPosOps[j]);
stepStop.EnterState();
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error) || e.Contains(Event.RegulValveTimeOut)) { errorFlag = true; }
if (TestAndLogUiCmdStop(e)) { stopFlag = true; }
}
if (stopFlag) return Event.UiCmdStop;
if (errorFlag) return Event.Error;
return Event.Done;
}
/// <summary>
/// Opens a modeless dialog for entering data at the beginning of a procedure (serial numbers)
/// </summary>

View File

@ -223,6 +223,7 @@ namespace TBF.BenchControl
ProcessData.IperlHeads = new List<TestMethods.iPerlCommunication.iPerlHead.IperlHead>();
SequenceBase.FlowMeters = new List<IFlowMeter>();
SequenceBase.RegulValves = new List<IRegulValve>();
SequenceBase.OutputRegulValves = new List<IRegulValve>();
SequenceBase.PumpsWithFM = new List<IPumpFM>();
SequenceBase.WaterMeters = new List<IWaterMeter>();
SequenceBase.Cameras = new List<ICamera>();
@ -245,7 +246,9 @@ namespace TBF.BenchControl
if (cmpnt is IFlowMeter) SequenceBase.FlowMeters.Add(cmpnt as IFlowMeter);
if ((cmpnt is IRegulValve) && !(cmpnt is BenchControl.Elde.RegulValveTandem.RegulValveTandem))
{
SequenceBase.RegulValves.Add(cmpnt as IRegulValve);
IRegulValve rv = cmpnt as IRegulValve;
SequenceBase.RegulValves.Add(rv);
if (rv.Category == ValveCategory.Output || rv.Category == ValveCategory.All) SequenceBase.OutputRegulValves.Add(rv);
}
if (cmpnt is IPumpFM && !(cmpnt is Elde.PumpTandem.Pump))
{

View File

@ -34,6 +34,7 @@ namespace TBF.UI.Bench.Paths
public IList<BenchControl.Generic.IComponent> TbfComponents;
public IList<IValve> Valves;
public IList<IRegulValve> FeedingRegulValves;
public IList<IRegulValve> OutputRegulValves;
public ISession Session; /// One common DB session passed also to the controls inside tab pages
public IList<Procedure> Procedures;
public IList<Test> Tests;
@ -78,12 +79,24 @@ namespace TBF.UI.Bench.Paths
/// Find all feeding regulation valves
FeedingRegulValves = new List<IRegulValve>();
OutputRegulValves = new List<IRegulValve>();
foreach (var cmpnt in TbfComponents)
{
IRegulValve regValve = cmpnt as IRegulValve;
if (regValve != null && (regValve.Category == TBF.BenchControl.ValveCategory.Feeding || regValve.Category == TBF.BenchControl.ValveCategory.All))
if (regValve != null)
{
FeedingRegulValves.Add(regValve);
switch (regValve.Category)
{
case TBF.BenchControl.ValveCategory.Feeding:
FeedingRegulValves.Add(regValve);
break;
case TBF.BenchControl.ValveCategory.Output:
OutputRegulValves.Add(regValve);
break;
case TBF.BenchControl.ValveCategory.All:
OutputRegulValves.Add(regValve);
break;
}
}
}

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2017 Sensus Slovensko a.s.
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@ -12,6 +12,7 @@ using TBF.BenchControl;
using TBF.BenchControl.GenericDevices;
using TBF.Resources;
using TBF.UI.Shared;
using System.Text;
namespace TBF.UI.Bench.Paths
{
@ -45,6 +46,9 @@ namespace TBF.UI.Bench.Paths
}
readonly int fixedColumnsCount = (int)Column.FixedColumnsCount;
int valvescount;
int regulValvesCount;
PathsDlg parent;
Control parentControl;
Control[] editors;
@ -90,15 +94,26 @@ namespace TBF.UI.Bench.Paths
Columns.Add(string.Format("{0} 3", Strings.StartValve), (ls.OutputColumnCount > 14) ? ls.OutputColumnWidths[14] : 80 * parent.Dpi / Constants.Dpi100pct);
Columns.Add(string.Format("Inv.SV3"), (ls.OutputColumnCount > 15) ? ls.OutputColumnWidths[15] : 80 * parent.Dpi / Constants.Dpi100pct);
Columns.Add(string.Format("Lag SV3"), (ls.OutputColumnCount > 16) ? ls.OutputColumnWidths[16] : 80 * parent.Dpi / Constants.Dpi100pct);
valvescount = 0;
regulValvesCount = 0;
int clmn = (int)Column.FixedColumnsCount;
///
foreach (var vlv in parent.Valves)
{
if (vlv.Category == ValveCategory.All || vlv.Category == ValveCategory.Output)
{
Columns.Add(vlv.Cfg.Name, (ls.OutputColumnCount > clmn) ? ls.OutputColumnWidths[clmn] : 50 * parent.Dpi / Constants.Dpi100pct);
clmn++;
valvescount++;
}
}
foreach (var rvlv in parent.OutputRegulValves)
{
Columns.Add(rvlv.Cfg.Name + " [%]", (ls.OutputColumnCount > clmn) ? ls.OutputColumnWidths[clmn] : 55 * parent.Dpi / Constants.Dpi100pct);
clmn++;
regulValvesCount++;
}
/// Prepare fixed columns combo boxes
ComboBox flowMeterComboBox = new ComboBox();
@ -143,7 +158,7 @@ namespace TBF.UI.Bench.Paths
}
}
editors = new Control[fixedColumnsCount + 64];
editors = new Control[fixedColumnsCount + valvescount + regulValvesCount];
///
editors[(int)Column.Name] = new TextBox(); /// Name
editors[(int)Column.Qfrom] = new TextBox(); /// Q_from
@ -163,7 +178,7 @@ namespace TBF.UI.Bench.Paths
editors[(int)Column.InvertSV3] = invertSV3ComboBox;
editors[(int)Column.LagSV3] = lagSV3TextBox;
/// Prepare valve combo-boxes (max. 64 valves)
for (int i = 0; i < 64; i++)
for (int i = 0; i < valvescount; i++)
{
ComboBox cb = new ComboBox();
cb.Items.Add("---");
@ -171,7 +186,19 @@ namespace TBF.UI.Bench.Paths
cb.Items.Add(Strings.close);
editors[fixedColumnsCount + i] = cb;
}
///
/// Prepare regul. valve combo-boxes
for (int i = 0; i < regulValvesCount; i++)
{
ComboBox cb = new ComboBox();
cb.Items.Add("---");
cb.Items.Add("0");
cb.Items.Add("25");
cb.Items.Add("50");
cb.Items.Add("75");
cb.Items.Add("100");
editors[fixedColumnsCount + valvescount + i] = cb;
}
///
for (int i = 0; i < editors.Length; i++)
{
editors[i].Visible = false;
@ -221,10 +248,14 @@ namespace TBF.UI.Bench.Paths
void listViewEx_SubItemEndEditing(object sender, SubItemEndEditingEventArgs e)
{
if (e.SubItem >= fixedColumnsCount)
if (e.SubItem >= fixedColumnsCount && e.SubItem < fixedColumnsCount + valvescount)
{
e.Item.SubItems[e.SubItem].BackColor = e.DisplayText == Strings.open ? Color.LightGray : Color.White;
}
else if (e.SubItem >= fixedColumnsCount + valvescount)
{
e.Item.SubItems[e.SubItem].BackColor = (e.DisplayText != "0" && e.DisplayText != "---") ? Color.LightGray : Color.White;
}
}
public override void DrawOne(object myItem)
@ -256,26 +287,43 @@ namespace TBF.UI.Bench.Paths
foreach (var valve in parent.Valves)
{
int subItemNr = lvi.SubItems.Count;
if (valve.Category == ValveCategory.All || valve.Category == ValveCategory.Output)
{
if (path.ValvesOpen != null && path.ValvesOpen.Contains(valve))
{
lvi.SubItems.Add(Strings.open);
lvi.SubItems[lvi.SubItems.Count - 1].BackColor = Color.LightGray;
lvi.SubItems[subItemNr].BackColor = Color.LightGray;
}
else if (path.ValvesClose != null && path.ValvesClose.Contains(valve))
{
lvi.SubItems.Add(Strings.close);
lvi.SubItems[lvi.SubItems.Count - 1].BackColor = Color.White;
lvi.SubItems[subItemNr].BackColor = Color.White;
}
else
{
lvi.SubItems.Add("---");
lvi.SubItems[lvi.SubItems.Count - 1].BackColor = Color.White;
lvi.SubItems[subItemNr].BackColor = Color.White;
}
}
}
for (int i = 0; i < parent.OutputRegulValves.Count; i++ )
{
int subItemNr = lvi.SubItems.Count;
if (i < path.RegulValvesPct.Length && 0 <= path.RegulValvesPct[i] && path.RegulValvesPct[i] <= 100)
{
float rvPos = path.RegulValvesPct[i];
lvi.SubItems.Add(rvPos.ToString());
lvi.SubItems[subItemNr].BackColor = (rvPos == 0) ? Color.White : Color.LightGray;
}
else
{
lvi.SubItems.Add("---");
lvi.SubItems[subItemNr].BackColor = Color.White;
}
}
lvi.Tag = entity;
Items.Add(lvi);
@ -322,26 +370,46 @@ namespace TBF.UI.Bench.Paths
string valvesOpen = string.Empty;
string valvesClose = string.Empty;
int k = 0;
for (int j = 0; j < parent.Valves.Count; j++)
foreach (var valve in parent.Valves)
{
if (parent.Valves[j].Category == ValveCategory.All || parent.Valves[j].Category == ValveCategory.Output)
if (valve.Category == ValveCategory.All || valve.Category == ValveCategory.Output)
{
string text = lvi.SubItems[fixedColumnsCount + k].Text;
if (text.Equals(Strings.open))
{
if (valvesOpen != string.Empty) valvesOpen += ";";
valvesOpen += parent.Valves[j].Cfg.Name;
valvesOpen += valve.Cfg.Name;
}
if (text.Equals(Strings.close))
{
if (valvesClose != string.Empty) valvesClose += ";";
valvesClose += parent.Valves[j].Cfg.Name;
valvesClose += valve.Cfg.Name;
}
k++;
}
}
entity.ValvesOpen = valvesOpen;
entity.ValvesClose = valvesClose;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < regulValvesCount; i++)
{
float pct;
string text = lvi.SubItems[fixedColumnsCount + valvescount + i].Text;
if (Utils.TryParseUFloat(text, out pct) && pct >= 0 && pct <= 100.0f)
{
sb.Append(pct.ToString());
}
else
{
sb.Append("-1");
}
if (i != regulValvesCount - 1)
{
sb.Append(";");
}
}
entity.RegulValvesPct = sb.ToString();
}
public void AddOne()