tbf/TBF/Rig/TestMethods/FlyingStart/FlyingStartSeq.cs
Michal Buzik 52bd0d01ce Restore Genesis communication and Q3 calibration from special branches
A – Registration and execution
- Register GenesisCommunication Factory in the component list.
- Separate the Genesis form and sequence from iPerl communication.

B – Communication activities
- Restore initialization, connection, PCB reading, password and login.
- Include grouped login, mode switching and disconnection.
- Support processing up to 10 slots.

C1 – Input calibration factors
- Read three factors from Water meters / Text1–Text3.
- Validate integer values in the range 1–65535.
- Preserve the default of 15625 when all three fields are empty.

D – Q3 calibration
- Connect the Prepare Q3 → measurement → Write Q3 workflow.
- Add channel processing to FlyingStart and FlyingStartMassCollection.
- Reset previous measurement data and validate calculated factors.
- Mark factors as stored only after StoreCalibration succeeds.

E – Results and database
- Store calibration factors separately for each meter and channel.
- Add result entities, mappings and Q3 data.
- Extend DB.cs / EnsureSchema to create and update the schema.
- Preserve compatibility with the existing binary format.

Validation:
- Debug build and 18 tests passed.
- Simulated communication runs follow the same activity sequence.
- The complete Q3 workflow has not yet been verified on hardware.

Known limitation:
- An inherited mismatch in simulated responses and error propagation
  can produce an incorrect OK result; this change does not fix it.
2026-09-09 15:04:49 +02:00

1249 lines
59 KiB
C#

