Config.Entities.OutputPath.RegVPositions added, UI and SequenceBase changes, ver. 3.4.1975

This commit is contained in:
Milan Hanajik 2022-10-26 14:42:00 +02:00
parent 0f738be73e
commit ac5684a2b5
15 changed files with 348 additions and 163 deletions

View File

@ -18,7 +18,7 @@ namespace Config.Entities
public virtual Unit FlowUnit { get; set; } /// Not mapped to database, used in UI
public virtual string Selector { get; set; }
public virtual string Pump { get; set; }
public virtual string RegVPositions { get; set; } /// Positions of regulation valves in % separated by ';'
public virtual string RegVPositions { get; set; } /// Positions of regulation valves in Category.Feeding in % separated by ';'
/// Valves
public virtual string ValvesOpen { get; set; }

View File

@ -24,6 +24,7 @@ namespace Config.Entities
public virtual string Diverter { get; set; }
public virtual string TempMtrDiv { get; set; }
public virtual string Scale { get; set; }
public virtual string RegVPositions { get; set; } /// Positions of regulation valves in Category.Output in % separated by ';'
/// Valves
public virtual string ValvesOpen { get; set; }
@ -63,6 +64,7 @@ namespace Config.Entities
result.Diverter = Diverter;
result.TempMtrDiv = TempMtrDiv;
result.Scale = Scale;
result.RegVPositions= RegVPositions;
result.ValvesOpen = ValvesOpen;
result.ValvesClose = ValvesClose;

View File

@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2015 Sensus Metering Systems
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
///
using FluentNHibernate.Mapping;
using Config.Entities;
@ -23,6 +23,7 @@ namespace Config.Mappings
Map(x => x.Diverter);
Map(x => x.TempMtrDiv);
Map(x => x.Scale);
Map(x => x.RegVPositions);
Map(x => x.ValvesOpen)
.CustomType("StringClob")
.CustomSqlType("varchar(8000)");

View File

@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("3.3.1973.0")]
[assembly: AssemblyFileVersion("3.3.1973.0")]
[assembly: AssemblyVersion("3.4.1975.0")]
[assembly: AssemblyFileVersion("3.4.1975.0")]

View File

@ -13,21 +13,19 @@ namespace TBF.Rig
public double Qfrom;
public double Qto;
public string Selector;
public IValve Pump; /// pump to use with this path or null
public IList<IRegValve> RegulValves;
public IList<float> RegulValvesPct;
public IList<IValve> ValvesOpen; /// a list of valves to open or null
public IList<IValve> ValvesClose; /// a list of valves to close or null
public IValve Pump; /// pump to use with this path or null
public IList<RegValvePosition> RegVPositions;
public IList<IValve> ValvesOpen; /// a list of valves to open or null
public IList<IValve> ValvesClose; /// a list of valves to close or null
/// Constructor from name, the rest is empty
public FeedingPath(string name, int itemNr)
{
ItemNr = itemNr;
Name = name;
ValvesOpen = new List<IValve>();
RegVPositions = new List<RegValvePosition>();
ValvesOpen = new List<IValve>();
ValvesClose = new List<IValve>();
RegulValves = new List<IRegValve>();
RegulValvesPct = new List<float>();
}
/// Constructor from data entity
@ -40,29 +38,22 @@ namespace TBF.Rig
Pump = TbfComponents.FindComponent(entity.Pump, components) as IValve;
///
/// Feeding regulation valve components
/// Feeding regulation valves and their positions
///
RegVPositions.Clear();
foreach (var cmpnt in components)
{
IRegValve regValve = cmpnt as IRegValve;
if (regValve != null && regValve.Category == TBF.Rig.ValveCategory.Feeding)
IRegValve rv = cmpnt as IRegValve;
if (rv != null && rv.Category == TBF.Rig.ValveCategory.Feeding && !(rv is TBF.Rig.Uni.RegValveTandem.RegValveTandem))
{
RegulValves.Add(regValve);
RegVPositions.Add(new RegValvePosition(rv));
}
}
TBF.Utils.UpdateRegVPositionsFromStr(ref RegVPositions, entity.RegVPositions);
///
/// Feeding regulation valve precentages
/// Regular valves to open
///
string[] rvPosStr = (entity.RegVPositions != null) ? entity.RegVPositions.Split(new char[] { ';' }) : new string[0];
for (int i = 0; i < RegulValves.Count; i++)
{
string str = (i < rvPosStr.Length) ? rvPosStr[i] : "---";
float pct;
if (!Utils.TryParseUFloat(str, out pct) || pct > 100.0f || str == "---") pct = 0;
RegulValvesPct.Add(pct);
}
string[] vOpen = entity.ValvesOpen.Split(new char[] { ';' });
ValvesOpen = new List<IValve>();
foreach (var vName in vOpen)
@ -71,6 +62,9 @@ namespace TBF.Rig
if (cmpnt is IValve) ValvesOpen.Add(cmpnt as IValve);
}
///
/// Regular valves to close
///
string[] vClose = entity.ValvesClose.Split(new char[] { ';' });
ValvesClose = new List<IValve>();
foreach (var vName in vClose)

