/// /// Copyright (c) 2015-2023 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.Drawing; /// Point definition using log4net; using Common; using Config.Entities; using RestClient; using TBF.Rig.Sequences; using TBF.Resources; using TBF.UiBridge; using Results; namespace TBF.Rig.TestMethods.iPerlCommunication { public class iPerlCommunicationSeq : SequenceBase { private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationSeq)); public const string Q2correctedFromCmd = "Q2 corrected from "; public const string StrictQ2ErrorCheckStr = "Strict Q2 error check "; public const string Q2correctionCheckCmd = "Q2 correction check "; public const string IperlCheckCmd = "iPERL_check "; System.Windows.Forms.Form modelessDlg; /// delegate void iPerlCommFormDlgt(iPerlCommunicationSeq myRef, TestMethod method, Test test, iPerlCommunicationParams testParams); /// void OpenIPerlCommForm(iPerlCommunicationSeq myRef, TestMethod method, Test test, iPerlCommunicationParams testParams) { myRef.modelessDlg = new iPerlCommunicationForm(method, test, testParams); myRef.modelessDlg.Show(); } void CloseIPerlCommForm() { UiBridge.Bridge.OnCloseModelessForm(this, null); modelessDlg = null; } /// /// Flying start mass collection method sequence /// /// Test entity /// /// 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 /// public IList Execute(Test test, int repetitionNr, TestMethod method, iPerlCommunicationParams testParams) { TestMethodCfg cfg = method.Cfg as TestMethodCfg; IList e; /// Events from currently running operations checkUiOp = new Operations.CheckUIOp(true); /// Runs in more then one state modelessDlg = null; processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, false); string cmd; if (testParams.Activity.ToLower().Equals(cmd = iPerlCommunicationForm.GetDefaultQ2CorrectionsStr.ToLower())) { TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 }); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted)); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting)); /// Get 'wmType' from IperlHead procedure parameters int wmType = 0; #if IPERL foreach (var wm in ProcessData.BatchRslts.Batch.WaterMeters) { if (wm != null && !wm.Disabled && wm.WMTypeId() > 0) { wmType = wm.WMTypeId(); break; } } #endif if (cfg.UseWebService) { IsQ2PreCorrectionCalculated = GetQ2PreCorrectionsOrBackups(cfg, wmType, out CalculatedQ2PreCorrectionLR, out CalculatedQ2PreCorrectionRL); } /// Generate test results Results.Entities.TestRslt tstRslt = BatchRslts.GetTestRslt(test.Name, 0); if (tstRslt != null) { tstRslt.StartTime = DateTime.Now; tstRslt.TestDone = true; foreach (var wm in BatchRslts.Batch.WaterMeters) { if (!wm.Disabled) { foreach(var mtr in wm.MeterTestRslts) { if (mtr.TestRslt == tstRslt) { mtr.Passed = !cfg.UseWebService || IsQ2PreCorrectionCalculated; mtr.TestDone = true; break; } } } } } Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed)); Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0))); allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file return new List { Event.Done }; } else if (testParams.Activity.ToLower().Contains(cmd = Q2correctedFromCmd.ToLower())) { TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 }); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted)); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting)); string[] args = testParams.Activity.Substring(cmd.Length).Split(new char[] { ' ' }); string fromTestName = (args.Length >= 1) ? args[0] : string.Empty; bool isPlus = (args.Length >= 2) ? args[1].ToLower().Contains("plus") : false; MakeQ2CorrectedFrom(test.Name, fromTestName, isPlus); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed)); Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0))); allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file return new List { Event.Done }; } else if (testParams.Activity.ToLower().Contains(cmd = StrictQ2ErrorCheckStr.ToLower())) { TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 }); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted)); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting)); string fromTestName = testParams.Activity.Substring(cmd.Length); StrictQ2ErrorCheck(test.Name, fromTestName); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed)); Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0))); allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file return new List { Event.Done }; } else if (testParams.Activity.ToLower().Contains(cmd = Q2correctionCheckCmd.ToLower())) { TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 }); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted)); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting)); string[] testNames = testParams.Activity.Substring(cmd.Length).Split(new char[] { ' ' }); if (testNames.Length >= 2) { CheckQ2Correction(test.Name, testNames[0], testNames[1]); } Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed)); Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, 0))); allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file return new List { Event.Done }; } else if (testParams.Activity.ToLower().Contains(cmd = IperlCheckCmd.ToLower())) { TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 }); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted)); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting)); string[] args = testParams.Activity.Substring(cmd.Length).Split(new char[] { ' ' }); int maxTestIndex = (ProcessData.BenchInfo is DataContainers.BenchInfo.iPerl.Component) ? (ProcessData.BenchInfo as DataContainers.BenchInfo.iPerl.Component).MaxTestIndex : int.MaxValue; Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(test.Name, 0); if (tstRslt != null) { tstRslt.StartTime = DateTime.Now; int wrongMetersCount = 0; string message = string.Empty; for (int i = 0; i < BatchRslts.WMPositionsCount; i++) { Results.Entities.WaterMeter wm = BatchRslts.Batch.WaterMeters[i]; Results.Entities.MeterTestRslt mtr = ProcessData.BatchRslts.GetMeterTestRslt(test.Name, i, CompoundMeterId.Single); ///// Reference to iPerl water meter or null: //TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerlHead = ((sensPath.RegisterReaders != null) && (i < sensPath.RegisterReaders.Length)) // ? (sensPath.RegisterReaders[i] as TestMethods.iPerlCommunication.iPerlHead.IperlHead) // : null; if ((wm != null) && (mtr != null)) { int errorIndicators = 0; bool anyErrorOfThisMeter = false; foreach (var arg in args) { #if TURA_SPECIAL if (arg.ToLower() == "q2factors") { if ((wm.ProdQ2CorrRL != wm.Q2CorrRL) || (wm.ProdQ2CorrLR != wm.Q2CorrLR)) { anyErrorOfThisMeter = true; message += string.Format("Q2 korekčné faktory vodomera {0} nesedia{1}", wm.WMPosition, Environment.NewLine); errorIndicators |= (int)ErrorFlagMask.E26; /// Q2 correction factors not valid } } #endif if (arg.ToLower() == "direction") { //if (wm.Pruefindex > maxTestIndex) //{ // anyErrorOfThisMeter = true; // message += string.Format("Príliš veľa opakovaní testu vodomera {0}{1}", wm.WMPosition, Environment.NewLine); // errorIndicators |= (int)ErrorFlagMask.E27; /// Wrong direction (positive/negative counting) //} } if (arg.ToLower() == "prevworkstep") { if (wm.LastRecordIsNok) { wm.ErrorFlags |= (int)ErrorFlagMask.E28; /// Set E28 } if ((wm.ErrorFlags & (int)ErrorFlagMask.E28) != 0) { anyErrorOfThisMeter = true; message += string.Format("iPerl{0} : Predchádzajúci krok nebol zaznamenaný{1}", wm.WMPosition, Environment.NewLine); errorIndicators |= (int)ErrorFlagMask.E28; /// Previous workstep missing or NOK (production tracing) } } } mtr.TestDone = true; mtr.ErrorIndicators = errorIndicators; /// if (anyErrorOfThisMeter) { /// This iPerl check did not pass mtr.Passed = false; wrongMetersCount++; } else { /// Check passed OK mtr.Passed = true; } } } tstRslt.EndTime = DateTime.Now; tstRslt.TestDone = true; Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed)); Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, tstRslt)); allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file if (wrongMetersCount >= cfg.IperlCheckErrorsToStop) { State.Create("iPerlCommunicationSeq : Show check result") .AddOperation(new Operations.LargeMessageBoxOp(message)) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); } while (!e.Contains(Event.Continue) && !e.Contains(Event.Abort)); if (e.Contains(Event.Abort)) { Bridge.OnError(this, string.Format("Niečo nie je v poriadku !")); return new List { Event.UiCmdStop }; } } } return new List { Event.Done }; } else if (testParams.Activity.ToLower().Contains(cmd = "simulate ")) { TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 }); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted)); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.FlowSetting)); if (testParams.Activity.ToLower().Contains("q3")) MakeSimulated(test, 1, 0, -0.5f); else if (testParams.Activity.Substring(cmd.Length).ToLower() == "q2") MakeSimulated(test, 1, 0, 0.5f); else if (testParams.Activity.Substring(cmd.Length).ToLower() == "q1") MakeSimulated(test, 1, 0, -5.1f); else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound ok") MakeSimulatedCompound(test, 1, 0, 0.7f, 1.0f); else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound nok") MakeSimulatedCompound(test, 1, 0, 4.7f, 0.9f); else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound rise") MakeSimulatedCompound(test, 1, 0, 0.7f, 0.0f); else if (testParams.Activity.Substring(cmd.Length).ToLower() == "compound fall") MakeSimulatedCompound(test, 1, 0, 0.7f, 0.9f); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed)); Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(Common.Utils.GetTestName(test.Name, 1, 1), 0))); allResults.Info(TestResult2CsvLine(test.Name, 0)); /// Append the results to the CSV-file //------------------------------------------------ Bridge.OnActivity(this, testParams.Activity); //------------------------------------------------ State.Create(string.Format("iPerlCommunicationSeq : {0}", testParams.Activity)) .AddOperation(checkUiOp) .EnterState(); e = StateMachine.WaitRunDevsRunOps(); if (TestAndLogUiCmdStop(test, e)) { return new List { Event.UiCmdStop }; } } else { /// /// Show the modeless dialog with error indication /// Program.MainWnd.Invoke(new iPerlCommFormDlgt(OpenIPerlCommForm), new object[] { this, method, test, testParams }); //------------------------------------------------ Bridge.OnActivity(this, Strings.iPerl_Communication_in_progress); //------------------------------------------------ bool stopPressed = false; /// true when STOP button pressed bool completed = false; State.Create("iPerlCommunicationSeq : Wait until the entry form is closed") .AddOperation(checkUiOp) .EnterState(); do { e = StateMachine.WaitRunDevsRunOps(); stopPressed = TestAndLogUiCmdStop(test, e); completed = (modelessDlg is GenericDevices.IHasCompleted) && (modelessDlg as GenericDevices.IHasCompleted).Completed; } while (!stopPressed && !completed); if (stopPressed) { CloseIPerlCommForm(); return new List { Event.UiCmdStop }; } else { TBF.UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(test.Name, Progress.Completed)); } /// Test 'Quit' modelessDlg = null; /// Modeless dialog is closed now } return new List { Event.Done }; } /// /// Read default Q2 correction factors from a REST service (= Web service). /// /// iPerlCommunication component configuration /// Water meter type (WZ Typ) /// Default Q2 correction LR /// Default Q2 correction RL /// true when successful static bool ReadCorrectionsFromWebService(TestMethodCfg cfg, int wmType, out int q2PreCorrectionLR, out int q2PreCorrectionRL) { if (wmType == 0) { /// No REST service call when wmType == 0, factors are 0 q2PreCorrectionLR = 0; q2PreCorrectionRL = 0; return true; } try { GetQ2PreCorrectionClient client = new GetQ2PreCorrectionClient(cfg.BaseUrl); client.GetToken("ReadUser", "sensus", "https://deluh1web03.world.fluidtechnology.net/SensusCore/api/v1/Locations/1/Login2").Wait(); Q2PreCorrection response = client.GetQ2Correction(string.Format(cfg.RelativeUrl, wmType)).Result; if (response != null && response.AreDataCalculated) { q2PreCorrectionLR = response.CorrLR; q2PreCorrectionRL = response.CorrRL; log.WarnFormat("Q2 corrections from a REST client for WM Type = {0} are: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL); return true; } else { log.ErrorFormat("Failed to obtain Q2 corrections from a REST client for WM Type = {0}", wmType); q2PreCorrectionLR = 0; q2PreCorrectionRL = 0; return false; } } catch (Exception exc) { log.ErrorFormat("Failed to obtain Q2 corrections from a REST client for WM Type = {0}: {1}", wmType, exc.Message); q2PreCorrectionLR = 0; q2PreCorrectionRL = 0; return false; } } /// /// Obtain Q2 correction factors from a REST service or from local settings (stored backup values) /// /// iPerlCommunication component configuration /// Water meter type (WZ Typ) /// Default Q2 correction LR /// Default Q2 correction RL /// true when successful public static bool GetQ2PreCorrectionsOrBackups(TestMethodCfg cfg, int wmType, out int q2PreCorrectionLR, out int q2PreCorrectionRL) { /// Get Q2 pre-correction values from REST service bool restOK = ReadCorrectionsFromWebService(cfg, wmType, out q2PreCorrectionLR, out q2PreCorrectionRL); /// Store / load Q2 pre-correction values Point storedValue; if (restOK) { /// Q2 pre-correction values were successfully obtained from a REST service for the specified wmType if (!Program.LocalSettings.Q2PreCorrections.TryGetValue(wmType, out storedValue)) { /// No Q2 pre-correction values in the dictionary for the specified wmType => save them Program.LocalSettings.Q2PreCorrections.Add(wmType, new Point(q2PreCorrectionLR, q2PreCorrectionRL)); log.WarnFormat("Q2 corrections added to dictionary for WM Type = {0}: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL); } else if (storedValue.X != q2PreCorrectionLR || storedValue.Y != q2PreCorrectionRL) { /// Different Q2 pre-correction values in the dictionary for the specified wmType => overwrite them with ones from the REST service Program.LocalSettings.Q2PreCorrections[wmType] = new Point(q2PreCorrectionLR, q2PreCorrectionRL); log.WarnFormat("Q2 corrections modified in dictionary for WM Type = {0}: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL); } else { /// Q2 pre-correction values in the dictionary are the same and were not changed log.WarnFormat("Q2 corrections in dictionary for WM Type = {0} are the same and were not changed", wmType, q2PreCorrectionLR, q2PreCorrectionRL); } } else { /// No Q2 pre-correction values from a REST service => read the dictionary if (Program.LocalSettings.Q2PreCorrections.TryGetValue(wmType, out storedValue)) { /// Q2 pre-correction values successfully read from the dictionary q2PreCorrectionLR = storedValue.X; q2PreCorrectionRL = storedValue.Y; log.WarnFormat("Q2 corrections loaded from dictionary for WM Type = {0}: LR = {1}, RL = {2}", wmType, q2PreCorrectionLR, q2PreCorrectionRL); } else { /// Q2 pre-correction values not found in the dictionary => use zeros q2PreCorrectionLR = 0; q2PreCorrectionRL = 0; log.ErrorFormat("Q2 corrections not found in the dictionary for WM Type = {0}, using zeros", wmType, q2PreCorrectionLR, q2PreCorrectionRL); /// Everything failed => using zero values return false; } } /// Q2 pre-corections were obtained from REST service or stored backup values were used return true; } /// /// Virtually apply Q2 correction to a test used for the correction calculation. /// /// This test name /// Name of Q2 test done before Q2 correction (Q2adj) /// Assuming this test does not have multiple parts (part = 0) void MakeQ2CorrectedFrom(string testName, string oriTestName, bool isPlus = false) { Results.Entities.TestRslt oriTestRslt = ProcessData.BatchRslts.GetTestRslt(oriTestName, 0); Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(testName, 0); if (oriTestRslt == null || tstRslt == null) return; tstRslt.Components = oriTestRslt.Components; /// Auxiliary results, as in SequenceBase.UpdateTemoPressDensAmb() tstRslt.AmbTempMean = oriTestRslt.AmbTempMean; tstRslt.AmbTempStart = oriTestRslt.AmbTempStart; tstRslt.AmbTempEnd = oriTestRslt.AmbTempEnd; tstRslt.AmbTempMin = oriTestRslt.AmbTempMin; tstRslt.AmbTempMax = oriTestRslt.AmbTempMax; tstRslt.AmbPressMean = oriTestRslt.AmbPressMean; tstRslt.AmbPressStart = oriTestRslt.AmbPressStart; tstRslt.AmbPressEnd = oriTestRslt.AmbPressEnd; tstRslt.AmbPressMin = oriTestRslt.AmbPressMin; tstRslt.AmbPressMax = oriTestRslt.AmbPressMax; tstRslt.AmbHumiMean = oriTestRslt.AmbHumiMean; tstRslt.AmbHumiStart = oriTestRslt.AmbHumiStart; tstRslt.AmbHumiEnd = oriTestRslt.AmbHumiEnd; tstRslt.AmbHumiMin = oriTestRslt.AmbHumiMin; tstRslt.AmbHumiMax = oriTestRslt.AmbHumiMax; tstRslt.PressUpMean = oriTestRslt.PressUpMean; tstRslt.PressUpStart = oriTestRslt.PressUpStart; tstRslt.PressUpEnd = oriTestRslt.PressUpEnd; tstRslt.PressUpMin = oriTestRslt.PressUpMin; tstRslt.PressUpMax = oriTestRslt.PressUpMax; tstRslt.PressDownMean = oriTestRslt.PressDownMean; tstRslt.PressDownStart = oriTestRslt.PressDownStart; tstRslt.PressDownEnd = oriTestRslt.PressDownEnd; tstRslt.PressDownMin = oriTestRslt.PressDownMin; tstRslt.PressDownMax = oriTestRslt.PressDownMax; tstRslt.PressDeltaMean = oriTestRslt.PressDeltaMean; tstRslt.PressDeltaStart = oriTestRslt.PressDeltaStart; tstRslt.PressDeltaEnd = oriTestRslt.PressDeltaEnd; tstRslt.PressDeltaMin = oriTestRslt.PressDeltaMin; tstRslt.PressDeltaMax = oriTestRslt.PressDeltaMax; tstRslt.ConductMean = oriTestRslt.ConductMean; tstRslt.ConductStart = oriTestRslt.ConductStart; tstRslt.ConductEnd = oriTestRslt.ConductEnd; tstRslt.ConductMin = oriTestRslt.ConductMin; tstRslt.ConductMax = oriTestRslt.ConductMax; tstRslt.TempUpMean = oriTestRslt.TempUpMean; tstRslt.TempUpStart = oriTestRslt.TempUpStart; tstRslt.TempUpEnd = oriTestRslt.TempUpEnd; tstRslt.TempUpMin = oriTestRslt.TempUpMin; tstRslt.TempUpMax = oriTestRslt.TempUpMax; tstRslt.TempDownMean = oriTestRslt.TempDownMean; tstRslt.TempDownStart = oriTestRslt.TempDownStart; tstRslt.TempDownEnd = oriTestRslt.TempDownEnd; tstRslt.TempDownMin = oriTestRslt.TempDownMin; tstRslt.TempDownMax = oriTestRslt.TempDownMax; tstRslt.TempDivMean = oriTestRslt.TempDivMean; tstRslt.TempDivStart = oriTestRslt.TempDivStart; tstRslt.TempDivEnd = oriTestRslt.TempDivEnd; tstRslt.TempDivMin = oriTestRslt.TempDivMin; tstRslt.TempDivMax = oriTestRslt.TempDivMax; tstRslt.DensityIn = oriTestRslt.DensityIn; tstRslt.DensityLine = oriTestRslt.DensityLine; tstRslt.DensityDiv = oriTestRslt.DensityDiv; tstRslt.StartTime = oriTestRslt.StartTime; tstRslt.EndTime = oriTestRslt.EndTime; tstRslt.FlowSetTime = oriTestRslt.FlowSetTime; tstRslt.TestTime = oriTestRslt.TestTime; tstRslt.PulsesMaster = oriTestRslt.PulsesMaster; tstRslt.ConstMasterRaw = oriTestRslt.ConstMasterRaw; tstRslt.ConstMaster = oriTestRslt.ConstMaster; tstRslt.MassStartRaw = oriTestRslt.MassStartRaw; tstRslt.MassStart = oriTestRslt.MassStart; tstRslt.MassEndRaw = oriTestRslt.MassEndRaw; tstRslt.MassEnd = oriTestRslt.MassEnd; tstRslt.MassOfEvapWater = oriTestRslt.MassOfEvapWater; tstRslt.FlowMass = oriTestRslt.FlowMass; tstRslt.FlowVolume = oriTestRslt.FlowVolume; tstRslt.VolumeCTV = oriTestRslt.VolumeCTV; tstRslt.VolumeMaster = oriTestRslt.VolumeMaster; tstRslt.ErrorMaster = oriTestRslt.ErrorMaster; tstRslt.FlowMean = oriTestRslt.FlowMean; tstRslt.FlowMin = oriTestRslt.FlowMin; tstRslt.FlowMax = oriTestRslt.FlowMax; tstRslt.Custom1 = oriTestRslt.Custom1; tstRslt.Custom2 = oriTestRslt.Custom2; tstRslt.Custom3 = oriTestRslt.Custom3; tstRslt.Custom4 = oriTestRslt.Custom4; tstRslt.Custom5 = oriTestRslt.Custom5; tstRslt.Custom6 = oriTestRslt.Custom6; tstRslt.Custom7 = oriTestRslt.Custom7; tstRslt.Custom8 = oriTestRslt.Custom8; for (int i = 0; i < ProcessData.BatchRslts.WMPositionsCount; i++) { var q3mtr = ProcessData.BatchRslts.GetMeterTestRslt("Q3", i); double q3error = (q3mtr != null) ? q3mtr.Error : 0; Results.Entities.MeterTestRslt oriMeterRslt = ProcessData.BatchRslts.GetMeterTestRslt(oriTestName, i); Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(testName, i); /// Reference to iPerl water meter or null: TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = ((sensPath != null) && (sensPath.RegisterReaders != null) && (i < sensPath.RegisterReaders.Length)) ? (sensPath.RegisterReaders[i] as TestMethods.iPerlCommunication.iPerlHead.IperlHead) : null; if (iPerl != null && meterRslt != null && oriMeterRslt != null) { #if ORACLE_DB meterRslt.ErrorBC = oriMeterRslt.Error; #endif meterRslt.PulsesMeter = oriMeterRslt.PulsesMeter; meterRslt.PulsesMaster = oriMeterRslt.PulsesMaster; meterRslt.PulsesPerLiter = oriMeterRslt.PulsesPerLiter; meterRslt.VolumeRef = oriMeterRslt.VolumeRef; meterRslt.TestTime = oriMeterRslt.TestTime; if (q3error * oriMeterRslt.Error < 0) { /// iPerl with Q2 correction => generate an artificial error equal to +1/10 of the original one (relative to Q2 target error) meterRslt.Error = 0.1 * oriMeterRslt.Error; } else { /// iPerl with Q2 correction => generate an artificial error equal to -1/10 of the original one (relative to Q2 target error) meterRslt.Error = - 0.1 * oriMeterRslt.Error; } meterRslt.VolumeMeter = meterRslt.VolumeRef * (100.0 + meterRslt.Error) / 100.0; double signature = (oriMeterRslt.VolumeEnd > oriMeterRslt.VolumeStart) ? (+1) : (-1); meterRslt.VolumeStart = oriMeterRslt.VolumeStart; meterRslt.VolumeEnd = meterRslt.VolumeStart + signature * meterRslt.VolumeMeter; meterRslt.Passed = (meterRslt.Error >= tstRslt.ErrLimLo() + tstRslt.ErrLimMargin() && meterRslt.Error <= tstRslt.ErrLimHi() - tstRslt.ErrLimMargin()); meterRslt.TestDone = true; tstRslt.TestDone = true; } } } /// /// Evaluate a given Q2 test result agains stricter error limits when Oruefindex == 1. /// /// This test name /// Name of Q2 test done before Q2 correction (Q2adj) /// Assuming this test does not have multiple parts (part = 0) void StrictQ2ErrorCheck(string testName, string oriTestName) { Results.Entities.TestRslt oriTestRslt = ProcessData.BatchRslts.GetTestRslt(oriTestName, 0); Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(testName, 0); if (oriTestRslt == null || tstRslt == null) return; tstRslt.Components = oriTestRslt.Components; /// Auxiliary results, as in SequenceBase.UpdateTemoPressDensAmb() tstRslt.AmbTempMean = oriTestRslt.AmbTempMean; tstRslt.AmbTempStart = oriTestRslt.AmbTempStart; tstRslt.AmbTempEnd = oriTestRslt.AmbTempEnd; tstRslt.AmbTempMin = oriTestRslt.AmbTempMin; tstRslt.AmbTempMax = oriTestRslt.AmbTempMax; tstRslt.AmbPressMean = oriTestRslt.AmbPressMean; tstRslt.AmbPressStart = oriTestRslt.AmbPressStart; tstRslt.AmbPressEnd = oriTestRslt.AmbPressEnd; tstRslt.AmbPressMin = oriTestRslt.AmbPressMin; tstRslt.AmbPressMax = oriTestRslt.AmbPressMax; tstRslt.AmbHumiMean = oriTestRslt.AmbHumiMean; tstRslt.AmbHumiStart = oriTestRslt.AmbHumiStart; tstRslt.AmbHumiEnd = oriTestRslt.AmbHumiEnd; tstRslt.AmbHumiMin = oriTestRslt.AmbHumiMin; tstRslt.AmbHumiMax = oriTestRslt.AmbHumiMax; tstRslt.PressUpMean = oriTestRslt.PressUpMean; tstRslt.PressUpStart = oriTestRslt.PressUpStart; tstRslt.PressUpEnd = oriTestRslt.PressUpEnd; tstRslt.PressUpMin = oriTestRslt.PressUpMin; tstRslt.PressUpMax = oriTestRslt.PressUpMax; tstRslt.PressDownMean = oriTestRslt.PressDownMean; tstRslt.PressDownStart = oriTestRslt.PressDownStart; tstRslt.PressDownEnd = oriTestRslt.PressDownEnd; tstRslt.PressDownMin = oriTestRslt.PressDownMin; tstRslt.PressDownMax = oriTestRslt.PressDownMax; tstRslt.PressDeltaMean = oriTestRslt.PressDeltaMean; tstRslt.PressDeltaStart = oriTestRslt.PressDeltaStart; tstRslt.PressDeltaEnd = oriTestRslt.PressDeltaEnd; tstRslt.PressDeltaMin = oriTestRslt.PressDeltaMin; tstRslt.PressDeltaMax = oriTestRslt.PressDeltaMax; tstRslt.ConductMean = oriTestRslt.ConductMean; tstRslt.ConductStart = oriTestRslt.ConductStart; tstRslt.ConductEnd = oriTestRslt.ConductEnd; tstRslt.ConductMin = oriTestRslt.ConductMin; tstRslt.ConductMax = oriTestRslt.ConductMax; tstRslt.TempUpMean = oriTestRslt.TempUpMean; tstRslt.TempUpStart = oriTestRslt.TempUpStart; tstRslt.TempUpEnd = oriTestRslt.TempUpEnd; tstRslt.TempUpMin = oriTestRslt.TempUpMin; tstRslt.TempUpMax = oriTestRslt.TempUpMax; tstRslt.TempDownMean = oriTestRslt.TempDownMean; tstRslt.TempDownStart = oriTestRslt.TempDownStart; tstRslt.TempDownEnd = oriTestRslt.TempDownEnd; tstRslt.TempDownMin = oriTestRslt.TempDownMin; tstRslt.TempDownMax = oriTestRslt.TempDownMax; tstRslt.TempDivMean = oriTestRslt.TempDivMean; tstRslt.TempDivStart = oriTestRslt.TempDivStart; tstRslt.TempDivEnd = oriTestRslt.TempDivEnd; tstRslt.TempDivMin = oriTestRslt.TempDivMin; tstRslt.TempDivMax = oriTestRslt.TempDivMax; tstRslt.DensityIn = oriTestRslt.DensityIn; tstRslt.DensityLine = oriTestRslt.DensityLine; tstRslt.DensityDiv = oriTestRslt.DensityDiv; tstRslt.StartTime = oriTestRslt.StartTime; tstRslt.EndTime = oriTestRslt.EndTime; tstRslt.FlowSetTime = oriTestRslt.FlowSetTime; tstRslt.TestTime = oriTestRslt.TestTime; tstRslt.PulsesMaster = oriTestRslt.PulsesMaster; tstRslt.ConstMasterRaw = oriTestRslt.ConstMasterRaw; tstRslt.ConstMaster = oriTestRslt.ConstMaster; tstRslt.MassStartRaw = oriTestRslt.MassStartRaw; tstRslt.MassStart = oriTestRslt.MassStart; tstRslt.MassEndRaw = oriTestRslt.MassEndRaw; tstRslt.MassEnd = oriTestRslt.MassEnd; tstRslt.MassOfEvapWater = oriTestRslt.MassOfEvapWater; tstRslt.FlowMass = oriTestRslt.FlowMass; tstRslt.FlowVolume = oriTestRslt.FlowVolume; tstRslt.VolumeCTV = oriTestRslt.VolumeCTV; tstRslt.VolumeMaster = oriTestRslt.VolumeMaster; tstRslt.ErrorMaster = oriTestRslt.ErrorMaster; tstRslt.FlowMean = oriTestRslt.FlowMean; tstRslt.FlowMin = oriTestRslt.FlowMin; tstRslt.FlowMax = oriTestRslt.FlowMax; tstRslt.Custom1 = oriTestRslt.Custom1; tstRslt.Custom2 = oriTestRslt.Custom2; tstRslt.Custom3 = oriTestRslt.Custom3; tstRslt.Custom4 = oriTestRslt.Custom4; tstRslt.Custom5 = oriTestRslt.Custom5; tstRslt.Custom6 = oriTestRslt.Custom6; tstRslt.Custom7 = oriTestRslt.Custom7; tstRslt.Custom8 = oriTestRslt.Custom8; for (int i = 0; i < ProcessData.BatchRslts.WMPositionsCount; i++) { Results.Entities.MeterTestRslt oriMeterRslt = ProcessData.BatchRslts.GetMeterTestRslt(oriTestName, i, CompoundMeterId.Single); Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(testName, i, CompoundMeterId.Single); /// Reference to iPerl water meter or null: TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = ((sensPath != null) && (sensPath.RegisterReaders != null) && (i < sensPath.RegisterReaders.Length)) ? (sensPath.RegisterReaders[i] as TestMethods.iPerlCommunication.iPerlHead.IperlHead) : null; if (meterRslt != null && oriMeterRslt != null) { #if ORACLE_DB meterRslt.ErrorBC = oriMeterRslt.Error; #endif meterRslt.PulsesMeter = oriMeterRslt.PulsesMeter; meterRslt.PulsesMaster = oriMeterRslt.PulsesMaster; meterRslt.PulsesPerLiter = oriMeterRslt.PulsesPerLiter; meterRslt.VolumeRef = oriMeterRslt.VolumeRef; meterRslt.TestTime = oriMeterRslt.TestTime; if (iPerl != null && ProcessData.BatchRslts.Batch.WaterMeters[i] != null && !ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled) { /// Either no iPerl head or no Q2 correction meterRslt.Error = oriMeterRslt.Error; meterRslt.VolumeMeter = oriMeterRslt.VolumeMeter; meterRslt.VolumeStart = oriMeterRslt.VolumeStart; meterRslt.VolumeEnd = oriMeterRslt.VolumeEnd; #if ORACLE_DB if ((ProcessData.BatchRslts.Batch.WaterMeters[i].Pruefindex % 100) == 1) { meterRslt.Passed = (oriMeterRslt.Error >= tstRslt.ErrLimLo() + tstRslt.ErrLimMargin() && oriMeterRslt.Error <= tstRslt.ErrLimHi() - tstRslt.ErrLimMargin()); } else #endif { meterRslt.Passed = oriMeterRslt.Passed; } meterRslt.TestDone = true; tstRslt.TestDone = true; } } } } /// /// Check results of 2 tests: before Q2 correction and after Q2 correction. /// Evaluate whether Q2 correction works OK. /// /// This test name /// Name of Q2 test done before correction /// Name of Q2 test done after correction /// Assuming these tests do not have multiple parts (part = 0) void CheckQ2Correction(string testName, string testNameQ2bc, string testNameQ2ac) { Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(testName, 0); Results.Entities.TestRslt testRsltQ2bc = ProcessData.BatchRslts.GetTestRslt(testNameQ2bc, 0); Results.Entities.TestRslt testRsltQ2ac = ProcessData.BatchRslts.GetTestRslt(testNameQ2ac, 0); if ((tstRslt == null) || (testRsltQ2bc == null) || (testRsltQ2ac == null)) return; tstRslt.Components = testRsltQ2ac.Components; /// Auxiliary results, as in SequenceBase.UpdateTemoPressDensAmb() tstRslt.AmbTempMean = testRsltQ2ac.AmbTempMean; tstRslt.AmbTempStart = testRsltQ2ac.AmbTempStart; tstRslt.AmbTempEnd = testRsltQ2ac.AmbTempEnd; tstRslt.AmbTempMin = testRsltQ2ac.AmbTempMin; tstRslt.AmbTempMax = testRsltQ2ac.AmbTempMax; tstRslt.AmbPressMean = testRsltQ2ac.AmbPressMean; tstRslt.AmbPressStart = testRsltQ2ac.AmbPressStart; tstRslt.AmbPressEnd = testRsltQ2ac.AmbPressEnd; tstRslt.AmbPressMin = testRsltQ2ac.AmbPressMin; tstRslt.AmbPressMax = testRsltQ2ac.AmbPressMax; tstRslt.AmbHumiMean = testRsltQ2ac.AmbHumiMean; tstRslt.AmbHumiStart = testRsltQ2ac.AmbHumiStart; tstRslt.AmbHumiEnd = testRsltQ2ac.AmbHumiEnd; tstRslt.AmbHumiMin = testRsltQ2ac.AmbHumiMin; tstRslt.AmbHumiMax = testRsltQ2ac.AmbHumiMax; tstRslt.PressUpMean = testRsltQ2ac.PressUpMean; tstRslt.PressUpStart = testRsltQ2ac.PressUpStart; tstRslt.PressUpEnd = testRsltQ2ac.PressUpEnd; tstRslt.PressUpMin = testRsltQ2ac.PressUpMin; tstRslt.PressUpMax = testRsltQ2ac.PressUpMax; tstRslt.PressDownMean = testRsltQ2ac.PressDownMean; tstRslt.PressDownStart = testRsltQ2ac.PressDownStart; tstRslt.PressDownEnd = testRsltQ2ac.PressDownEnd; tstRslt.PressDownMin = testRsltQ2ac.PressDownMin; tstRslt.PressDownMax = testRsltQ2ac.PressDownMax; tstRslt.PressDeltaMean = testRsltQ2ac.PressDeltaMean; tstRslt.PressDeltaStart = testRsltQ2ac.PressDeltaStart; tstRslt.PressDeltaEnd = testRsltQ2ac.PressDeltaEnd; tstRslt.PressDeltaMin = testRsltQ2ac.PressDeltaMin; tstRslt.PressDeltaMax = testRsltQ2ac.PressDeltaMax; tstRslt.ConductMean = testRsltQ2ac.ConductMean; tstRslt.ConductStart = testRsltQ2ac.ConductStart; tstRslt.ConductEnd = testRsltQ2ac.ConductEnd; tstRslt.ConductMin = testRsltQ2ac.ConductMin; tstRslt.ConductMax = testRsltQ2ac.ConductMax; tstRslt.TempUpMean = testRsltQ2ac.TempUpMean; tstRslt.TempUpStart = testRsltQ2ac.TempUpStart; tstRslt.TempUpEnd = testRsltQ2ac.TempUpEnd; tstRslt.TempUpMin = testRsltQ2ac.TempUpMin; tstRslt.TempUpMax = testRsltQ2ac.TempUpMax; tstRslt.TempDownMean = testRsltQ2ac.TempDownMean; tstRslt.TempDownStart = testRsltQ2ac.TempDownStart; tstRslt.TempDownEnd = testRsltQ2ac.TempDownEnd; tstRslt.TempDownMin = testRsltQ2ac.TempDownMin; tstRslt.TempDownMax = testRsltQ2ac.TempDownMax; tstRslt.TempDivMean = testRsltQ2ac.TempDivMean; tstRslt.TempDivStart = testRsltQ2ac.TempDivStart; tstRslt.TempDivEnd = testRsltQ2ac.TempDivEnd; tstRslt.TempDivMin = testRsltQ2ac.TempDivMin; tstRslt.TempDivMax = testRsltQ2ac.TempDivMax; tstRslt.DensityIn = testRsltQ2ac.DensityIn; tstRslt.DensityLine = testRsltQ2ac.DensityLine; tstRslt.DensityDiv = testRsltQ2ac.DensityDiv; tstRslt.StartTime = testRsltQ2ac.StartTime; tstRslt.EndTime = testRsltQ2ac.EndTime; tstRslt.FlowSetTime = testRsltQ2ac.FlowSetTime; tstRslt.TestTime = testRsltQ2ac.TestTime; tstRslt.PulsesMaster = testRsltQ2ac.PulsesMaster; tstRslt.ConstMasterRaw = testRsltQ2ac.ConstMasterRaw; tstRslt.ConstMaster = testRsltQ2ac.ConstMaster; tstRslt.MassStartRaw = testRsltQ2ac.MassStartRaw; tstRslt.MassStart = testRsltQ2ac.MassStart; tstRslt.MassEndRaw = testRsltQ2ac.MassEndRaw; tstRslt.MassEnd = testRsltQ2ac.MassEnd; tstRslt.MassOfEvapWater = testRsltQ2ac.MassOfEvapWater; tstRslt.FlowMass = testRsltQ2ac.FlowMass; tstRslt.FlowVolume = testRsltQ2ac.FlowVolume; tstRslt.VolumeCTV = testRsltQ2ac.VolumeCTV; tstRslt.VolumeMaster = testRsltQ2ac.VolumeMaster; tstRslt.ErrorMaster = testRsltQ2ac.ErrorMaster; tstRslt.FlowMean = testRsltQ2ac.FlowMean; tstRslt.FlowMin = testRsltQ2ac.FlowMin; tstRslt.FlowMax = testRsltQ2ac.FlowMax; tstRslt.Custom1 = testRsltQ2ac.Custom1; tstRslt.Custom2 = testRsltQ2ac.Custom2; tstRslt.Custom3 = testRsltQ2ac.Custom3; tstRslt.Custom4 = testRsltQ2ac.Custom4; tstRslt.Custom5 = testRsltQ2ac.Custom5; tstRslt.Custom6 = testRsltQ2ac.Custom6; tstRslt.Custom7 = testRsltQ2ac.Custom7; tstRslt.Custom8 = testRsltQ2ac.Custom8; for (int i = 0; i < ProcessData.BatchRslts.WMPositionsCount; i++) { Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(testName, i, CompoundMeterId.Single); Results.Entities.MeterTestRslt meterRsltQ2bc = ProcessData.BatchRslts.GetMeterTestRslt(testNameQ2bc, i, CompoundMeterId.Single); Results.Entities.MeterTestRslt meterRsltQ2ac = ProcessData.BatchRslts.GetMeterTestRslt(testNameQ2ac, i, CompoundMeterId.Single); if ((meterRslt != null) && (meterRsltQ2bc != null) && (meterRsltQ2ac != null)) { meterRslt.PulsesMeter = meterRsltQ2ac.PulsesMeter; meterRslt.PulsesMaster = meterRsltQ2ac.PulsesMaster; meterRslt.PulsesPerLiter = meterRsltQ2ac.PulsesPerLiter; meterRslt.VolumeRef = meterRsltQ2ac.VolumeRef; meterRslt.TestTime = meterRsltQ2ac.TestTime; meterRslt.VolumeStart = meterRsltQ2ac.VolumeStart; meterRslt.VolumeEnd = meterRsltQ2ac.VolumeEnd; meterRslt.VolumeMeter = meterRsltQ2ac.VolumeMeter; meterRslt.Error = meterRsltQ2ac.Error; meterRslt.TestDone = meterRsltQ2ac.TestDone; tstRslt.TestDone = true; if (((meterRsltQ2bc.Error < -0.51) && (meterRsltQ2ac.Error < meterRsltQ2bc.Error)) || ((meterRsltQ2bc.Error > +0.51) && (meterRsltQ2ac.Error > meterRsltQ2bc.Error))) { meterRslt.Passed = false; /// Q2 correction check failed } else { meterRslt.Passed = true; /// Q2 correction check passed } } } } } }