From 6da5bd92ecb71952557fe0bdd45529977b083abe Mon Sep 17 00:00:00 2001 From: Milan Hanajik Date: Wed, 2 Dec 2020 13:42:03 +0100 Subject: [PATCH] Positions of reg. valves are defined in output path --- Config/Entities/OutputPath.cs | 6 +- Config/Mappings/OutputPathMap.cs | 5 +- TBF/BenchControl/OutputPath.cs | 3 +- TBF/BenchControl/Sequences/SequenceBase.cs | 175 +++++++++++++-------- TBF/BenchControl/StateMachine.cs | 5 +- TBF/UI/Bench/Paths/PathsDlg.cs | 17 +- TBF/UI/Bench/Paths/PathsOutputCtrl.cs | 92 +++++++++-- 7 files changed, 220 insertions(+), 83 deletions(-) diff --git a/Config/Entities/OutputPath.cs b/Config/Entities/OutputPath.cs index 8b375f3b5..1a9b1ef1b 100644 --- a/Config/Entities/OutputPath.cs +++ b/Config/Entities/OutputPath.cs @@ -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; diff --git a/Config/Mappings/OutputPathMap.cs b/Config/Mappings/OutputPathMap.cs index 1e7ebbe14..1eaac857e 100644 --- a/Config/Mappings/OutputPathMap.cs +++ b/Config/Mappings/OutputPathMap.cs @@ -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)"); diff --git a/TBF/BenchControl/OutputPath.cs b/TBF/BenchControl/OutputPath.cs index a2bf7fd5d..8b928636f 100644 --- a/TBF/BenchControl/OutputPath.cs +++ b/TBF/BenchControl/OutputPath.cs @@ -26,6 +26,7 @@ namespace TBF.BenchControl public IValve StartValve3; public bool InvertSV3; public int LagSV3; + public float[] RegulValvesPct; public IList ValvesOpen; public IList 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; /// diff --git a/TBF/BenchControl/Sequences/SequenceBase.cs b/TBF/BenchControl/Sequences/SequenceBase.cs index bc9da5be8..e2f1ffa55 100644 --- a/TBF/BenchControl/Sequences/SequenceBase.cs +++ b/TBF/BenchControl/Sequences/SequenceBase.cs @@ -37,11 +37,12 @@ namespace TBF.BenchControl.Sequences ///------------------------------------------------------------ /// Global static variables set only once. ///------------------------------------------------------------ - public static IList FlowMeters; /// list of reference flowmeters - public static IList RegulValves; /// list of regulation valves - public static IList PumpsWithFM; /// list of FM controlled pumps - public static IList WaterMeters; /// list of water meters - public static IList Cameras; /// list of cameras + public static IList FlowMeters; /// list of reference flowmeters + public static IList RegulValves; /// list of regulation valves + public static IList OutputRegulValves; /// list of regulation valves + public static IList PumpsWithFM; /// list of FM controlled pumps + public static IList WaterMeters; /// list of water meters + public static IList 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 GetRegValvePositioningOps(IList regValves, float[] regValvePositions) + { + IList rvPosOps = new List(); + + 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; + } + + /// /// Executes steps of a transition sequence /// @@ -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 rvPosOps = new List(); - IList rvPosStr = new List(); - 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 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 valvesToOpen, IList valvesToClose, IList rvPosOps, string stateTitle) + { + bool stopFlag = false; + bool errorFlag = false; + IList 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; + } + + /// /// Opens a modeless dialog for entering data at the beginning of a procedure (serial numbers) /// diff --git a/TBF/BenchControl/StateMachine.cs b/TBF/BenchControl/StateMachine.cs index 3241b1ea4..0dccc115d 100644 --- a/TBF/BenchControl/StateMachine.cs +++ b/TBF/BenchControl/StateMachine.cs @@ -223,6 +223,7 @@ namespace TBF.BenchControl ProcessData.IperlHeads = new List(); SequenceBase.FlowMeters = new List(); SequenceBase.RegulValves = new List(); + SequenceBase.OutputRegulValves = new List(); SequenceBase.PumpsWithFM = new List(); SequenceBase.WaterMeters = new List(); SequenceBase.Cameras = new List(); @@ -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)) { diff --git a/TBF/UI/Bench/Paths/PathsDlg.cs b/TBF/UI/Bench/Paths/PathsDlg.cs index cb75d8aa6..44fa10c88 100644 --- a/TBF/UI/Bench/Paths/PathsDlg.cs +++ b/TBF/UI/Bench/Paths/PathsDlg.cs @@ -34,6 +34,7 @@ namespace TBF.UI.Bench.Paths public IList TbfComponents; public IList Valves; public IList FeedingRegulValves; + public IList OutputRegulValves; public ISession Session; /// One common DB session passed also to the controls inside tab pages public IList Procedures; public IList Tests; @@ -78,12 +79,24 @@ namespace TBF.UI.Bench.Paths /// Find all feeding regulation valves FeedingRegulValves = new List(); + OutputRegulValves = new List(); 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; + } } } diff --git a/TBF/UI/Bench/Paths/PathsOutputCtrl.cs b/TBF/UI/Bench/Paths/PathsOutputCtrl.cs index 87c226187..aa48b7a94 100644 --- a/TBF/UI/Bench/Paths/PathsOutputCtrl.cs +++ b/TBF/UI/Bench/Paths/PathsOutputCtrl.cs @@ -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()