View File

@ -27,6 +27,7 @@ namespace TBF.Rig
public IValve StartValve3;
public bool InvertSV3;
public int LagSV3;
public IList<RegValvePosition> RegVPositions;
public IList<IValve> ValvesOpen;
public IList<IValve> ValvesClose;
@ -35,6 +36,7 @@ namespace TBF.Rig
{
ItemNr = itemNr;
Name = name;
RegVPositions = new List<RegValvePosition>();
ValvesOpen = new List<IValve>();
ValvesClose = new List<IValve>();
}
@ -65,6 +67,23 @@ namespace TBF.Rig
InvertSV3 = (svs.Length > 6) ? svs[6].Equals("i") : false;
LagSV3 = (svs.Length > 7 && int.TryParse(svs[7], out iTmp)) ? iTmp : 0;
///
/// Output regulation valves and their positions
///
RegVPositions.Clear();
foreach (var cmpnt in components)
{
IRegValve rv = cmpnt as IRegValve;
if (rv != null && rv.Category == TBF.Rig.ValveCategory.Output && !(rv is TBF.Rig.Uni.RegValveTandem.RegValveTandem))
{
RegVPositions.Add(new RegValvePosition(rv));
}
}
TBF.Utils.UpdateRegVPositionsFromStr(ref RegVPositions, entity.RegVPositions);
///
/// Regular valves to open
///
string[] vOpen = entity.ValvesOpen.Split(new char[] { ';' });
ValvesOpen = new List<IValve>();
foreach (var vName in vOpen)
@ -73,7 +92,10 @@ namespace TBF.Rig
if (cmpnt is IValve) ValvesOpen.Add(cmpnt as IValve);
}
string[] vClose = entity.ValvesClose.Split(new char[] { ';' });
///
/// Regular valves to close
///
string[] vClose = entity.ValvesClose.Split(new char[] { ';' });
ValvesClose = new List<IValve>();
foreach (var vName in vClose)
{

View File

@ -0,0 +1,27 @@
///
/// Copyright (c) 2022 Sensus Slovensko a.s.
///
using System;
using TBF.Rig.GenericDevices;
namespace TBF.Rig
{
public class RegValvePosition
{
public IRegValve RegValve;
public float Position; /// 0 .. 100.0f is position in %, <0 (default -1.0f) means no change
public RegValvePosition(IRegValve regValve, float position)
{
RegValve = regValve;
Position = position;
}
/// Constructor with reg. valve and no position change
public RegValvePosition(IRegValve regValve)
{
RegValve = regValve;
Position = -1.0f;
}
}
}

View File

@ -8,6 +8,7 @@ using SchematicDrawing;
using TBF.Rig.GenericDevices;
using TBF.Boxes;
using TBF.Resources;
using Config.Entities;
namespace TBF.Rig.Sequences
{
@ -52,11 +53,35 @@ namespace TBF.Rig.Sequences
/// Created when test sequence is open.
/// They persist during all repetitions of the same test
///
public static Rig.OutputPath Devices { get { return outPath; } }
///
protected static Rig.FeedingPath inPath;
protected static Rig.BenchPath benchPath;
protected static Rig.OutputPath outPath;
public static Rig.OutputPath Devices { get { return outPath; } }
protected static Rig.MetersPath sensPath;
protected static Rig.HeatMetersPath heatMetersPath;
protected static TransitionSequence transitionBefore;
protected static TransitionSequence transitionBetween;
protected static TransitionSequence transitionAfter;
///
/// Advanced information about the next test
///
protected static Rig.FeedingPath nextInPath;
protected static Rig.BenchPath nextBenchPath;
protected static Rig.OutputPath nextOutPath;
protected static Rig.MetersPath nextSensPath;
protected static Rig.HeatMetersPath nextHeatMetersPath;
protected static TransitionSequence nextTransitionBefore;
protected static double nextQfrom;
protected static double nextQto;
protected static float nextPumpPower;
protected static float nextPidCoef;
protected static int nextShortPulses;
///
/// Schematic drawing related
///
public static readonly IList<IDrawingItCmpntWithMeasuredVal> ComponentsWithMeasuredVal;
public static readonly IList<IDrawingItCmpntWithSetpoint> ComponentsWithSetpoint;
public static readonly IList<IDrawingItCmpntWithCustomBmp> ComponentsWithCustomBmp;
@ -74,8 +99,11 @@ namespace TBF.Rig.Sequences
/// State variables to be saved after each completed test
///
public static Results.BatchResults BatchRslts;
public static int BatchNr { get { return (BatchRslts != null && BatchRslts.Batch != null) ? BatchRslts.Batch.BatchNr : 0; } }
///
/// iPERL related state variables to be saved after each completed test
///
public static IList<TestMethods.iPerlCommunication.iPerlHead.IperlHead> IperlHeads;
public static bool IsQ2PreCorrectionCalculated;
public static int CalculatedQ2PreCorrectionLR;

View File

@ -35,11 +35,11 @@ namespace TBF.Rig.Sequences
///------------------------------------------------------------
/// Global static variables set only once.
///------------------------------------------------------------
public static IList<IFlowMeter> FlowMeters; /// list of reference flowmeters
public static IList<IRegValve> 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<RegValvePosition> RegVPositions; /// 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.
@ -50,34 +50,11 @@ namespace TBF.Rig.Sequences
public static double Qrise;
public static double Qfall;
///------------------------------------------------------------
/// Test related (instance) variables.
/// Created when test sequence is open.
/// They persist during all repetitions of the same test
///------------------------------------------------------------
protected static Rig.FeedingPath inPath;
protected static Rig.MetersPath sensPath;
protected static Rig.HeatMetersPath heatMetersPath;
protected static TransitionSequence transitionBefore;
protected static TransitionSequence transitionBetween;
protected static TransitionSequence transitionAfter;
/// <summary>
/// Advanced information about the next test
/// </summary>
protected static Rig.FeedingPath nextInPath;
protected static Rig.BenchPath nextBenchPath;
protected static Rig.OutputPath nextOutPath;
protected static Rig.MetersPath nextSensPath;
protected static Rig.HeatMetersPath nextHeatMetersPath;
protected static TransitionSequence nextTransitionBefore;
protected static double nextQfrom;
protected static double nextQto;
protected static float nextPumpPower;
protected static float nextPidCoef;
protected static int nextShortPulses;
protected IOperation queryEnd1;
@ -347,6 +324,36 @@ namespace TBF.Rig.Sequences
}
/// <summary>
/// Returns a list of reg.valve positioning operations
/// </summary>
/// <param name="regVPositions">List of reg.valve/position pairs, position is in %, position LT 0 ... no operation</param>
/// <returns>List of reg.valve positioning operations</returns>
List<IOperation> GetRegVPositioningOps(IList<RegValvePosition> regVPositions)
{
List<IOperation> rvPosOps = new List<IOperation>();
if (regVPositions == null) return rvPosOps;
foreach (var rvp in regVPositions)
{
if (rvp.Position >= 0) /// Negative value means no position change
{
if (rvp.RegValve.IsCoax)
{
rvPosOps.Add(rvp.RegValve.SetRegValvePositionOp(rvp.Position, -1, 60));
}
else
{
rvPosOps.Add(rvp.RegValve.SetRegValvePositionOp(rvp.Position - 3.0, rvp.Position + 3.0, 60));
}
}
}
return rvPosOps;
}
/// <summary>
/// Executes steps of a transition sequence
/// </summary>
@ -432,12 +439,13 @@ namespace TBF.Rig.Sequences
string activity = string.Format(message, transitionSequence.Name, step.ItemNr + 1, stepsCount);
Bridge.OnActivity(this, activity);
Bridge.OnMessage(this, step.Message);
log.Info(activity + " " +step.Message);
log.InfoFormat("{0} {1}", activity, step.Message);
//------------------------------------------------
///
/// Prepare operation to switch valves
IOperation setValvesOp = StateMachine.ControlBoard.SetValvesOp(Utils.ValvesOpen(step), Utils.ValvesClose(step));
/// Fetch the condition operation, null value is allowed if there is no condition
///
IOperation conditionOperation = null;
if (step.EndCondition != "None")
{
@ -469,30 +477,9 @@ namespace TBF.Rig.Sequences
}
}
/// Get new regulation valve positions,
float[] allRegvPositions = Utils.GetRegulValvesPositions(step.RegulValvesPct, RegulValves.Count);
/// 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].SetRegValvePositionOp(allRegvPositions[i], allRegvPositions[i], 60));
rvPosStr.Add(string.Format("RV{0}.SetRegValvePositionOp({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].SetRegValvePositionOp(lo, hi, 60));
rvPosStr.Add(string.Format("RV{0}.SetRegValvePositionOp({1}, {2}, 60s)", i, lo, hi));
}
}
}
Utils.UpdateRegVPositionsFromStr(ref RegVPositions, step.RegulValvesPct);
IList<IOperation> rvPosOps = GetRegVPositioningOps(RegVPositions);
/// Max. one SetRegValvePositionOp can be started or stopped in one sub-step.
/// Therefore SetRegValvePositionOp operations are added and removed to subsequent states one by one.
@ -507,11 +494,10 @@ namespace TBF.Rig.Sequences
.Create(string.Format("SequenceBase.Transition() : Step {0} start, opening={1}, closing={2}", step.ItemNr + 1, step.ValvesOpen, step.ValvesClose))
.AddOperation(checkUiOp)
.AddOperation(conditionOperation)
.AddOperation(StateMachine.ControlBoard.SetValvesOp(Utils.ValvesOpen(step), Utils.ValvesClose(step)));
.AddOperation(setValvesOp);
for (int j = 0; j <= i; j++)
{
stepStrt.AddOperation(rvPosOps[j]);
log.Debug(rvPosStr[j]);
}
lastStartedRV = i;
stepStrt.EnterState();
@ -528,12 +514,11 @@ namespace TBF.Rig.Sequences
.Create(string.Format("SequenceBase.Transition() : Step {0} delay {1}s, opening={2}, closing={3}", step.ItemNr + 1, delay, step.ValvesOpen, step.ValvesClose))
.AddOperation(checkUiOp)
.AddOperation(conditionOperation)
.AddOperation(StateMachine.ControlBoard.SetValvesOp(Utils.ValvesOpen(step), Utils.ValvesClose(step)))
.AddOperation(setValvesOp)
.AddOperation(new TimerOp(delay));
for (int j = 0; j <= lastStartedRV; j++)
{
stepDelay.AddOperation(rvPosOps[j]);
log.Debug(rvPosStr[j]);
}
stepDelay.EnterState();
bool endContitionFulfilled = false;
@ -574,11 +559,10 @@ namespace TBF.Rig.Sequences
.Create(string.Format("SequenceBase.Transition() : Step {0} stop, opening={1}, closing={2}", step.ItemNr + 1, step.ValvesOpen, step.ValvesClose))
.AddOperation(checkUiOp)
.AddOperation(conditionOperation)
.AddOperation(StateMachine.ControlBoard.SetValvesOp(Utils.ValvesOpen(step), Utils.ValvesClose(step)));
.AddOperation(setValvesOp);
for (int j = first; j <= lastStartedRV; j++)
{
stepStop.AddOperation(rvPosOps[j]);
log.Debug(rvPosStr[j]);
}
stepStop.EnterState();
e = StateMachine.WaitRunDevsRunOps();
@ -621,47 +605,37 @@ namespace TBF.Rig.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(BuiltIn.ValveBase.Merge(inPath.ValvesOpen, benchPath.ValvesOpen, outPath.ValvesOpen),
BuiltIn.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));
}
List<IOperation> regVPosOps = GetRegVPositioningOps(inPath.RegVPositions);
regVPosOps.AddRange(GetRegVPositioningOps(outPath.RegVPositions));
Event evnt = PerformSteps(BuiltIn.ValveBase.Merge(inPath.ValvesOpen, benchPath.ValvesOpen, outPath.ValvesOpen),
BuiltIn.ValveBase.Merge(inPath.ValvesClose, benchPath.ValvesClose, outPath.ValvesClose),
regVPosOps,
"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)
{
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(BuiltIn.ValveBase.Merge(nextInPath.ValvesOpen, nextBenchPath.ValvesOpen, nextOutPath.ValvesOpen),
BuiltIn.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));
///
List<IOperation> regVPosOps = GetRegVPositioningOps(nextInPath.RegVPositions);
regVPosOps.AddRange(GetRegVPositioningOps(nextOutPath.RegVPositions));
Event evnt = PerformSteps(BuiltIn.ValveBase.Merge(nextInPath.ValvesOpen, nextBenchPath.ValvesOpen, nextOutPath.ValvesOpen),
BuiltIn.ValveBase.Merge(nextInPath.ValvesClose, nextBenchPath.ValvesClose, nextOutPath.ValvesClose),
regVPosOps,
"SequenceBase : AfterTestWithOverlap : Default action");
if (evnt == Event.Error || evnt == Event.UiCmdStop) return evnt;
/// Set PID coefficient, etc.
if (StateMachine.ControlBoard is ControlBoard.Uni.UniCB)
@ -708,6 +682,69 @@ namespace TBF.Rig.Sequences
}
Event PerformSteps(IList<IValve> valvesToOpen, IList<IValve> valvesToClose, IList<IOperation> rvPosOps, string stateTitle)
{
bool stopFlag = false;
bool errorFlag = false;
IList<Event> e;
IOperation setValvesOp = StateMachine.ControlBoard.SetValvesOp(valvesToOpen, valvesToClose);
int lastStartedRV = -1;
for (int i = 0; i < rvPosOps.Count; i++)
{
State stepStrt = State.Create(stateTitle)
.AddOperation(checkUiOp)
.AddOperation(setValvesOp);
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(setValvesOp);
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(setValvesOp);
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

@ -153,7 +153,7 @@ namespace TBF.Rig
ProcessData.IperlHeads = new List<TestMethods.iPerlCommunication.iPerlHead.IperlHead>();
SequenceBase.FlowMeters = new List<IFlowMeter>();
SequenceBase.RegulValves = new List<IRegValve>();
SequenceBase.RegVPositions = new List<RegValvePosition>();
SequenceBase.PumpsWithFM = new List<IPumpFM>();
SequenceBase.WaterMeters = new List<IWaterMeter>();
SequenceBase.Cameras = new List<ICamera>();
@ -270,7 +270,7 @@ namespace TBF.Rig
if (cmpnt is IFlowMeter) SequenceBase.FlowMeters.Add(cmpnt as IFlowMeter);
if ((cmpnt is IRegValve) && !(cmpnt is Rig.Uni.RegValveTandem.RegValveTandem))
{
SequenceBase.RegulValves.Add(cmpnt as IRegValve);
SequenceBase.RegVPositions.Add(new RegValvePosition(cmpnt as IRegValve));
}
if (cmpnt is IPumpFM && !(cmpnt is BuiltIn.PumpTandem.Pump)) SequenceBase.PumpsWithFM.Add(cmpnt as IPumpFM);
if (cmpnt is IWaterMeter) SequenceBase.WaterMeters.Add(cmpnt as IWaterMeter);

View File

@ -1129,6 +1129,7 @@
</Compile>
<Compile Include="Rig\RegisterReaders\StandingStartStop\Factory.cs" />
<Compile Include="Rig\RegisterReaders\StandingStartStop\RRProcParams.cs" />
<Compile Include="Rig\RegValvePosition.cs" />
<Compile Include="Rig\Scales\MettlerToledo\ScaleCfg.cs" />
<Compile Include="Rig\Scales\MettlerToledo\Scale.cs" />
<Compile Include="Rig\Scales\MettlerToledo\Factory.cs" />

View File

@ -9,6 +9,7 @@ using log4net;
using Common;
using Common.Forms;
using Config.Entities;
using TBF.Rig;
using TBF.Rig.GenericDevices;
using TBF.Resources;
using TBF.UI.Shared;
@ -33,7 +34,8 @@ namespace TBF.UI.Bench.Paths
public IList<Rig.Generic.IComponent> TbfComponents;
public IList<IValve> Valves;
public IList<IRegValve> FeedingRegulValves;
public IList<IRegValve> FeedingRegValves;
public IList<IRegValve> OutputRegValves;
public ISession Session; /// One common DB session passed also to the controls inside tab pages
public IList<Procedure> Procedures;
public IList<Test> Tests;
@ -72,13 +74,21 @@ namespace TBF.UI.Bench.Paths
Valves = Rig.BuiltIn.ValveBase.GetMasterValves(TbfComponents);
/// Find all feeding regulation valves
FeedingRegulValves = new List<IRegValve>();
FeedingRegValves = new List<IRegValve>();
OutputRegValves = new List<IRegValve>();
foreach (var cmpnt in TbfComponents)
{
IRegValve regValve = cmpnt as IRegValve;
if (regValve != null && regValve.Category == TBF.Rig.ValveCategory.Feeding)
if (cmpnt is IRegValve && !(cmpnt is TBF.Rig.Uni.RegValveTandem.RegValveTandem))
{
FeedingRegulValves.Add(regValve);
switch ((cmpnt as IRegValve).Category)
{
case ValveCategory.Feeding:
FeedingRegValves.Add(cmpnt as IRegValve);
break;
case ValveCategory.Output:
OutputRegValves.Add(cmpnt as IRegValve);
break;
}
}
}

View File

@ -76,18 +76,18 @@ namespace TBF.UI.Bench.Paths
Columns.Add(Strings.Pump, (ls.FeedingColumnCount > 5) ? ls.FeedingColumnWidths[5] : 60 * parent.Dpi / Constants.Dpi100pct);
int clmn = (int)Column.FixedColumnsCount;
foreach (var rv in parent.FeedingRegulValves)
foreach (var rv in parent.FeedingRegValves)
{
Columns.Add(rv.Cfg.Name, (ls.FeedingColumnCount > clmn) ? ls.FeedingColumnWidths[clmn] : 50 * parent.Dpi / Constants.Dpi100pct);
Columns.Add(string.Format("{0} [%]", rv.Name), (ls.FeedingColumnCount > clmn) ? ls.FeedingColumnWidths[clmn] : 50 * parent.Dpi / Constants.Dpi100pct);
clmn++;
}
regvCount = clmn - (int)Column.FixedColumnsCount;
regvCount = parent.FeedingRegValves.Count;
foreach (var vlv in parent.Valves)
{
if (vlv.Category == TBF.Rig.ValveCategory.Feeding)
{
Columns.Add(vlv.Cfg.Name, (ls.FeedingColumnCount > clmn) ? ls.FeedingColumnWidths[clmn] : 50 * parent.Dpi / Constants.Dpi100pct);
Columns.Add(vlv.Name, (ls.FeedingColumnCount > clmn) ? ls.FeedingColumnWidths[clmn] : 50 * parent.Dpi / Constants.Dpi100pct);
clmn++;
}
}
@ -105,7 +105,7 @@ namespace TBF.UI.Bench.Paths
if (cmpnt is IPump) pumpCBox.Items.Add(cmpnt.Cfg.Name);
}
editors = new Control[fixedColumnsCount + regvCount + 64];
editors = new Control[fixedColumnsCount + regvCount + valvesCount];
///
editors[(int)Column.Name] = new TextBox(); /// Name
editors[(int)Column.Qfrom] = new TextBox(); /// Q_from
@ -125,8 +125,8 @@ namespace TBF.UI.Bench.Paths
editors[fixedColumnsCount + i] = cb;
}
/// Prepare valve combo-boxes (max. 64 valves)
for (int i = 0; i < 64; i++)
/// Prepare valve combo-boxes
for (int i = 0; i < valvesCount; i++)
{
ComboBox cb = new ComboBox();
cb.Items.Add("---");
@ -264,7 +264,7 @@ namespace TBF.UI.Bench.Paths
lvi.SubItems.Add(path.Pump != null ? path.Pump.Cfg.Name : "---");
string[] rvPosStr = (entity.RegVPositions != null) ? entity.RegVPositions.Split(new char[] {';'})
: new string[0];
: new string[0];
for (int i = 0; i < regvCount; i++)
{
lvi.SubItems.Add((i < rvPosStr.Length) ? rvPosStr[i] : "---");
@ -322,18 +322,18 @@ namespace TBF.UI.Bench.Paths
///
/// Regulation valves
///
string regulValvesPct = string.Empty;
string regulVPositions = string.Empty;
for (int i = fixedColumnsCount; i < fixedColumnsCount + regvCount; i++)
{
if (regulValvesPct.Length > 0) regulValvesPct += ";";
if (regulVPositions.Length > 0) regulVPositions += ";";
float fdummy;
if (lvi.SubItems[i].Text.Equals("---") ||
(Utils.TryParseUFloat(lvi.SubItems[i].Text, out fdummy) && (fdummy >= 0) && (fdummy <= 100.0f)))
{
regulValvesPct += lvi.SubItems[i].Text;
regulVPositions += lvi.SubItems[i].Text;
}
}
entity.RegVPositions = regulValvesPct;
entity.RegVPositions = regulVPositions;
///
/// Valves

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using log4net;
using Common;
@ -48,6 +49,9 @@ namespace TBF.UI.Bench.Paths
}
readonly int fixedColumnsCount = (int)Column.FixedColumnsCount;
int valvescount;
int regulValvesCount;
PathsDlg parent;
Control parentControl;
Control[] editors;
@ -100,16 +104,25 @@ namespace TBF.UI.Bench.Paths
Columns.Add(string.Format("Inv.SV3"), (ls.OutputColumnCount > 17) ? ls.OutputColumnWidths[17] : 80 * parent.Dpi / Constants.Dpi100pct);
Columns.Add(string.Format("Lag SV3"), (ls.OutputColumnCount > 18) ? ls.OutputColumnWidths[18] : 80 * parent.Dpi / Constants.Dpi100pct);
valvescount = 0;
regulValvesCount = 0;
int clmn = (int)Column.FixedColumnsCount;
///
foreach (var vlv in parent.Valves)
{
if (vlv.Category == ValveCategory.Output)
{
Columns.Add(vlv.Cfg.Name, (ls.OutputColumnCount > clmn) ? ls.OutputColumnWidths[clmn] : 50 * parent.Dpi / Constants.Dpi100pct);
Columns.Add(vlv.Name, (ls.OutputColumnCount > clmn) ? ls.OutputColumnWidths[clmn] : 50 * parent.Dpi / Constants.Dpi100pct);
clmn++;
valvescount++;
}
}
foreach (var rv in parent.OutputRegValves)
{
Columns.Add(string.Format("{0} [%]", rv.Name), (ls.OutputColumnCount > clmn) ? ls.OutputColumnWidths[clmn] : 55 * parent.Dpi / Constants.Dpi100pct);
clmn++;
regulValvesCount++;
}
/// Prepare fixed columns combo boxes
ComboBox flowMeterComboBox = new ComboBox();
@ -158,7 +171,7 @@ namespace TBF.UI.Bench.Paths
var flowUnitBox = new ComboBox();
for (Unit u = 0; u < Unit.Count; u++) if (Units.IsFlow(u)) flowUnitBox.Items.Add(u.ToDescription());
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
@ -180,7 +193,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("---");
@ -188,7 +201,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;
@ -200,8 +225,9 @@ namespace TBF.UI.Bench.Paths
void listViewEx_SubItemClicked(object sender, SubItemEventArgs e)
{
if (!Unlocked || e.SubItem >= editors.Length) return;
if ((e.Item.Tag is IHasItemNr) &&
if (e.SubItem != (int)Column.FlowUnit && (!Unlocked || e.SubItem >= editors.Length)) return;
if ((e.Item.Tag is IHasItemNr) &&
((e.Item.Tag as IHasItemNr).ItemNr < FixedRowsCount) &&
(e.SubItem < fixedColumnsCount))
{
@ -243,10 +269,14 @@ namespace TBF.UI.Bench.Paths
var entity = e.Item.Tag as Config.Entities.OutputPath;
double ddummy;
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;
}
else if (e.SubItem == (int)Column.Qfrom)
{
if (Utils.TryParseUDouble(e.DisplayText, out ddummy))
@ -333,26 +363,43 @@ namespace TBF.UI.Bench.Paths
foreach (var valve in parent.Valves)
{
int subItemNr = lvi.SubItems.Count;
if (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;
}
}
}
foreach (var rvp in path.RegVPositions)
{
int subItemNr = lvi.SubItems.Count;
if (0 <= rvp.Position && rvp.Position <= 100)
{
float rvPos = rvp.Position;
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);
@ -400,26 +447,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.Output)
if (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.RegVPositions = sb.ToString();
}
public void AddOne()

View File

@ -189,30 +189,26 @@ namespace TBF
/// <summary>
/// Get an array of RegulValve positions from a TransitionStep entity
/// Update a list of regulation valve position pairs from a string
/// </summary>
/// <param name="entity">TransitionStep entity</param>
/// <returns>float[] of regulation valve positions from 0 to 100.0f</returns>
public static float[] GetRegulValvesPositions(string regulValvesPct, int regvCount)
/// <param name="regVPositionsStr">String with reg.valve positions in % separated by ';'</param>
/// <param name="regVPositions">List with reg. valve / position pairs</param>
public static void UpdateRegVPositionsFromStr(ref IList<Rig.RegValvePosition> regVPositions, string regVPositionsStr)
{
float[] result = new float[regvCount];
string[] rvPosStr = string.IsNullOrEmpty(regVPositionsStr) ? new string[0] : regVPositionsStr.Split(new char[] { ';' });
string[] rvPosStr = (regulValvesPct != null) ? regulValvesPct.Split(new char[] { ';' }) : new string[0];
for (int i = 0; i < regvCount; i++)
for (int i = 0; i < Math.Min(rvPosStr.Length, regVPositions.Count); i++)
{
float fdummy;
if ((i < rvPosStr.Length) && Utils.TryParseUFloat(rvPosStr[i], out fdummy) &&
(fdummy >= 0) && (fdummy <= 100.0f))
if (Utils.TryParseUFloat(rvPosStr[i], out fdummy) && fdummy >= 0 && fdummy <= 100.0f)
{
result[i] = fdummy;
regVPositions[i].Position = fdummy;
}
else // if ((i < rvPosStr.Length) && rvPosStr[i].Equals("---"))
else //if (rvPosStr[i].Equals("---"))
{
result[i] = -1.0f; /// Negative value means no regulation valve position change
regVPositions[i].Position = -1.0f; /// Negative value means no regulation valve position change
}
}
return result;
}