///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Text;
using log4net;
using Common;
using Config.Entities;
using Results.Entities;
using TBF.Rig;
using TBF.Rig.GenericDevices;
using TBF.Boxes;
using TBF.Resources;
using TBF.Rig.RegisterReaders.GenesisRegReader.implementations;
using TBF.Rig.Sequences;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
using TBF.UiBridge;
namespace TBF.Rig.TestMethods.FlyingStart
{
public class FlyingStartSeq : Sequences.SequenceBase
{
private static readonly ILog log = LogManager.GetLogger(typeof(FlyingStartSeq));
/// <summary>
/// Check capabilities of devces in the output path required for this test method
/// </summary>
/// <param name="devices">Devices</param>
/// <returns>true when capabilities of devices are OK</returns>
public static bool CheckDeviceCaps(Config.Entities.Test test, OutputPath devices, out string message)
{
if (!(StateMachine.ControlBoardMain is ControlBoard.Uni.UniCB))
{
/// Control board does not support this method
message = string.Format("{0}: {1}", test.Name, Strings.Test_bench_does_not_suport_selected_test_method);
return false;
}
if (!(devices.FlowMeter is TBF.Rig.GenericDevices.IFlowMeter))
{
/// Flow meter is missing
message = string.Format("{0}: {1}", test.Name, Strings.Missing_a_flow_meter);
return false;
}
if (!(devices.RegValve is GenericDevices.IRegValve))
{
/// Regulation valve is missing
message = string.Format("{0}: {1}", test.Name, Strings.Missing_a_regulation_valve);
return false;
}
message = string.Empty;
return true;
}
/// <summary>
/// Flying start mass collection method sequence
/// </summary>
/// <param name="test">Test entity</param>
/// <returns>
/// Event.Done . . . . . . . OK
/// Event.UiCmdStop . . . . Stopped by the user using the on-screen button STOP
/// Event.OpArgumentError . Target flow is out of range
/// Event.Error . . . . . . Unspecified error
/// </returns>
public IList<Event> Execute(Config.Entities.Test test, int repetitionNr, bool isLastRepetition,
Compound.TestParams compoundTestParams,
HeatMeters.TestParams heatMetersTestParams,
Common.DebugMode debugLevel)
{
if (debugLevel == Common.DebugMode.Simulate)
{
return Simulate(test, repetitionNr, isLastRepetition, compoundTestParams, heatMetersTestParams, debugLevel);
}
ControlBoard.Uni.UniCB cBrd = StateMachine.ControlBoardMain as ControlBoard.Uni.UniCB;
if ((outPath.FlowMeter is IFlowMeterSingle) &&
(outPath.FlowMeter as IFlowMeterSingle).GetRange(test.TempLimLo, test.TempLimHi) == -1)
{
Bridge.OnError(this, Strings.Flow_meter_temperature_range_does_not_fit_this_test_conditions);
return new List<Event> { Event.ConfigurationError }; /// or Event.UiCmdStop ???
}
IList<Event> e; /// Events from currently running operations
Event retVal = Event.Done;
checkUiOp = new Operations.CheckUIOp(true); /// Runs in more then one state
processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, heatMetersTestParams != null);
if (cBrd is ControlBoard.Uni.UniCB)
{
int[] filters = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
if (sensPath != null && sensPath.RegisterReaders != null)
{
foreach (var rr in sensPath.RegisterReaders)
{
IRegReaderPulses rrPls = rr as IRegReaderPulses;
if (rrPls != null && rrPls.Position >= 1 && rrPls.Position <= 8)
{
filters[rrPls.Position - 1] = rrPls.Filter;
}
}
}
(cBrd as ControlBoard.Uni.UniCB).SetFiltersPidShortPulses(filters, outPath.PidCoef, test.ShortPulses);
}
IList<IOperation> readTempPressOps = new List<IOperation>();
if (benchPath.TempMtrUp != null) readTempPressOps.Add(benchPath.TempMtrUp.ReadTempOp(ref TempUp));
if (benchPath.TempMtrDown != null) readTempPressOps.Add(benchPath.TempMtrDown.ReadTempOp(ref TempDown));
if (benchPath.PressMtrUp != null) readTempPressOps.Add(benchPath.PressMtrUp.ReadPressureOp(ref PressUp));
if (benchPath.PressMtrDown != null) readTempPressOps.Add(benchPath.PressMtrDown.ReadPressureOp(ref PressDown));
if (benchPath.PressMtrDelta != null) readTempPressOps.Add(benchPath.PressMtrDelta.ReadPressureOp(ref PressDelta));
if (benchPath.ElectricMtrUp != null) readTempPressOps.Add(benchPath.ElectricMtrUp.ReadPressureOp(ref ElectricUp));
if (benchPath.ElectricMtrDown != null) readTempPressOps.Add(benchPath.ElectricMtrDown.ReadPressureOp(ref ElectricDown));
if (benchPath.ElectricMtrDelta != null) readTempPressOps.Add(benchPath.ElectricMtrDelta.ReadPressureOp(ref ElectricDelta));
if (heatMetersPath != null) readTempPressOps.Add(heatMetersPath.TMeterRefWarm1.ReadTempOp(ref TempRefHi1));
if (heatMetersPath != null) readTempPressOps.Add(heatMetersPath.TMeterRefWarm2.ReadTempOp(ref TempRefHi2));
if (heatMetersPath != null) readTempPressOps.Add(heatMetersPath.TMeterRefCold1.ReadTempOp(ref TempRefLo1));
if (heatMetersPath != null) readTempPressOps.Add(heatMetersPath.TMeterRefCold2.ReadTempOp(ref TempRefLo2));
int totalPulses = Convert.ToInt32(test.Volume / outPath.FlowMeter.LtrPerPulse);
///============================================================================================
/// Read pressure and temperature once before calling Bridge.OnTestSelected(...)
State.Create(string.Format("{0}({1}) : Measuring process data", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (e.Contains(Event.Busy));
/// Start the test, initialize test results
Bridge.OnTestSelected(this, new TestSelectedEventArgs(test, repetitionNr, inPath, benchPath, outPath, sensPath, heatMetersPath));
string testName = Results.Utils.GetTestName(test.Name, test.Repeats, repetitionNr);
TestStartTime = DateTime.Now;
// Genesis switch
//bool atleastOneGenesis = GenesisHeadBatch.Start(sensPath.RegisterReaders, Program.LocalSettings.LastSNTexts);
//log.Info($"Genesis - atleastOneGenesis = {atleastOneGenesis}");
///
/// Optionally display prompt to emerge temperature meters to appropriate baths for heat meters test
///
IOperation heatMetersPromptOp = null;
if (heatMetersTestParams != null && !string.IsNullOrEmpty(heatMetersTestParams.Prompt))
{
/// Make sure the CycleBeginForm is closed
if (UIFlowControl.Stop == WaitBeginFormClosed()) goto stopTest;
heatMetersPromptOp = new Operations.MessageBoxOp(heatMetersTestParams.Prompt);
}
//------------------------------------------------
Bridge.OnActivity(this, Strings.Starting_the_pump);
//------------------------------------------------
if (inPath.Pump is GenericDevices.IPumpFM) (inPath.Pump as GenericDevices.IPumpFM).TurnOn(test.PumpPower);
///
State.Create(string.Format("{0}({1}) : Starting the pump", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
//.AddOperation(new Operations.SetAllRegulValvesOp(inPath.RegulValves, inPath.RegulValvesPct, 60))
.AddOperation(heatMetersPromptOp)
.AddOperation(inPath.Pump != null ? cBrd.SetValvesOp(inPath.Pump, null) : null)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
}
while (e.Contains(Event.ValvesBusy) /* || !e.Contains(Event.AllPositionsReached)*/);
if (test.TimePump2StartV > 0)
{
State.Create(string.Format("{0}({1}) : Waiting after the pump started", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(new Operations.TimerOp(test.TimePump2StartV))
.AddOperation(heatMetersPromptOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (!e.Contains(Event.TimerExpired));
}
if (benchPath.StopBFValve != null)
{
State.Create(string.Format("{0}({1}) : Opening the stop backflow valve", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(cBrd.SetValvesOp(benchPath.StopBFValve, null))
.AddOperation(heatMetersPromptOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
}
while (!e.Contains(Event.ValvesSet));
}
if (test.TimeBeforeFlow > 0)
{
State.Create(string.Format("{0}({1}) : Waiting before flow setting process starts", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(new Operations.TimerOp(test.TimeBeforeFlow))
.AddOperation(heatMetersPromptOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (!e.Contains(Event.TimerExpired));
}
//------------------------------------------------
Bridge.OnActivity(this, Strings.Setting_the_flow);
//------------------------------------------------
int flowSetTime0 = StateMachine.Time;
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)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
if (e.Contains(Event.OpArgumentError)) { retVal = Event.OpArgumentError; goto stopTest; }
if (TestAndLogUiCmdStop(test,e)) { retVal = Event.UiCmdStop; goto stopTest; }
if (e.Contains(Event.RegulValveTimeOut))
{
Bridge.OnError(this, Strings.Flow_adjustment_failed);
retVal = Event.RecoverableError;
goto stopTest;
}
if (e.Contains(Event.Next)) goto flow_set;
}
while (!e.Contains(Event.FlowReached));
flow_set:
int flowSetTime = StateMachine.Time - flowSetTime0;
double currentFlow = RefFlow.Val;
if (heatMetersTestParams != null && heatMetersPath != null)
{
//---------------------------------------------------
Bridge.OnActivity(this, Strings.Setting_temperature);
//---------------------------------------------------
int lastTimeSec = StateMachine.Time;
double Tw_last = 0;
double Tc_last = 0;
State.Create(string.Format("{0}({1}) : Checking if the temperature is stable", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(heatMetersPromptOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
if (e.Contains(Event.Next)) goto temperature_set;
if (TempRefHi1.Val != 0 && TempRefHi2.Val != 0 && TempRefLo1.Val != 0 && TempRefLo2.Val != 0)
{
if (StateMachine.Time - lastTimeSec > 10 || StateMachine.Time - lastTimeSec < 0)
{
double Tw = (TempRefHi1.Val + TempRefHi2.Val) / 2;
double Tc = (TempRefLo1.Val + TempRefLo2.Val) / 2;
if (heatMetersTestParams.TempWarmLo <= Tw && Tw <= heatMetersTestParams.TempWarmHi &&
heatMetersTestParams.TempColdLo <= Tc && Tc <= heatMetersTestParams.TempColdHi &&
Math.Abs(Tw - Tw_last) <= heatMetersTestParams.ChangeInTimeWarm &&
Math.Abs(Tc - Tc_last) <= heatMetersTestParams.ChangeInTimeCold &&
Math.Abs(TempRefHi1.Val - TempRefHi2.Val) <= heatMetersTestParams.DeltaTempWarm &&
Math.Abs(TempRefLo1.Val - TempRefLo2.Val) <= heatMetersTestParams.DeltaTempCold)
{
goto temperature_set;
}
lastTimeSec = StateMachine.Time;
Tw_last = Tw;
Tc_last = Tc;
}
}
}
while (true);
}
else if (!string.IsNullOrEmpty(test.TempControl) && benchPath.TempMtrUp != null && benchPath.TempMtrDown != null)
{
//---------------------------------------------------
Bridge.OnActivity(this, Strings.Setting_temperature);
//---------------------------------------------------
State.Create(string.Format("{0}({1}) : Wait until the water temperature is within limits", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
if (e.Contains(Event.Next)) goto temperature_set;
if ((test.TempLimLo <= TempUp.Val) && (TempUp.Val <= test.TempLimHi) &&
(test.TempLimLo <= TempDown.Val) && (TempDown.Val <= test.TempLimHi))
{
goto temperature_set;
}
}
while (true);
}
temperature_set:
//TODO genesis - check with genesis switch
/*if (atleastOneGenesis)
{
log.Info($"Genesis - Starting... Test Name:{test.Name.ToLower()}.");
if (test.Name.ToLower().Contains("calib"))
{
log.Info("Genesis - Calibration starting.");
GenesisHeadBatch.BatchHolder.Value.MetersLogin();
GenesisHeadBatch.BatchHolder.Value.MetersInitCalibration();
} else if (test.Name.ToLower().Contains("init"))
{
log.Info("Genesis - Init measurement starting.");
GenesisHeadBatch.BatchHolder.Value.MetersLogin();
GenesisHeadBatch.BatchHolder.Value.MetersInitMeasurement();
}
}*/
///
/// Prepare cameras, ROI-s and measurementOperations
///
/// Find ROI-s
IList<GenericDevices.IRegReaderLiveCamera> rois = new List<GenericDevices.IRegReaderLiveCamera>();
foreach (var rr in sensPath.RegisterReaders)
{
GenericDevices.IRegReaderLiveCamera cameraRoI = rr as GenericDevices.IRegReaderLiveCamera;
if ((cameraRoI != null) && cameraRoI.Detected)
{
rois.Add(cameraRoI);
}
}
/// Find cameras
IList<GenericDevices.ICamera> cameras = new List<GenericDevices.ICamera>();
foreach (var roi in rois)
{
if (roi.Camera != null && !cameras.Contains(roi.Camera))
{
roi.Camera.ClearRoiParams();
cameras.Add(roi.Camera);
}
}
/// Register ROI-parameters to cameras
foreach (var roi in rois) roi.RegisterRoiToCamera();
/// Prepare measurementOperations
IList<IOperation> cameraMeasurementOps = new List<IOperation>();
foreach (var camera in cameras) cameraMeasurementOps.Add(camera.MeasurementOp());
/// Prepare datastream read operations
IList<IOperation> readDatastreamOps = new List<IOperation>();
if (sensPath != null && sensPath.RegisterReaders != null)
{
foreach (var rr in sensPath.RegisterReaders)
{
if (rr is IRegReaderDatastream datastreamRR)
{
(datastreamRR).TestIsGoingToStartSoon(test, repetitionNr);
readDatastreamOps.Add(datastreamRR.ReadDatastreamOp());
}
/*if (rr is GenesisHead) // Genesis - CORDONEL head
(rr as GenesisHead).StartRead(test.Name, BatchRslts.Batch.BatchNr, repetitionNr);*/
}
}
//------------------------------------------------
Bridge.OnActivity(this, Strings.Test_in_progress);
//------------------------------------------------
/// Measurement loop preparation
int estimtdEndTime = StateMachine.Time + (int)test.TestTime;
int remainingTime;
StartNewStatistics(outPath.FlowMeter, BatchRslts.Batch.BatchNr, test, repetitionNr, 0);
/// Measurement loop
State.Create(string.Format("{0}({1}) : FlyingStartStopTestOp is running", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperations(readDatastreamOps)
.AddOperations(cameraMeasurementOps)
.AddOperation(cBrd.FlyingStartStopTestOp(test, test.QfromM3ph(), test.QtoM3ph(), totalPulses))
.AddOperation(processDataLoggingOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.OpArgumentError)) { retVal = Event.OpArgumentError; goto stopTest; }
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
/// Show remaining time
if ((remainingTime = Math.Max(estimtdEndTime - StateMachine.Time, 0)) > 60)
Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Test_in_progress, remainingTime / 60, "min", remainingTime % 60, Strings.sec));
else
Bridge.OnActivity(this, string.Format("{0} ... {1} s", Strings.Test_in_progress, remainingTime));
/// Update statistics
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
UpdateAllStatistics();
#region Heat meters
if (heatMetersTestParams != null)
{
/// Update heatmeter volume and energy values
if (lastEnergyUpdateTime == 0)
{
lastEnergyUpdateTime = StateMachine.Time;
}
else
{
//double deltaTime = (double)(StateMachine.Time - lastEnergyUpdateTime);
double T_in = (TempRefHi1.Val + TempRefHi2.Val) / 2; /// [°C]
double T_out = (TempRefLo1.Val + TempRefLo2.Val) / 2; /// [°C]
double deltaVolume = outPath.FlowMeter.LtrPerPulse * RefPulsesDelta; /// [l]
double deltaEnergy = (0.001 * deltaVolume) * (T_in - T_out) * Formulas.HeatCoefficientWater(16, T_in, T_out, heatMetersTestParams.FlowMeasuredAtHiTempPipe); /// [J] = [m3] * [K] * [J/(m3 K)]
Energy.Update(deltaEnergy);
VolumeForEnergy.Update(deltaVolume);
lastEnergyUpdateTime = StateMachine.Time;
}
}
#endregion
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test));
}
while (!e.Contains(Event.TestCompleted) && !e.Contains(Event.Next)); /// 'Next' button is enabled in Debug version only
//------------------------------------------------
Bridge.OnActivity(this, Strings.Test_in_calculation);
//------------------------------------------------
/// Measurement loop end
StopRecordingStatistics();
/// call StopDataStreamProcessing
if (sensPath != null && sensPath.RegisterReaders != null)
{
foreach (var rr in sensPath.RegisterReaders)
{
var datastreamRR = rr as ISmartReader;
if (datastreamRR != null)
{
datastreamRR.StopDataStreamProcessing();
}
}
}
//TODO genesis - check with genesis switch
/* if (atleastOneGenesis)
{
if (test.Name.ToLower().Contains("calib"))
{
log.Info("Genesis - Calibration stopped.");
GenesisHeadBatch.BatchHolder.Value.MetersStopCalibration();
}
else if (test.Name.ToLower().Contains("Init"))
{
log.Info("Genesis - Init measurement stopped.");
GenesisHeadBatch.BatchHolder.Value.MetersStopMeasurement();
}
}*/
//------------------------------------------------
Bridge.OnActivity(this, Strings.Test_completed);
//------------------------------------------------
TestEndTime = DateTime.Now;
/// Make sure the CycleBeginForm is closed so that water meter data (s/n) can be copied into results
if (heatMetersPromptOp == null)
{
if (UIFlowControl.Stop == WaitBeginFormClosed()) goto stopTest;
}
///
/// Populate TestResult data entity with data
///
Results.Entities.TestRslt tstRslt = BatchRslts.GetTestRslt(testName, test.Part);
bool stopCycle = false;
if (tstRslt != null)
{
Results.Utils.GetCounterStates(tstRslt, Program.LocalSettings.Counters);
/// Raw data
UpdateTempPressDensAmb(tstRslt);
tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName;
tstRslt.StartTime = TestStartTime;
tstRslt.EndTime = TestEndTime;
tstRslt.FlowSetTime = flowSetTime;
tstRslt.TestTime = cBrd.TestTime; /// [s] measurement time
tstRslt.PulsesMaster = Convert.ToDouble(cBrd.RefPulses); /// Pulses of the master flow meter (test total)
tstRslt.MassStartRaw = 0;
tstRslt.MassEndRaw = 0;
tstRslt.TimeBtwnMassMsrmnts = 0;
tstRslt.ConstMasterRaw = outPath.FlowMeter.LtrPerPulse; /// Uncorrected master flowmeter coefficient
tstRslt.VolumeMaster = tstRslt.ConstMasterRaw * tstRslt.PulsesMaster; /// [l] volume from the master flow meter
double flowMID = tstRslt.TestTime == 0 ? 0 : 3.6 * tstRslt.VolumeMaster / tstRslt.TestTime; /// [m3/h]
/// Corrected data
tstRslt.MassStart = 0;
tstRslt.MassEnd = 0;
tstRslt.MassOfEvapWater = 0;
tstRslt.ConstMasterCorr = outPath.FlowMeter.LtrPerPulseCorrected(flowMID, tstRslt.TempDownMean);
/// Main result calculation
tstRslt.VolumeCTV = tstRslt.ConstMasterCorr * tstRslt.PulsesMaster; /// [l] 1000.0f is because density is in [kg/m3]
tstRslt.Flow = tstRslt.TestTime==0 ? 0 : 3.6 * tstRslt.VolumeCTV / tstRslt.TestTime;
tstRslt.ErrorMaster = 0.0; /// Not available without a mass measurement
tstRslt.ConstMaster = tstRslt.ConstMasterCorr;
/// More corrected data
tstRslt.FlowMean = Convert.ToSingle(tstRslt.ConstMaster * RefFlowStat.Average / tstRslt.ConstMasterRaw);
tstRslt.FlowStart = Convert.ToSingle(tstRslt.ConstMaster * RefFlowStat.First / tstRslt.ConstMasterRaw);
tstRslt.FlowEnd = Convert.ToSingle(tstRslt.ConstMaster * RefFlowStat.Last / tstRslt.ConstMasterRaw);
tstRslt.FlowMin = Convert.ToSingle(tstRslt.ConstMaster * RefFlowStat.Min / tstRslt.ConstMasterRaw);
tstRslt.FlowMax = Convert.ToSingle(tstRslt.ConstMaster * RefFlowStat.Max / tstRslt.ConstMasterRaw);
tstRslt.DiverterStart = 0;
tstRslt.DivStart10 = 0;
tstRslt.DivStart50 = 0;
tstRslt.DivStart90 = 0;
tstRslt.DiverterEnd = 0;
tstRslt.DivEnd90 = 0;
tstRslt.DivEnd50 = 0;
tstRslt.DivEnd10 = 0;
long infoFlags = 0;
tstRslt.ErrorFlags = (ErrorFlagsComp != null)
? ErrorFlagsComp.GetErrorFlags(tstRslt, false, false, 0, 0, out infoFlags, out stopCycle) : 0;
tstRslt.InfoFlags = infoFlags;
if (compoundTestParams != null)
{
///
/// Compound meters
///
/// TODO
}
else if (heatMetersTestParams != null)
{
///
/// Heat meters
///
tstRslt.RefEnergy = Energy.Sum * tstRslt.VolumeCTV / VolumeForEnergy.Sum; /// [J] = [J] * [l] / [l]
tstRslt.Custom1 = (float)TempRefHiStat.Average;
tstRslt.Custom2 = (float)TempRefHiStat.First;
tstRslt.Custom3 = (float)TempRefHiStat.Last;
tstRslt.Custom4 = (float)TempRefHiStat.Min;
tstRslt.Custom5 = (float)TempRefHiStat.Max;
tstRslt.Custom6 = (float)TempRefLoStat.Average;
tstRslt.Custom7 = (float)TempRefLoStat.First;
tstRslt.Custom8 = (float)TempRefLoStat.Last;
tstRslt.Custom9 = (float)TempRefLoStat.Min;
tstRslt.Custom10 = (float)TempRefLoStat.Max;
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
{
if (!test.IsPartCompatible(Utils.PartNr(i + 1, BatchRslts.Batch.Compound))) continue;
Results.Entities.MeterTestRslt volumeRslt = BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.HeatMeterVolume);
Results.Entities.MeterTestRslt energyRslt = BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.HeatMeterEnergy);
Rig.GenericDevices.IRegReader volumeRegReader =
(sensPath.RegisterReaders.Length > 2 * i) ? sensPath.RegisterReaders[2 * i] : null;
Rig.GenericDevices.IRegReader energyRegReader =
(sensPath.RegisterReaders.Length > 2 * i + 1) ? sensPath.RegisterReaders[2 * i + 1] : null;
if (volumeRslt != null && volumeRegReader != null)
{
volumeRslt.PulsesPerLiter = volumeRegReader.PulsesPerLtr; /// [l ^ -1]
volumeRslt.PulsesMeter = Convert.ToDouble(volumeRegReader.WMPulses);
volumeRslt.PulsesMaster = Convert.ToDouble(volumeRegReader.WMRefPulses);
volumeRslt.VolumeStart = 0;
volumeRslt.VolumeEnd = 0;
volumeRslt.VolumeMeter = volumeRslt.PulsesMeter * volumeRegReader.LtrsPerPulse; /// [l]
volumeRslt.VolumeRef = volumeRslt.PulsesMaster * tstRslt.ConstMaster; /// [l]
volumeRslt.TestTime = tstRslt.TestTime; /// [s]
volumeRslt.Error = Formulas.ErrorFromVolumes(volumeRslt.VolumeMeter, volumeRslt.VolumeRef);
volumeRslt.Passed = !heatMetersTestParams.EvaluateVolume ||
((volumeRslt.Error >= test.GetErrLimLo(tstRslt.VolumeCTV, tstRslt.TestTime) + test.Uncertainty) &&
(volumeRslt.Error <= test.GetErrLimHi(tstRslt.VolumeCTV, tstRslt.TestTime) - test.Uncertainty) &&
(tstRslt.ErrorFlags == 0));
volumeRslt.TestDone = true;
tstRslt.TestDone = true;
}
if (energyRslt != null && energyRegReader != null)
{
energyRslt.PulsesPerLiter = energyRegReader.PulsesPerLtr; /// [kWh ^ -1]
energyRslt.PulsesMeter = Convert.ToDouble(energyRegReader.WMPulses);
energyRslt.PulsesMaster = Convert.ToDouble(energyRegReader.WMRefPulses);
energyRslt.VolumeStart = 0;
energyRslt.VolumeEnd = 0;
energyRslt.VolumeRef = tstRslt.RefEnergy * (energyRslt.PulsesMaster / tstRslt.PulsesMaster); /// [J]
energyRslt.VolumeMeter = energyRslt.PulsesMeter * Common.Units.ConvertFrom(Common.Unit.kWh, energyRegReader.LtrsPerPulse); /// [J]
energyRslt.TestTime = tstRslt.TestTime; /// [s]
energyRslt.Error = Formulas.ErrorFromVolumes(energyRslt.VolumeMeter, energyRslt.VolumeRef);
energyRslt.Passed = (energyRslt.Error >= heatMetersTestParams.ErrorLimitLo)
&& (energyRslt.Error <= heatMetersTestParams.ErrorLimitHi)
&& (tstRslt.ErrorFlags == 0);
energyRslt.TestDone = true;
tstRslt.TestDone = true;
}
}
}
else
{
///
/// Single meters
///
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
{
if (!test.IsPartCompatible(Utils.PartNr(i + 1, BatchRslts.Batch.Compound))) continue;
Results.Entities.MeterTestRslt meterRslt = BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.Single);
GenericDevices.IRegReader regReader = sensPath.RegisterReaders[i];
GenericDevices.IRegReaderDatastream dstrReader = regReader as GenericDevices.IRegReaderDatastream;
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IRegReaderLiveCamera cameraRoi = regReader as GenericDevices.IRegReaderLiveCamera;
//GenesisHead Genesis = regReader as GenesisHead;
TBF.Rig.RegisterReaders.GenesisRegReader.implementations.GenesisSmartReader GenesisSmart = regReader as TBF.Rig.RegisterReaders.GenesisRegReader.implementations.GenesisSmartReader;
if (meterRslt != null && regReader != null)
{
meterRslt.RegReaderType = (int)regReader.RegisterReaderType;
meterRslt.PulsesPerLiter = regReader.PulsesPerLtr;
meterRslt.PulsesMeter = Convert.ToDouble(regReader.WMPulses);
/*if (Genesis != null)
{
Genesis.Stop(tstRslt.TestTime, tstRslt.VolumeCTV);
meterRslt.TimestampStart = Genesis.TimestampSecStart;
meterRslt.TimestampEnd = Genesis.TimestampSecEnd;
meterRslt.TestTime = Genesis.WMTestTime;
meterRslt.VolumeStart = Genesis.BeginWMState;
meterRslt.VolumeEnd = Genesis.EndWMState; /// liter
meterRslt.VolumeMeter = Math.Abs(Genesis.WMVolume);
meterRslt.VolumeRef = tstRslt.VolumeCTV;
if (GenesisHeadBatch.MeterIdDetailResults == null)
{
Genesis.Log("MeterIdDetailResults na!");
}
else
{
if (Genesis.DetailedResults != null)
{
try
{
GenesisHeadBatch.MeterIdDetailResults.Add(meterRslt.SerialNr(), Genesis.DetailedResults);
}
catch (Exception ex) { Genesis.Log(ex.Message.ToString()); }
}
else
{
Genesis.Log("DetailedResults na!");
}
}
Genesis.Log("VolumeRef=" + meterRslt.VolumeRef);
Genesis.Log("TestTime Meter =" + meterRslt.TestTime + "S, test time ref =" + tstRslt.TestTime + "s");
Genesis.Log(" results for " + test.Name);
Genesis.Log(" Ref Vol = " + meterRslt.VolumeRef + " m³");
Genesis.Log(" Ref Time = " + tstRslt.TestTime + " s");
Genesis.Log(" Meter Time = " + meterRslt.TestTime + " s");
Genesis.Log(" Meter Vol = " + meterRslt.VolumeMeter + " m³");
var calError = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef);
Genesis.Log(" MeterError = " + calError.ToString() + " %");
}
else*/
if (GenesisSmart != null)
{
log.Debug("GenesisSmart - store data on end!");
int CH1=0, CH2=1, CH3=2;
CalculateMeterResults(meterRslt, GenesisSmart, tstRslt,GenesisSmart.TimestampSecStart, GenesisSmart.TimestampSecEnd, GenesisSmart.VolumeLtrStart, GenesisSmart.VolumeLtrEnd);
//Init Calculate Calibration
GenesisSmart.RefVolume = meterRslt.VolumeRef;
GenesisSmart.RefTime = meterRslt.TestTime;
//Store Raw Calibration Data to database
WaterMeterParentCopy(i, CH1,testName,meterRslt,GenesisSmart,tstRslt);
WaterMeterParentCopy(i, CH2,testName,meterRslt,GenesisSmart,tstRslt);
WaterMeterParentCopy(i, CH3,testName,meterRslt,GenesisSmart,tstRslt);
}
else
{
if (dstrReader != null)
{
meterRslt.TimestampStart = dstrReader.TimestampSecStart;
meterRslt.TimestampEnd = dstrReader.NoSamples
? (dstrReader.TimestampSecStart + tstRslt.TestTime)
: dstrReader.TimestampSecEnd;
meterRslt.TestTime = meterRslt.TimestampEnd - meterRslt.TimestampStart;
meterRslt.VolumeStart = dstrReader.VolumeLtrStart; /// liter
meterRslt.VolumeEnd = dstrReader.VolumeLtrEnd; /// liter
meterRslt.VolumeMeter =
Math.Abs(dstrReader.VolumeLtrEnd - dstrReader.VolumeLtrStart);
meterRslt.VolumeRef = tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
meterRslt.PulsesMaster =
tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
if (iPerl != null)
{
if (iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode &
(int)Results.Entities.ResultCode
.OptoErrorCodeMask) == 0)
{
meterRslt.WaterMeter.ResultCode |= iPerl.ResultCode;
}
#if IPERL
meterRslt.WaterMeter.CalibFactor = iPerl.CalibFactor;
meterRslt.FlipMode = iPerl.ConfigStruct != null && iPerl.ConfigStruct.FlipMode.HasValue
? (int?)iPerl.ConfigStruct.FlipMode.Value
: null;
meterRslt.ExtraDataPath = iPerl.ExtraDataPath;
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 1)
meterRslt.X1 = iPerl.X[0];
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 2)
meterRslt.X2 = iPerl.X[1];
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 3)
meterRslt.X3 = iPerl.X[2];
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 4)
meterRslt.X4 = iPerl.X[3];
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 5)
meterRslt.X5 = iPerl.X[4];
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 6)
meterRslt.X6 = iPerl.X[5];
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 7)
meterRslt.X7 = iPerl.X[6];
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 8)
meterRslt.X8 = iPerl.X[7];
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 9)
meterRslt.X9 = iPerl.X[8];
#endif
iPerl.LastTestResult2 =
iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
}
}
else if (cameraRoi != null)
{
meterRslt.TimestampStart = cameraRoi.TimestampStart; /// second
meterRslt.TimestampEnd = cameraRoi.TimestampEnd; /// second
meterRslt.VolumeStart = cameraRoi.VolumeStart; /// liter
meterRslt.VolumeEnd = cameraRoi.VolumeEnd; /// liter
meterRslt.VolumeMeter = cameraRoi.VolumeEnd - cameraRoi.VolumeStart; /// liter
if (meterRslt.VolumeMeter != 0)
{
/// Normal measurement with camera
meterRslt.TestTime =
cameraRoi.TimestampEnd - cameraRoi.TimestampStart; /// second
meterRslt.VolumeRef = tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
meterRslt.PulsesMaster =
tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
}
else
{
/// None or one pulse from the water meter using camera
meterRslt.TestTime = tstRslt.TestTime;
meterRslt.VolumeRef = tstRslt.VolumeCTV;
meterRslt.PulsesMaster = tstRslt.PulsesMaster;
}
}
else
{
meterRslt.PulsesMaster = Convert.ToDouble(regReader.WMRefPulses);
meterRslt.VolumeStart = 0;
meterRslt.VolumeEnd = 0;
meterRslt.VolumeMeter = meterRslt.PulsesMeter * regReader.LtrsPerPulse; /// liter
///
if (regReader.WMPulses >= 1)
{
/// Normal measurement
meterRslt.TestTime = cBrd.TestTimeWM(regReader.Position);
meterRslt.VolumeRef = meterRslt.PulsesMaster * tstRslt.ConstMaster; /// liter
}
else
{
/// None or one pulse from the water meter
meterRslt.TestTime = tstRslt.TestTime;
meterRslt.VolumeRef = tstRslt.VolumeCTV; /// liter
}
}
}
meterRslt.Error = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef);
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);
meterRslt.TestDone = true;
tstRslt.TestDone = true;
#if ORACLE_DB
meterRslt.ErrorBC = meterRslt.Error;
#endif
}
}
}
tstRslt.Components = Results.Entities.Components
.UpdateList(BatchRslts.ComponentsList,
new Results.Entities.Components((BenchInfo != null) ? BenchInfo.TestBenchId : 1,
(BenchInfo != null) ? BenchInfo.TestBenchName : "testbench",
inPath.Pump != null ? inPath.Pump.Name : string.Empty,
outPath.FlowMeter != null ? outPath.FlowMeter.Name : string.Empty,
string.Empty,
outPath.RegValve != null ? outPath.RegValve.Name : string.Empty,
outPath.Diverter != null ? outPath.Diverter.Name : string.Empty));
/// Update water meter error flags
if (ErrorFlagsComp != null)
{
if (BatchRslts.Batch != null && BatchRslts.Batch.WaterMeters != null)
{
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
{
if (BatchRslts.Batch.WaterMeters[i] != null && !BatchRslts.Batch.WaterMeters[i].Disabled)
{
long wmInfoFlags;
BatchRslts.Batch.WaterMeters[i].ErrorFlags = ErrorFlagsComp.GetWMtrErrorFlags(BatchRslts.Batch.WaterMeters[i].MeterTestRslts, out wmInfoFlags);
BatchRslts.Batch.WaterMeters[i].InfoFlags = wmInfoFlags;
}
}
}
}
/// Update results
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(testName, tstRslt));
}
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.TransitionAfter));
/// Append the results to the CSV-file
allResults.Info(TestResult2CsvLine(testName, test.Part));
//TODO genesis - process result writing
//ProcessDatabaseResultsWriting(test, tstRslt);
if (stopCycle) retVal = Event.ErrorFlagsStop;
stopTest:
/*GenesisHeadBatch.BatchHolder.Value.RemoveAllMeters();*/
StopRecordingStatistics();
cBrd.StopAll(false);
///
/// Quit this sequence
///
if (isLastRepetition || retVal == Event.UiCmdStop
|| retVal == Event.OpArgumentError
|| retVal == Event.RecoverableError
|| retVal == Event.ErrorFlagsStop
|| retVal == Event.Error
|| retVal == Event.ConfigurationError)
{
cBrd.StopAll(false);
}
return new List<Event> { retVal };
}
//backup how work genesis - not a clean code!
// private void ProcessDatabaseResultsWriting(Test test, TestRslt tstRslt)
// {
// IList<Event> e;
// if (!String.IsNullOrEmpty(test.Procedure.ResultsWriter))
// {
// string[] writers = StateMachine.Procedure.ResultsWriter.Split(new char[] { '~' });
// foreach (var writerName in writers)
// {
// IResultsWriter writer = TbfComponents.FindComponent(writerName) as IResultsWriter;
// if (writer != null && writer is )
// {
// var SensusLaWriter = ((DB.SensusLa.Database)writer);
//
// State.Create(string.Format("{0}({1}) : Store results into db.", test.Method, test.Name))
// .AddOperation(checkUiOp)
// .AddOperation(SensusLaWriter.WriteResultsOp(tstRslt, BatchRslts, GenesisHeadBatch.MeterIdDetailResults))
// .EnterState();
// do
// {
// e = StateMachine.WaitRunDevsRunOps();
// }
// while (!e.Contains(Event.Error) && !e.Contains(Event.ResultsWritten) && !e.Contains(Event.ResultsNotWritten));
// }
// }
// }
// }
private const int CountCh = 3;
private static void WaterMeterParentCopy(int i, int iCH, string testName, MeterTestRslt meterRslt,
GenesisSmartReader genesisSmart,
TestRslt tstRslt)
{
try
{
WaterMeter waterMeterParent = BatchRslts.Batch.WaterMeters[i];
int wmNrChX = (i * CountCh) + BatchRslts.WMPositionsCount + iCH + 1;
String sSerialNr =
(string.IsNullOrEmpty(waterMeterParent.SerialNr) ? (i + 1).ToString() : waterMeterParent.SerialNr) +
"_CH" + (iCH + 1);
WaterMeter chXWaterMeter = null;
//------ add new water meter to batch ------
if (BatchRslts.Batch.WaterMeters.Count < wmNrChX || BatchRslts.Batch.WaterMeters[wmNrChX - 1] == null)
{
log.Debug("add new water meter to batch, CH = " + (iCH + 1) + " CH = " + wmNrChX);
chXWaterMeter = new WaterMeter()
{
MeterTestRslts = new List<MeterTestRslt>(),
};
//This will delete each setting before
chXWaterMeter.CopyContentFrom(waterMeterParent);
chXWaterMeter.Batch = BatchRslts.Batch;
chXWaterMeter.WaterMeterData = waterMeterParent.WaterMeterData;
chXWaterMeter.SerialNr = sSerialNr;
chXWaterMeter.WMPosition = wmNrChX;
chXWaterMeter.Q3Channel = iCH + 1;
chXWaterMeter.YearOfProduction = waterMeterParent.YearOfProduction;
chXWaterMeter.Disabled = false;
BatchRslts.Batch.WaterMeters.Add(chXWaterMeter);
}
else
{
chXWaterMeter = BatchRslts.Batch.WaterMeters[wmNrChX - 1];
chXWaterMeter.Batch = BatchRslts.Batch;
chXWaterMeter.WaterMeterData = waterMeterParent.WaterMeterData;
chXWaterMeter.SerialNr = sSerialNr;
chXWaterMeter.WMPosition = wmNrChX;
chXWaterMeter.Q3Channel = iCH + 1;
chXWaterMeter.YearOfProduction = waterMeterParent.YearOfProduction;
chXWaterMeter.Disabled = false;
}
//~------ add new water meter to batch ------~
//create copy of meterRslt and add to additionalResultsByChannel
MeterTestRslt meterTestRsltChX = new MeterTestRslt(chXWaterMeter, meterRslt.TestRslt,
(CompoundMeterId)meterRslt.CompoundMeterId);
meterTestRsltChX.Q3Channel = iCH + 1;
chXWaterMeter.MeterTestRslts.Add(meterTestRsltChX);
MeterTestRslt chanelXMeterRslt =
BatchRslts.GetMeterTestRslt(testName, wmNrChX - 1, Common.CompoundMeterId.Single);
if (chanelXMeterRslt != null)
{
chanelXMeterRslt?.CopyContentFrom(meterRslt);
if (iCH == 0)
{
chanelXMeterRslt.Q3Channel = 1;
CalculateMeterResults(chanelXMeterRslt, genesisSmart, tstRslt,
genesisSmart.TimestampSecStartRawCh1,
genesisSmart.TimestampSecEndRawCh1, genesisSmart.VolumeLtrStartRawCh1,
genesisSmart.VolumeLtrEndRawCh1);
try
{
TestRsltCalibFactor testRsltCalibFactor = null;
if (tstRslt.GetCalibrationFactors(waterMeterParent).Count > 0)
{
testRsltCalibFactor = tstRslt.GetCalibrationFactors(waterMeterParent)[0];
}
else
{
//store in table
testRsltCalibFactor = new TestRsltCalibFactor();
tstRslt.GetCalibrationFactors(waterMeterParent).Add(testRsltCalibFactor);
testRsltCalibFactor.CalibFactorIndex = 1;
}
testRsltCalibFactor.TestRslt = chanelXMeterRslt.TestRslt;
testRsltCalibFactor.TimeStart = genesisSmart.TimestampSecStartRawCh1;
testRsltCalibFactor.TimeEnd = genesisSmart.TimestampSecEndRawCh1;
testRsltCalibFactor.VolumeStart = genesisSmart.VolumeLtrStartRawCh1;
testRsltCalibFactor.VolumeEnd = genesisSmart.VolumeLtrEndRawCh1;
testRsltCalibFactor.Error = chanelXMeterRslt.Error;
}
catch (Exception ex)
{
log.Error("Error in store to DB result set CH1", ex);
}
}
else if (iCH == 1)
{
chanelXMeterRslt.Q3Channel = 2;
CalculateMeterResults(chanelXMeterRslt, genesisSmart, tstRslt,
genesisSmart.TimestampSecStartRawCh2,
genesisSmart.TimestampSecEndRawCh2, genesisSmart.VolumeLtrStartRawCh2,
genesisSmart.VolumeLtrEndRawCh2);
try
{
TestRsltCalibFactor testRsltCalibFactor = null;
if (tstRslt.GetCalibrationFactors(waterMeterParent).Count > 1)
{
testRsltCalibFactor = tstRslt.GetCalibrationFactors(waterMeterParent)[1];
}
else
{
//store in table
testRsltCalibFactor = new TestRsltCalibFactor();
tstRslt.GetCalibrationFactors(waterMeterParent).Add(testRsltCalibFactor);
testRsltCalibFactor.CalibFactorIndex = 2;
}
testRsltCalibFactor.TestRslt = chanelXMeterRslt.TestRslt;
testRsltCalibFactor.TimeStart = genesisSmart.TimestampSecStartRawCh2;
testRsltCalibFactor.TimeEnd = genesisSmart.TimestampSecEndRawCh2;
testRsltCalibFactor.VolumeStart = genesisSmart.VolumeLtrStartRawCh2;
testRsltCalibFactor.VolumeEnd = genesisSmart.VolumeLtrEndRawCh2;
testRsltCalibFactor.Error = chanelXMeterRslt.Error;
}
catch (Exception ex)
{
log.Error("Error in store to DB result set CH2", ex);
}
}
else if (iCH == 2)
{
chanelXMeterRslt.Q3Channel = 3;
CalculateMeterResults(chanelXMeterRslt, genesisSmart, tstRslt,
genesisSmart.TimestampSecStartRawCh3,
genesisSmart.TimestampSecEndRawCh3, genesisSmart.VolumeLtrStartRawCh3,
genesisSmart.VolumeLtrEndRawCh3);
try
{
TestRsltCalibFactor testRsltCalibFactor = null;
if (tstRslt.GetCalibrationFactors(waterMeterParent).Count > 2)
{
testRsltCalibFactor = tstRslt.GetCalibrationFactors(waterMeterParent)[2];
}
else
{
//store in table
testRsltCalibFactor = new TestRsltCalibFactor();
tstRslt.GetCalibrationFactors(waterMeterParent).Add(testRsltCalibFactor);
testRsltCalibFactor.CalibFactorIndex = 3;
}
testRsltCalibFactor.TestRslt = chanelXMeterRslt.TestRslt;
testRsltCalibFactor.TimeStart = genesisSmart.TimestampSecStartRawCh3;
testRsltCalibFactor.TimeEnd = genesisSmart.TimestampSecEndRawCh3;
testRsltCalibFactor.VolumeStart = genesisSmart.VolumeLtrStartRawCh3;
testRsltCalibFactor.VolumeEnd = genesisSmart.VolumeLtrEndRawCh3;
testRsltCalibFactor.Error = chanelXMeterRslt.Error;
}
catch (Exception ex)
{
log.Error("Error in store to DB result set CH3", ex);
}
}
if (!genesisSmart.EnableShowChanels)
{
chXWaterMeter.Disabled = !genesisSmart.EnableShowChanels;
//meterTestRsltChX.TestDone = false;
}
else
{
chXWaterMeter.Disabled = false;
meterTestRsltChX.TestDone = true;
}
meterTestRsltChX.Passed = meterRslt.Passed;
}
}
catch (Exception ex)
{
log.Error("Error in WaterMeterParentCopy", ex);
}
}
private static void CalculateMeterResults(MeterTestRslt meterRslt, IRegReaderDatastream dstrReader, TestRslt tstRslt, double dstrReaderTimestampSecStart, double dstrReaderTimestampSecEnd, double dstrReaderVolumeLtrStart, double dstrReaderVolumeLtrEnd)
{
try
{
meterRslt.TimestampStart = dstrReaderTimestampSecStart;
meterRslt.TimestampEnd = !dstrReader.NoSamples
? dstrReaderTimestampSecEnd
: (dstrReaderTimestampSecStart + tstRslt.TestTime);
meterRslt.TestTime = meterRslt.TimestampEnd - meterRslt.TimestampStart;
meterRslt.VolumeStart = dstrReaderVolumeLtrStart; /// liter
meterRslt.VolumeEnd = dstrReaderVolumeLtrEnd; /// liter
meterRslt.VolumeMeter =
Math.Abs(dstrReaderVolumeLtrEnd - dstrReaderVolumeLtrStart);
meterRslt.VolumeRef = tstRslt.TestTime == 0
? tstRslt.VolumeCTV
: tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
meterRslt.PulsesMaster = tstRslt.TestTime == 0
? tstRslt.PulsesMaster
: tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
meterRslt.Error = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter,
meterRslt.VolumeRef); // Error based on volume difference
}catch(Exception ex)
{
log.Error($"Error in calculate meter results, meterRslt.Name:{meterRslt.Name()} Calculation Bug Detail:", ex);
}
}
IList<Event> Simulate(Config.Entities.Test test, int repetitionNr, bool isLastRepetition,
Compound.TestParams compoundTestParams,
HeatMeters.TestParams heatMetersTestParams,
Common.DebugMode debugLevel)
{
///
/// Test method simulation
///
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
if (compoundTestParams != null)
{
if (test.Name.ToLower().Contains("nok")) MakeSimulatedCompound(test, 1, 0, 4.7f, 0.9f);
else MakeSimulatedCompound(test, 1, 0, 0.7f, 1.0f);
}
else if (heatMetersTestParams != null)
{
MakeSimulatedHeatMeters(test, 1, 0, 1.5f, 1000000, heatMetersTestParams.ErrorLimitLo, heatMetersTestParams.ErrorLimitHi, heatMetersTestParams.EvaluateVolume);
}
else if (test.Name.ToLower().Contains("q3")) MakeSimulated(test, 1, 0, -0.5f);
else if (test.Name.ToLower().Contains("q2")) MakeSimulated(test, 1, 0, 0.5f);
else if (test.Name.ToLower().Contains("q1")) MakeSimulated(test, 1, 0, -5.1f);
else MakeSimulated(test, 1, 0, 0.9f);
//TODO bumi do simulate foe Q3 Calibration
///
/// Single meters
///
SimulateQ3CalibrationData(test,1, 0, -5.1f);
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Completed));
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, BatchRslts.GetTestRslt(Results.Utils.GetTestName(test.Name, 1, 1), 0)));
allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file
//------------------------------------------------------------------
Bridge.OnActivity(this, string.Format("{0} simulation", test.Name));
//------------------------------------------------------------------
State.Create(string.Format("{0}({1}) : Simulating {0}", test.Method, test.Name))
.AddOperation(checkUiOp)
.EnterState();
IList<Event> e = StateMachine.WaitRunDevsRunOps();
return new List<Event> { TestAndLogUiCmdStop(test, e) ? Event.UiCmdStop : Event.Done };
}
private void SimulateQ3CalibrationData(Test test,int repetitionNr, int part, float errorPctBase)
{
string testName = test.Name;
string fullTestName = Results.Utils.GetTestName(test.Name, test.Repeats, repetitionNr);
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(fullTestName, part);
Results.Utils.GetCounterStates(tstRslt, Program.LocalSettings.Counters);
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
{
if (!test.IsPartCompatible(Utils.PartNr(i + 1, BatchRslts.Batch.Compound))) continue;
Results.Entities.MeterTestRslt meterRslt =
BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.Single);
GenericDevices.IRegReader regReader = sensPath.RegisterReaders[i];
TBF.Rig.RegisterReaders.GenesisRegReader.implementations.GenesisSmartReader GenesisSmart =
regReader as TBF.Rig.RegisterReaders.GenesisRegReader.implementations.GenesisSmartReader;
if (GenesisSmart != null)
{
log.Debug("GenesisSmart - store data on end!");
int CH1 = 0, CH2 = 1, CH3 = 2;
CalculateMeterResults(meterRslt, GenesisSmart, tstRslt, GenesisSmart.TimestampSecStart,
GenesisSmart.TimestampSecEnd, GenesisSmart.VolumeLtrStart, GenesisSmart.VolumeLtrEnd);
//Init Calculate Calibration
GenesisSmart.RefVolume = meterRslt.VolumeRef;
GenesisSmart.RefTime = meterRslt.TestTime;
//Store Raw Calibration Data to database
WaterMeterParentCopy(i, CH1, testName, meterRslt, GenesisSmart, tstRslt);
WaterMeterParentCopy(i, CH2, testName, meterRslt, GenesisSmart, tstRslt);
WaterMeterParentCopy(i, CH3, testName, meterRslt, GenesisSmart, tstRslt);
}
}
}
}
}