Q2 correction for standard process and MakeQ2CorrectionFrom(...) modified to satisfy MID, Q2 correction done when OoR.
This commit is contained in:
parent
e1bfa71310
commit
6fd67cdf08
@ -174,7 +174,7 @@ namespace Results
|
||||
return Batch.GetTestRslt(name, part);
|
||||
}
|
||||
|
||||
public MeterTestRslt GetMeterTestRslt(string name, int wmNr0, CompoundMeterId meterId)
|
||||
public MeterTestRslt GetMeterTestRslt(string name, int wmNr0, CompoundMeterId meterId = CompoundMeterId.Single)
|
||||
{
|
||||
if (Batch.WaterMeters != null && Batch.WaterMeters.Count > wmNr0 && !Batch.WaterMeters[wmNr0].Disabled)
|
||||
{
|
||||
|
||||
@ -340,7 +340,7 @@ namespace Results.Entities
|
||||
return GetMeterTestRslt(testName, CompoundMeterId.SingleOrCompound);
|
||||
}
|
||||
|
||||
public virtual MeterTestRslt GetMeterTestRslt(string testName, CompoundMeterId meterId)
|
||||
public virtual MeterTestRslt GetMeterTestRslt(string testName, CompoundMeterId meterId = CompoundMeterId.Single)
|
||||
{
|
||||
if (string.IsNullOrEmpty(testName)) return null;
|
||||
if (Disabled) return null;
|
||||
|
||||
@ -1954,7 +1954,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
var args = string.IsNullOrEmpty(restOfLine) ? new string[0] : restOfLine.Split(new char[] { ' ' });
|
||||
|
||||
Results.Entities.MeterTestRslt q2adjResult; /// The only test or the 1st test (the test in R-L direction)
|
||||
Results.Entities.TestData q2adjTestData;
|
||||
Results.Entities.TestData q2adjTestData; /// The 2nd test in L-R direction in case tests in both directions are done
|
||||
///
|
||||
if (args.Length == 0)
|
||||
{
|
||||
@ -2063,30 +2063,6 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
|
||||
double errLimitLo = test.ErrLimLo + test.Uncertainty;
|
||||
double errLimitHi = test.ErrLimHi - test.Uncertainty;
|
||||
///
|
||||
if (q2adjResult.Error < errLimitLo || errLimitHi < q2adjResult.Error ||
|
||||
(q2adjResult2 != null && (q2adjResult2.Error < errLimitLo || errLimitHi < q2adjResult2.Error)))
|
||||
{
|
||||
/// At least one of Q2 errors is out of range for Q2 correction
|
||||
log.WarnFormat("OoR => no Q2 correction: Pos={0}, PCB#={1}, ***Q2_RL err={2}%***, ***Q2_LR err={3}%***, [Lo={4}%, Hi={5}%]",
|
||||
ihead.Name,
|
||||
ihead.SerialNr,
|
||||
q2adjResult.Error.ToString("F2"),
|
||||
q2adjResult2 != null ? q2adjResult2.Error.ToString("F2") : string.Empty,
|
||||
errLimitLo.ToString("F2"),
|
||||
errLimitHi.ToString("F2"));
|
||||
|
||||
resultStr = string.Format("Q2 error is out of range => no Q2 correction");
|
||||
rfidDataLogger.InfoFormat("{0}({1}): Q2 error ({2},{3}) is out of range ({4}..{5}) => Failed",
|
||||
ihead.Name,
|
||||
ihead.SerialNr,
|
||||
q2adjResult.Error.ToString("F2"),
|
||||
q2adjResult2 != null ? q2adjResult2.Error.ToString("F2") : string.Empty,
|
||||
errLimitLo.ToString("F2"),
|
||||
errLimitHi.ToString("F2"));
|
||||
return CommErr.Q2OutOfRange;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Calculate Q2 correction factor(s) from an error measured at Q2
|
||||
@ -2113,37 +2089,69 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
///
|
||||
if (q2CorrType == Q2CorrType.Standard ||
|
||||
q2CorrType == Q2CorrType.Standard_incl_05 ||
|
||||
q2CorrType == Q2CorrType.Standard_plus_incl_05 ||
|
||||
q2CorrType == Q2CorrType.UpdateBothQ2FactorsTestRLDir)
|
||||
q2CorrType == Q2CorrType.Standard_plus_incl_05)
|
||||
{
|
||||
///
|
||||
/// Standard process
|
||||
/// Standard process (RL)
|
||||
/// No 2nd Q2 test, MakeQ2CorrectedFrom(...) is used to calculate Q2 error
|
||||
/// Do not forget to modify iPerlCommunicationSeq.MakeQ2CorrectedFrom(...)
|
||||
///
|
||||
if (q2CorrType == Q2CorrType.Standard && Math.Abs(q2adjResult.Error) <= 0.5)
|
||||
{
|
||||
resultStr = string.Format("Q2 correction = 0 (writing bypassed)");
|
||||
return CommErr.None;
|
||||
}
|
||||
|
||||
q2CorrRL = (q2CorrType == Q2CorrType.Standard_plus_incl_05) ? (int)Math.Round(0.9 * q2Correction) : (int)Math.Round(1.1 * q2Correction);
|
||||
q2CorrLR = (int)Math.Round(0.5 * q2Correction);
|
||||
q2CorrRL = (q3error * q2adjResult.Error < 0) ? Convert.ToInt32(0.9 * q2Correction) : Convert.ToInt32(1.1 * q2Correction);
|
||||
}
|
||||
else if (q2CorrType == Q2CorrType.Dewa ||
|
||||
q2CorrType == Q2CorrType.Dewa_incl_05 ||
|
||||
q2CorrType == Q2CorrType.Dewa_plus_incl_05)
|
||||
{
|
||||
///
|
||||
/// Process for DEWA
|
||||
/// Standard process for the oposite flow direction (LR)
|
||||
/// No 2nd Q2 test, MakeQ2CorrectedFrom(...) is used to calculate Q2 error
|
||||
/// Do not forget to modify iPerlCommunicationSeq.MakeQ2CorrectedFrom(...)
|
||||
///
|
||||
if (q2CorrType == Q2CorrType.Dewa && Math.Abs(q2adjResult.Error) <= 0.5)
|
||||
q2CorrLR = (q3error * q2adjResult.Error < 0) ? Convert.ToInt32(0.9 * q2Correction) : Convert.ToInt32(1.1 * q2Correction);
|
||||
}
|
||||
else if (q2CorrType == Q2CorrType.RL ||
|
||||
q2CorrType == Q2CorrType.RL_incl_05 ||
|
||||
q2CorrType == Q2CorrType.ConditionalUpdateRL)
|
||||
{
|
||||
///
|
||||
/// RL only
|
||||
/// Assuming the 2nd Q2 test is done afterwards
|
||||
/// MakeQ2CorrectedFrom(...) is not used
|
||||
///
|
||||
if (q2CorrType == Q2CorrType.RL && Math.Abs(q2adjResult.Error) <= 0.5)
|
||||
{
|
||||
resultStr = string.Format("Q2 correction = 0 (writing bypassed)");
|
||||
return CommErr.None;
|
||||
}
|
||||
|
||||
/// Use the same correction factor in both directions
|
||||
q2CorrRL = (q2CorrType == Q2CorrType.Dewa_plus_incl_05) ? (int)Math.Round(0.9 * q2Correction2) : (int)Math.Round(1.0 * q2Correction2);
|
||||
q2CorrLR = (q2CorrType == Q2CorrType.Dewa_plus_incl_05) ? (int)Math.Round(0.9 * q2Correction2) : (int)Math.Round(1.0 * q2Correction2);
|
||||
q2CorrRL = Convert.ToInt32(q2Correction);
|
||||
}
|
||||
else if (q2CorrType == Q2CorrType.LR ||
|
||||
q2CorrType == Q2CorrType.LR_incl_05 ||
|
||||
q2CorrType == Q2CorrType.ConditionalUpdateLR)
|
||||
{
|
||||
///
|
||||
/// LR only
|
||||
/// Assuming the 2nd Q2 test is done afterwards
|
||||
/// MakeQ2CorrectedFrom(...) is not used
|
||||
///
|
||||
if (q2CorrType == Q2CorrType.LR && Math.Abs(q2adjResult.Error) <= 0.5)
|
||||
{
|
||||
resultStr = string.Format("Q2 correction = 0 (writing bypassed)");
|
||||
return CommErr.None;
|
||||
}
|
||||
|
||||
q2CorrLR = Convert.ToInt32(q2Correction2);
|
||||
}
|
||||
else if (q2CorrType == Q2CorrType.Update || q2CorrType == Q2CorrType.ConditionalUpdate)
|
||||
{
|
||||
///
|
||||
/// After tests in both directions
|
||||
/// Assuming the 2nd Q2 tests are done afterwards
|
||||
/// MakeQ2CorrectedFrom(...) is not used
|
||||
///
|
||||
q2CorrRL = Convert.ToInt32(q2Correction);
|
||||
q2CorrLR = Convert.ToInt32(q2Correction2);
|
||||
}
|
||||
else if (q2CorrType == Q2CorrType.Greece || q2CorrType == Q2CorrType.Greece_incl_05 || q2CorrType == Q2CorrType.UpdateBothQ2FactorsTestLRDir)
|
||||
{
|
||||
@ -2156,33 +2164,16 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
return CommErr.None;
|
||||
}
|
||||
|
||||
q2CorrRL = (int)Math.Round(2.0 * q2Correction2);
|
||||
q2CorrLR = (int)Math.Round(1.0 * q2Correction2);
|
||||
q2CorrRL = Convert.ToInt32(2.0 * q2Correction2);
|
||||
q2CorrLR = Convert.ToInt32(1.0 * q2Correction2);
|
||||
}
|
||||
else if (q2CorrType == Q2CorrType.RL || q2CorrType == Q2CorrType.RL_incl_05 || q2CorrType == Q2CorrType.ConditionalUpdateRL) /// RL only
|
||||
else if (q2CorrType == Q2CorrType.UpdateBothQ2FactorsTestRLDir)
|
||||
{
|
||||
if (q2CorrType == Q2CorrType.RL && Math.Abs(q2adjResult.Error) <= 0.5)
|
||||
{
|
||||
resultStr = string.Format("Q2 correction = 0 (writing bypassed)");
|
||||
return CommErr.None;
|
||||
}
|
||||
|
||||
q2CorrRL = (int)Math.Round(q2Correction);
|
||||
}
|
||||
else if (q2CorrType == Q2CorrType.LR || q2CorrType == Q2CorrType.LR_incl_05 || q2CorrType == Q2CorrType.ConditionalUpdateLR) /// LR only
|
||||
{
|
||||
if (q2CorrType == Q2CorrType.LR && Math.Abs(q2adjResult.Error) <= 0.5)
|
||||
{
|
||||
resultStr = string.Format("Q2 correction = 0 (writing bypassed)");
|
||||
return CommErr.None;
|
||||
}
|
||||
|
||||
q2CorrLR = (int)Math.Round(q2Correction2);
|
||||
}
|
||||
else if ((q2CorrType == Q2CorrType.Update) || (q2CorrType == Q2CorrType.ConditionalUpdate))
|
||||
{
|
||||
q2CorrRL = (int)Math.Round(q2Correction);
|
||||
q2CorrLR = (int)Math.Round(q2Correction2);
|
||||
///
|
||||
/// Another strange process
|
||||
///
|
||||
q2CorrRL = (q3error * q2adjResult.Error < 0) ? Convert.ToInt32(0.9 * q2Correction) : Convert.ToInt32(1.1 * q2Correction);
|
||||
q2CorrLR = q2CorrRL;
|
||||
}
|
||||
|
||||
|
||||
@ -2192,7 +2183,13 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
if (ihead.CommFailed) return CommErr.CommFailed;
|
||||
|
||||
CommErr error = CommErr.Write;
|
||||
if (q2CorrType == Q2CorrType.RL || q2CorrType == Q2CorrType.RL_incl_05 || q2CorrType == Q2CorrType.ConditionalUpdateRL)
|
||||
|
||||
if (q2CorrType == Q2CorrType.Standard ||
|
||||
q2CorrType == Q2CorrType.Standard_incl_05 ||
|
||||
q2CorrType == Q2CorrType.Standard_plus_incl_05 ||
|
||||
q2CorrType == Q2CorrType.RL ||
|
||||
q2CorrType == Q2CorrType.RL_incl_05 ||
|
||||
q2CorrType == Q2CorrType.ConditionalUpdateRL)
|
||||
{
|
||||
///
|
||||
/// Write R-L Q2 correction factor only
|
||||
@ -2200,11 +2197,17 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
byte[] wrData = new byte[1] { (byte)q2CorrRL };
|
||||
if (0 == WriteRequestPort(ihead, MessageID.MetrologyMemory, Q2CorrFactorsAddrRL, wrData.Length, wrData))
|
||||
{
|
||||
error = CommErr.None;
|
||||
wm.Q2CorrRL = ihead.Q2CorrRL = q2CorrRL;
|
||||
resultStr = string.Format("Q2 correction: RL={0}", q2CorrRL);
|
||||
error = CommErr.None;
|
||||
}
|
||||
}
|
||||
else if (q2CorrType == Q2CorrType.LR || q2CorrType == Q2CorrType.LR_incl_05 || q2CorrType == Q2CorrType.ConditionalUpdateLR)
|
||||
else if (q2CorrType == Q2CorrType.Dewa ||
|
||||
q2CorrType == Q2CorrType.Dewa_incl_05 ||
|
||||
q2CorrType == Q2CorrType.Dewa_plus_incl_05 ||
|
||||
q2CorrType == Q2CorrType.LR ||
|
||||
q2CorrType == Q2CorrType.LR_incl_05 ||
|
||||
q2CorrType == Q2CorrType.ConditionalUpdateLR)
|
||||
{
|
||||
///
|
||||
/// Write L-R Q2 correction factor only
|
||||
@ -2212,8 +2215,9 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
byte[] wrData = new byte[1] { (byte)q2CorrLR };
|
||||
if (0 == WriteRequestPort(ihead, MessageID.MetrologyMemory, Q2CorrFactorsAddrLR, wrData.Length, wrData))
|
||||
{
|
||||
error = CommErr.None;
|
||||
wm.Q2CorrLR = ihead.Q2CorrLR = q2CorrLR;
|
||||
resultStr = string.Format("Q2 correction: LR={0}", q2CorrLR);
|
||||
error = CommErr.None;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2224,15 +2228,47 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
byte[] wrData = new byte[2] { (byte)q2CorrLR, (byte)q2CorrRL };
|
||||
if (0 == WriteRequestPort(ihead, MessageID.MetrologyMemory, Q2CorrFactorsAddr, wrData.Length, wrData))
|
||||
{
|
||||
error = CommErr.None;
|
||||
wm.Q2CorrRL = ihead.Q2CorrRL = q2CorrRL;
|
||||
wm.Q2CorrLR = ihead.Q2CorrLR = q2CorrLR;
|
||||
resultStr = string.Format("Q2 correction: RL={0}, LR={1}", q2CorrRL, q2CorrLR);
|
||||
error = CommErr.None;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Verification disabled on 16.02.2016
|
||||
///
|
||||
|
||||
///
|
||||
/// Q2 correction factor was successfully written to the water meter.
|
||||
/// Check whether the original error at Q2 was within limits.
|
||||
///
|
||||
if (error == CommErr.None &&
|
||||
(q2adjResult.Error < errLimitLo || errLimitHi < q2adjResult.Error ||
|
||||
(q2adjResult2 != null && (q2adjResult2.Error < errLimitLo || errLimitHi < q2adjResult2.Error))))
|
||||
{
|
||||
resultStr = resultStr + " (OoR)";
|
||||
|
||||
/// At least one of Q2 errors is out of range for Q2 correction
|
||||
log.WarnFormat("OoR => anyhow Q2 correction was done: Pos={0}, PCB#={1}, ***Q2_RL err={2}%***, ***Q2_LR err={3}%***, [Lo={4}%, Hi={5}%]",
|
||||
ihead.Name,
|
||||
ihead.SerialNr,
|
||||
q2adjResult.Error.ToString("F2"),
|
||||
q2adjResult2 != null ? q2adjResult2.Error.ToString("F2") : string.Empty,
|
||||
errLimitLo.ToString("F2"),
|
||||
errLimitHi.ToString("F2"));
|
||||
|
||||
rfidDataLogger.InfoFormat("{0}({1}): Q2 error ({2},{3}) is out of range ({4}..{5}) => Failed",
|
||||
ihead.Name,
|
||||
ihead.SerialNr,
|
||||
q2adjResult.Error.ToString("F2"),
|
||||
q2adjResult2 != null ? q2adjResult2.Error.ToString("F2") : string.Empty,
|
||||
errLimitLo.ToString("F2"),
|
||||
errLimitHi.ToString("F2"));
|
||||
|
||||
error = CommErr.Q2OutOfRange;
|
||||
}
|
||||
|
||||
///
|
||||
/// Verification disabled on 16.02.2016
|
||||
///
|
||||
#if false
|
||||
if (error == CommErr.None)
|
||||
{
|
||||
@ -2253,30 +2289,18 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
if ((q2CorrType != Q2CorrType.Update) && (q2CorrType != Q2CorrType.ConditionalUpdate))
|
||||
{
|
||||
wm.Q2ErrWOCorrection = ihead.Q2ErrWOCorrection = q2adjResult.Error;
|
||||
}
|
||||
|
||||
///
|
||||
/// Update WaterMeter entity and IperlHead
|
||||
///
|
||||
if (error == CommErr.None)
|
||||
{
|
||||
if (q2CorrType == Q2CorrType.RL)
|
||||
{
|
||||
resultStr = string.Format("Q2 correction: RL={0}", q2CorrRL);
|
||||
}
|
||||
else if (q2CorrType == Q2CorrType.LR)
|
||||
{
|
||||
resultStr = string.Format("Q2 correction: LR={0}", q2CorrLR);
|
||||
}
|
||||
else
|
||||
{
|
||||
resultStr = string.Format("Q2 correction: RL={0}, LR={1}", q2CorrRL, q2CorrLR);
|
||||
}
|
||||
|
||||
rfidDataLogger.WarnFormat("{0}: {1}", ihead.Name, resultStr);
|
||||
|
||||
if ((q2CorrType != Q2CorrType.Update) && (q2CorrType != Q2CorrType.ConditionalUpdate))
|
||||
{
|
||||
wm.Q2ErrWOCorrection = ihead.Q2ErrWOCorrection = q2adjResult.Error;
|
||||
}
|
||||
rfidDataLogger.WarnFormat("{0}({1}): {2}", ihead.Name, ihead.SerialNr, resultStr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2022 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2015-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -572,15 +572,18 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
|
||||
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);
|
||||
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 (meterRslt != null && oriMeterRslt != null)
|
||||
if (iPerl != null && meterRslt != null && oriMeterRslt != null)
|
||||
{
|
||||
#if ORACLE_DB
|
||||
meterRslt.ErrorBC = oriMeterRslt.Error;
|
||||
@ -591,12 +594,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||
meterRslt.VolumeRef = oriMeterRslt.VolumeRef;
|
||||
meterRslt.TestTime = oriMeterRslt.TestTime;
|
||||
|
||||
if (iPerl == null || ((iPerl.Q2CorrRL == 0) && (iPerl.Q2CorrLR == 0)))
|
||||
{
|
||||
/// Either no iPerl head or no Q2 correction
|
||||
meterRslt.Error = oriMeterRslt.Error;
|
||||
}
|
||||
else if (isPlus)
|
||||
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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user