From 271200a8daf2dd9c1ae8f30db9c91e5cc6bb9251 Mon Sep 17 00:00:00 2001 From: Marek Frniak Date: Fri, 17 Jul 2026 12:42:07 +0200 Subject: [PATCH] Upgrade - StandingStartMassCollectionAdvance method - 1. changed structure and residual flow delays by changes in StandingStartMassCollection method, 2. added variables, counting and evaluation for volume/mass type of RegisterReader --- TBF/Properties/AssemblyInfo.cs | 4 +- .../StandingStartMassCollectionSeq.cs | 1 + .../StandingStartMassCollectionAdvanceSeq.cs | 234 ++++++++++++++---- 3 files changed, 195 insertions(+), 44 deletions(-) diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs index fd399a997..fc1dc9785 100644 --- a/TBF/Properties/AssemblyInfo.cs +++ b/TBF/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("3.9.3134.103")] -[assembly: AssemblyFileVersion("3.9.3134.103")] +[assembly: AssemblyVersion("3.9.3134.104")] +[assembly: AssemblyFileVersion("3.9.3134.104")] diff --git a/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs b/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs index e269bd9d9..77483c5c1 100644 --- a/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs +++ b/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs @@ -1216,6 +1216,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection tstRslt.ConstMasterRaw = 1; /// Uncorrected master flowmeter coefficient tstRslt.ConstMasterCorr = 1; /// Corrected master pulses per liter tstRslt.ConstMaster = 1; + tstRslt.MassConstMaster = 1; } tstRslt.ErrorMaster = Formulas.ErrorFromVolumes(tstRslt.VolumeMaster, tstRslt.VolumeCTV); tstRslt.MassErrorMaster = Formulas.ErrorFromVolumes(tstRslt.VolumeMaster, tstRslt.MassCTV); diff --git a/TBF/Rig/TestMethods/StandingStartMassCollectionAdvance/StandingStartMassCollectionAdvanceSeq.cs b/TBF/Rig/TestMethods/StandingStartMassCollectionAdvance/StandingStartMassCollectionAdvanceSeq.cs index 09fad7557..1df89b4c1 100644 --- a/TBF/Rig/TestMethods/StandingStartMassCollectionAdvance/StandingStartMassCollectionAdvanceSeq.cs +++ b/TBF/Rig/TestMethods/StandingStartMassCollectionAdvance/StandingStartMassCollectionAdvanceSeq.cs @@ -1,14 +1,16 @@ -/// +using Common; +using Config.Entities; +using FluentNHibernate.Conventions; +using log4net; +/// /// Copyright (c) 2013-2021 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.IO; using System.Threading; -using log4net; -using Common; -using Config.Entities; -using FluentNHibernate.Conventions; +using System.Windows.Forms; +using System.Xml.Serialization; using TBF.Boxes; using TBF.Resources; using TBF.Rig.Generic; @@ -16,6 +18,7 @@ using TBF.Rig.GenericDevices; using TBF.Rig.Network.RestAPI; using TBF.Rig.Operations; using TBF.Rig.Sequences; +using TBF.Rig.Various.ErrorFlags; using TBF.UiBridge; namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance @@ -115,6 +118,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance checkUiOp = new Operations.CheckUIOp(true); /// Runs in more then one state processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, heatMetersTestParams != null); + int delay; + if (cBrd is ControlBoard.Uni.UniCB) { int[] filters = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -332,8 +337,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance State.Create(string.Format("{0}({1}) : Setting the flow", test.Method, test.Name)) .AddOperation(checkUiOp) .AddOperations(readTempPressOps) - .AddOperation(cBrd.SetFlowOp(test.QfromM3ph(), test.QtoM3ph(), RefFlow, FlowSettingTimeoutSec)) - .AddOperation(heatMetersPromptOp) + .AddOperation(cBrd.SetFlowOp(test.QfromM3ph(), test.QtoM3ph(), RefFlow, FlowSettingTimeoutSec))//...develop: step 1 + .AddOperation(heatMetersPromptOp) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); @@ -454,8 +459,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance State.Create(string.Format("{0}({1}) : Close the start/stop valve before measuring the start mass", test.Method, test.Name)) .AddOperation(checkUiOp) .AddOperations(readTempPressOps) - .AddOperation(cBrd.CloseStartValveOp()) - .EnterState(); + .AddOperation(cBrd.CloseStartValveOp())//...develop: step 2 + .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } @@ -463,10 +468,39 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance } while (!e.Contains(Event.ValvesSet)); + ///...MF + ///----------------- + delay = test.TimeFlow2Mass; + + if (delay > 0) + { + State.Create(string.Format("{0}({1}) : Delay for meters stabilization ", test.Method, test.Name, delay)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(new Operations.TimerOp(delay)) //...develop: step 5 + .EnterState(); + do + { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + + /// Show remaining time + if ((delay = Math.Max(delay, 0)) > 60) + Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", "Delay", delay / 60, "min", delay % 60, Strings.sec)); + else + Bridge.OnActivity(this, string.Format("{0} ... {1} s", "Delay", delay)); + + if (delay > 0) + delay--; + } + while (!e.Contains(Event.TimerExpired)); + } + State.Create(string.Format("{0}({1}) : Start the standing start/stop test", test.Method, test.Name)) .AddOperation(checkUiOp) .AddOperations(readTempPressOps) - .AddOperation(testInProgress) + .AddOperation(testInProgress)//...develop: step 4 --> diverter switch to the mass .EnterState(); for (int i = 0; i < 3; i++) { @@ -492,6 +526,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance /// GenericDevices.IHasWMStatesForm dataEntryCmpnt = TbfComponents.FindComponent(StateMachine.Procedure.DataEntry) as GenericDevices.IHasWMStatesForm; IOperation readStartMassOp = scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread); + IOperation readStopMassOp = scale.ReadStableMassOp(ref StartMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread); + IOperation readEndMassOp = scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread); if (dataEntryCmpnt != null) { @@ -510,7 +546,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance State state2 = State.Create(string.Format("{0}({1}) : Grab images", test.Method, test.Name)) .AddOperation(checkUiOp) .AddOperations(readTempPressOps) - .AddOperation(readStartMassOp) + //.AddOperation(readStartMassOp) .AddOperation(testInProgress) .AddOperation(processDataLoggingOp); @@ -565,12 +601,13 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance Bridge.OnActivity(this, Strings.Grabbing_images);//Strings.Enter_water_meter_data); - State.Create(string.Format("{0}({1}) : Enter start states of water meters", test.Method, test.Name)) + State.Create(string.Format("{0}({1}) : Enter start states of water meters and Measuring the start mass after residual flow ", test.Method, test.Name, test.TimeStop2Mass)) .AddOperation(checkUiOp) .AddOperations(readTempPressOps) - .AddOperation(readStartMassOp) + //.AddOperation(readStartMassOp) .AddOperation(testInProgress) - //.AddOperation((dataEntryCmpnt as GenericDevices.IHasWMStatesForm).ShowTestStartFormOp(sensPath.RegisterReaders)) + //.AddOperation((dataEntryCmpnt as GenericDevices.IHasWMStatesForm).ShowTestStartFormOp(sensPath.RegisterReaders))//...develop: half of step 6 + .AddOperation(readStopMassOp) //...develop: half of step 6 .AddOperation(processDataLoggingOp) .EnterState(); do { @@ -650,10 +687,31 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance } } } + + State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(testInProgress)//...nevhodne prepina diverter + .AddOperation(scale.ReadStableMassOp(ref StartMass, 0, test.MassMethod, test.MassRepeats, test.MassSpread))//...develop: step 8 + .AddOperation(processDataLoggingOp) + .EnterState(); + do + { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + if (e.Contains(Event.ScaleTimeout)) + { + Bridge.OnError(this, Strings.Mass_measurement_timeout); + retVal = Event.RecoverableError; + goto stopTest; + } + } + while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next)); } else { - State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name)) + /*State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name)) .AddOperation(checkUiOp) .AddOperations(readTempPressOps) .AddOperation(testInProgress) @@ -671,6 +729,27 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance goto stopTest; } } + while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next));*/ + State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperations(readTempPressOps) + .AddOperation(testInProgress)//...nevhodne prepina diverter + //.AddOperation(readStartMassOp) + .AddOperation(scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread)) + .AddOperation(processDataLoggingOp) + .EnterState(); + do + { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; } + if (e.Contains(Event.ScaleTimeout)) + { + Bridge.OnError(this, Strings.Mass_measurement_timeout); + retVal = Event.RecoverableError; + goto stopTest; + } + } while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next)); } /// @@ -698,10 +777,10 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance State.Create(string.Format("{0}({1}) : Start the test, open the start/stop valve", test.Method, test.Name)) .AddOperation(checkUiOp) .AddOperations(readTempPressOps) - .AddOperation(cBrd.OpenStartValveOp(timeStampStart, startSwitchTime)) + .AddOperation(cBrd.OpenStartValveOp(timeStampStart, startSwitchTime)) //...develop: step 9 .AddOperation(testInProgress) .AddOperation(controlFlowOp) - .AddOperation(processDataLoggingOp) + .AddOperation(processDataLoggingOp)//...develop: step 10, step 11 .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); @@ -759,7 +838,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance .AddOperation(checkUiOp) .AddOperations(readTempPressOps) .AddOperation(testInProgress) - .AddOperation(cBrd.CloseStartValveOp(timeStampEnd, stopSwitchTime)) + .AddOperation(cBrd.CloseStartValveOp(timeStampEnd, stopSwitchTime))//...develop: step 12 .AddOperation(processDataLoggingOp) .EnterState(); do { @@ -778,12 +857,15 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance //------------------------------------------------ Bridge.OnActivity(this, Strings.Measuring_the_weight); //------------------------------------------------ - State.Create(string.Format("{0}({1}) : Measuring the end mass", test.Method, test.Name)) + + delay = test.TimeStop2Mass; + + State.Create(string.Format("{0}({1}) : Measuring the end mass after residual flow ", test.Method, test.Name, delay)) .AddOperation(checkUiOp) .AddOperations(readTempPressOps) .AddOperation(testInProgress) .AddOperation(scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread)) - .AddOperation(new Operations.TimerOp(StableMassMsrmntTimeoutSec)) + //.AddOperation(new Operations.TimerOp(StableMassMsrmntTimeoutSec)) .AddOperation(processDataLoggingOp) .EnterState(); do { @@ -796,26 +878,20 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance retVal = Event.RecoverableError; goto stopTest; } + + /// Show remaining time + if ((delay = Math.Max(delay, 0)) > 60) + Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", "Delay", delay / 60, "min", delay % 60, Strings.sec)); + else + Bridge.OnActivity(this, string.Format("{0} ... {1} s", "Delay", delay)); + + if (delay > 0) + delay--; } while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next)); /// tMass2 = StateMachine.Time; - if (test.DoDrainingAfter) - { - State.Create(string.Format("{0}({1}) : Open the drain valve", test.Method, test.Name)) - .AddOperation(checkUiOp) - .AddOperation(cBrd.SetValvesOp(scale.DrainValve, null)) - .EnterState(); - do - { - e = StateMachine.WaitRunDevsRunOps(); - if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } - } - while (e.Contains(Event.ValvesBusy)); - } - - double massStart = MeasurementCorrection.CorrectedValue(StartMass.Val, scale.Corrections); double massEnd = MeasurementCorrection.CorrectedValue(EndMass.Val, scale.Corrections); double densityOut = Formulas.WaterDensityFromTempPress((TempUpStat.Average + TempDownStat.Average) / 2, @@ -823,7 +899,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance double buoyancy = Formulas.Buoyancy(); double massOfEvaporatedWater = (double)(tMass2 - tMass1) * outPath.Scale.EvaporationRate(TempDivStat.Average); double volumeCTV = 1000.0 * buoyancy * (massEnd - massStart + massOfEvaporatedWater) / densityOut; - if (debugLevel == Common.DebugMode.Simulate) volumeCTV = test.Volume; + double massCTV = buoyancy * (massEnd - massStart + massOfEvaporatedWater); + if (debugLevel == Common.DebugMode.Simulate) volumeCTV = test.Volume; double refEnergy = Energy.Sum * volumeCTV / VolumeForEnergy.Sum; /// [J]=[J]*[l]/[l] @@ -989,6 +1066,20 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance } } + if (test.DoDrainingAfter) + { + State.Create(string.Format("{0}({1}) : Open the drain valve", test.Method, test.Name)) + .AddOperation(checkUiOp) + .AddOperation(cBrd.SetValvesOp(scale.DrainValve, null)) + .EnterState(); + do + { + e = StateMachine.WaitRunDevsRunOps(); + if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; } + } + while (e.Contains(Event.ValvesBusy)); + } + //------------------------------------------------ Bridge.OnActivity(this, Strings.Test_completed); //------------------------------------------------ @@ -1026,6 +1117,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance /// Main results tstRslt.VolumeCTV = volumeCTV; /// [l] 1000.0f is because density is in [kg/m3] tstRslt.Flow = 3.6 * volumeCTV / tstRslt.TestTime; /// [m3/h] + tstRslt.MassCTV = massCTV; /// [kg] 1000.0f is because density is in [kg/m3] + tstRslt.MassFlow = 3.6 * massCTV / tstRslt.TestTime; /// [kg/h] if (cBrd is ControlBoard.Uni.UniCB) { @@ -1034,6 +1127,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance tstRslt.ConstMasterCorr = outPath.FlowMeter.LtrPerPulseCorrected(tstRslt.Flow, tstRslt.TempDownMean); tstRslt.VolumeMaster = tstRslt.ConstMasterRaw * tstRslt.PulsesMaster; /// [l] volume from the master flow meter tstRslt.ConstMaster = (tstRslt.VolumeMaster != 0) ? (tstRslt.ConstMasterRaw * tstRslt.VolumeCTV / tstRslt.VolumeMaster) : tstRslt.ConstMasterCorr; + tstRslt.MassConstMaster = (tstRslt.PulsesMaster != 0) ? (tstRslt.MassCTV / tstRslt.PulsesMaster) : tstRslt.ConstMasterCorr; } else { @@ -1193,18 +1287,74 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance if (meterRslt != null && regReader != null) { meterRslt.RegReaderType = (int)regReader.RegisterReaderType; + ComponentProcedure procParamsEntity = test.Procedure.GetProcedureParamsEntity(regReader.Name); + + try + { + if (regReader.RegisterReaderType == RegisterReaderType.Pulses) + { + XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TBF.Rig.RegisterReaders.PulsesFromUniCB.RRProcParams) })[0]; + TBF.Rig.RegisterReaders.PulsesFromUniCB.RRProcParams tmp = Serializer.Deserialize(new StringReader(procParamsEntity.Parameters.ToString())) as TBF.Rig.RegisterReaders.PulsesFromUniCB.RRProcParams; + regReader.PulsesPerLtr = tmp.PulsesPerLtr; + regReader.QuantityUnits = tmp.Units; + } + else if (regReader.RegisterReaderType == RegisterReaderType.Manual) + { + XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TBF.Rig.RegisterReaders.StandingStartStop.RRProcParams) })[0]; + TBF.Rig.RegisterReaders.StandingStartStop.RRProcParams tmp = Serializer.Deserialize(new StringReader(procParamsEntity.Parameters.ToString())) as TBF.Rig.RegisterReaders.StandingStartStop.RRProcParams; + regReader.PulsesPerLtr = tmp.PulsesPerLtr; + regReader.QuantityUnits = tmp.Units; + } + else + { + //MessageBox.Show("Cannot create or initialize a printer", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + } + } + catch (Exception ex) + { + log.ErrorFormat(string.Format("Error during RegisterReader parameters deserialization. regReader.Name='{0}', regReader.ClassName='{1}', Exception: {2}", + regReader.Name, + regReader.ClassName, + ex)); + } + meterRslt.PulsesPerLiter = regReader.PulsesPerLtr; - meterRslt.VolumeStart = 0.0d;//regReader.BeginWMState; - meterRslt.VolumeEnd = 0.0d;//regReader.EndWMState; - meterRslt.VolumeMeter = 0.0d;//Math.Abs(meterRslt.VolumeEnd - meterRslt.VolumeStart); + meterRslt.VolumeStart = regReader.BeginWMState;//0.0d;//regReader.BeginWMState; + meterRslt.VolumeEnd = regReader.EndWMState;//0.0d;//regReader.EndWMState; + meterRslt.VolumeMeter = Math.Abs(meterRslt.VolumeEnd - meterRslt.VolumeStart);//0.0d;//Math.Abs(meterRslt.VolumeEnd - meterRslt.VolumeStart); + meterRslt.MassMeter = Math.Abs(meterRslt.VolumeEnd - meterRslt.VolumeStart); meterRslt.VolumeRef = tstRslt.VolumeCTV; /// liter + meterRslt.MassRef = tstRslt.MassCTV; /// kg meterRslt.PulsesMeter = meterRslt.VolumeMeter; meterRslt.PulsesMaster = tstRslt.PulsesMaster; meterRslt.TestTime = tstRslt.TestTime; - meterRslt.Error = 100.0d;//Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef); - meterRslt.Passed = (meterRslt.Error >= test.GetErrLimLo(tstRslt.VolumeCTV, tstRslt.TestTime) + test.Uncertainty) + //meterRslt.Error = 100.0d;//Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef); + double Error = 0; + if (meterRslt.GetQuantityFromUnits() == "Mass") + Error = Formulas.ErrorFromVolumes(meterRslt.MassMeter, meterRslt.MassRef); + else + Error = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef); + + meterRslt.Error = Error; + /*meterRslt.Passed = (meterRslt.Error >= test.GetErrLimLo(tstRslt.VolumeCTV, tstRslt.TestTime) + test.Uncertainty) && (meterRslt.Error <= test.GetErrLimHi(tstRslt.VolumeCTV, tstRslt.TestTime) - test.Uncertainty) - && (tstRslt.ErrorFlags == 0); + && (tstRslt.ErrorFlags == 0);*/ + var ErrLimLo_Volume = test.GetErrLimLo(tstRslt.VolumeCTV, tstRslt.TestTime); + var ErrLimHi_Volume = test.GetErrLimHi(tstRslt.VolumeCTV, tstRslt.TestTime); + var ErrLimLo_Mass = test.GetErrLimLo(tstRslt.MassCTV, tstRslt.TestTime); + var ErrLimHi_Mass = test.GetErrLimHi(tstRslt.MassCTV, tstRslt.TestTime); + + bool Passed; + if (meterRslt.GetQuantityFromUnits() == "Mass") + Passed = (meterRslt.Error >= ErrLimLo_Volume + test.Uncertainty) && + (meterRslt.Error <= ErrLimHi_Volume - test.Uncertainty) && + (tstRslt.ErrorFlags == 0); + else + Passed = (meterRslt.Error >= ErrLimLo_Mass + test.Uncertainty) && + (meterRslt.Error <= ErrLimHi_Mass - test.Uncertainty) && + (tstRslt.ErrorFlags == 0); + + meterRslt.Passed = Passed; meterRslt.TestDone = false; tstRslt.TestDone = false; tstRslt.TestMeasured = true;