iPerl communication changes (completed as in branch 12 - Greece).

This commit is contained in:
Milan Hanajik 2017-07-18 08:33:20 +02:00
parent f58bc38450
commit 77a6aff593
4 changed files with 72 additions and 66 deletions

View File

@ -579,7 +579,7 @@ namespace TBF.BenchControl.TestMethods.FlyingStart
#endif
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
iPerl.NominalTestFlow = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
iPerl.NominalTestFlowLph = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
}
else if (cameraRoi != null)
{

View File

@ -936,7 +936,7 @@ namespace TBF.BenchControl.TestMethods.FlyingStartMassCollection
#endif
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
iPerl.NominalTestFlow = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
iPerl.NominalTestFlowLph = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
}
else if (cameraRoi != null)
{

View File

@ -671,7 +671,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
if ((ihead.MuxBoardNr == rfidPortNr) && (ihead.Group == group))
{
wmFound = true;
WaterMeters.WaterMeter.WaterMeter wm = SequenceBase.WaterMeters[waterMeterPositions[j]] as WaterMeters.WaterMeter.WaterMeter; /// WaterMeters.WaterMeter.WaterMeter implements iPerl specific variables
Results.Entities.WaterMeter wm = ProcessData.BatchRslts.WaterMeters[waterMeterPositions[j]];
CommErr error;
string resultStr = string.Empty;
@ -749,7 +749,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="ihead">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static CommErr ReadConfiguration(IperlHead ihead, WaterMeters.WaterMeter.WaterMeter wm, ref string resultStr)
static CommErr ReadConfiguration(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr)
{
///
/// The activity is "Read configuration" (this enables the watermeter, resets error flag)
@ -794,7 +794,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="ihead">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static CommErr SetTestMode(IperlHead ihead, WaterMeters.WaterMeter.WaterMeter wm, ref string resultStr)
static CommErr SetTestMode(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr)
{
if (ihead.CommFailed) return CommErr.CommFailed;
@ -900,7 +900,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="ihead">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static CommErr SetActiveMode(IperlHead ihead, WaterMeters.WaterMeter.WaterMeter wm, ref string resultStr)
static CommErr SetActiveMode(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr)
{
if (OpenPort(ihead) != 0) return CommErr.OpenPort; /// Open RFID port
@ -963,7 +963,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="ihead">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static CommErr ReadCalibration(IperlHead ihead, WaterMeters.WaterMeter.WaterMeter wm, ref string resultStr)
static CommErr ReadCalibration(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr)
{
if (ihead.CommFailed) return CommErr.CommFailed;
@ -979,9 +979,9 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
{
ihead.CalibrationStruct = CalibrationStruct.FromByteArray(calib);
#if IPERL
if (wm != null && wm.OriginalCalibFactor == 0)
if (wm != null && wm.OrigCalibFactor == 0)
{
wm.OriginalCalibFactor = ihead.CalibrationStruct.Calibration;
wm.OrigCalibFactor = ihead.CalibrationStruct.Calibration;
wm.FWVersion = ihead.CalibrationStruct.FWVersionStr();
}
#endif
@ -1004,7 +1004,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="ihead">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static CommErr WriteCalibrationFactor(IperlHead ihead, WaterMeters.WaterMeter.WaterMeter wm, ref string resultStr)
static CommErr WriteCalibrationFactor(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr)
{
if (ihead.CommFailed) return CommErr.CommFailed;
@ -1027,7 +1027,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
{
if (ihead.LastTestResult == null || !ihead.LastTestResult.TestDone) return CommErr.MissingTest;
newCalibFactor = ihead.CalculateNewCalibFactor(ihead.LastTestResult, ihead.CalibrationFactor, factorLimitLo, factorLimitHi);
newCalibFactor = ihead.CalculateNewCalibFactor(ihead.LastTestResult, ihead.CalibFactor, factorLimitLo, factorLimitHi);
}
else if (arguments.Length == 1 && UInt16.TryParse(arguments[0], out val) && val > 0)
{
@ -1063,20 +1063,20 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
}
}
newCalibFactor = ihead.CalculateNewCalibFactor(adjustTestRslt, ihead.CalibrationFactor, ihead.FactorLimitLo, ihead.FactorLimitHi);
newCalibFactor = ihead.CalculateNewCalibFactor(adjustTestRslt, ihead.CalibFactor, ihead.FactorLimitLo, ihead.FactorLimitHi);
}
else
{
if (ihead.LastTestResult == null || !ihead.LastTestResult.TestDone) return CommErr.MissingTest;
newCalibFactor = ihead.CalculateNewCalibFactor(ihead.LastTestResult, ihead.CalibrationFactor, ihead.FactorLimitLo, ihead.FactorLimitHi);
newCalibFactor = ihead.CalculateNewCalibFactor(ihead.LastTestResult, ihead.CalibFactor, ihead.FactorLimitLo, ihead.FactorLimitHi);
}
}
else
{
if (ihead.LastTestResult == null || !ihead.LastTestResult.TestDone) return CommErr.MissingTest;
newCalibFactor = ihead.CalculateNewCalibFactor(ihead.LastTestResult, ihead.CalibrationFactor, ihead.FactorLimitLo, ihead.FactorLimitHi);
newCalibFactor = ihead.CalculateNewCalibFactor(ihead.LastTestResult, ihead.CalibFactor, ihead.FactorLimitLo, ihead.FactorLimitHi);
}
if (newCalibFactor == 0) return CommErr.CalibFactorOoRange;
@ -1134,11 +1134,11 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="ihead">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static CommErr NormalizeCalibrationFactor(IperlHead ihead, WaterMeters.WaterMeter.WaterMeter wm, ref string resultStr)
static CommErr NormalizeCalibrationFactor(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr)
{
if (ihead.CommFailed) return CommErr.CommFailed;
if (ihead.CalibrationFactor <= 5000)
if (ihead.CalibFactor <= 5000)
{
resultStr = "Calibratin factor is OK";
return CommErr.None; /// No need to update the calibration factor
@ -1211,7 +1211,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="ihead">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static CommErr ResetQ2Correction(IperlHead ihead, WaterMeters.WaterMeter.WaterMeter wm, ref string resultStr)
static CommErr ResetQ2Correction(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr)
{
if (ihead.CommFailed) return CommErr.CommFailed;
@ -1274,7 +1274,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="ihead">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static CommErr Reset2HzCorrection(IperlHead ihead, WaterMeters.WaterMeter.WaterMeter wm, ref string resultStr)
static CommErr Reset2HzCorrection(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr)
{
if (ihead.CommFailed) return CommErr.CommFailed;
@ -1321,7 +1321,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
if (error == CommErr.None)
{
resultStr = "2Hz correction reset to 0";
ihead.Hz2CorrectionFactor = 0;
ihead.Hz2Correction = 0;
}
#endif
@ -1391,7 +1391,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
///
if (q2adjResult == null) return CommErr.CommFailed; /// This should never happen
ihead.Q2ErrorWOCorrection = q2adjResult.Error;
ihead.Q2ErrWOCorrection = q2adjResult.Error;
ihead.Q2CorrectionDone = false;
ihead.Q2CorrRFlow = 0;
@ -1404,7 +1404,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
///
/// Standard process
///
if (Math.Abs(ihead.Q2ErrorWOCorrection) <= 0.5)
if (Math.Abs(ihead.Q2ErrWOCorrection) <= 0.5)
{
resultStr = string.Format("Q2 correction = 0 (writing bypassed)");
return CommErr.None;
@ -1423,7 +1423,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
///
/// Process for DEWA
///
if (ihead.Q2ErrorWOCorrection >= 0 && ihead.Q2ErrorWOCorrection <= 1.0)
if (ihead.Q2ErrWOCorrection >= 0 && ihead.Q2ErrWOCorrection <= 1.0)
{
resultStr = string.Format("Q2 correction = 0 (writing bypassed)");
return CommErr.None;
@ -1434,7 +1434,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
return CommErr.None; /// Q2 error is too large, water meter failed anyhow
}
if (ihead.Q2ErrorWOCorrection < 0)
if (ihead.Q2ErrWOCorrection < 0)
{
q2CorrRFlow = (byte)((int)Math.Round(1.1 * q2Correction) & 0x000000FF);
q2CorrLFlow = (byte)((int)Math.Round(1.1 * q2Correction) & 0x000000FF);
@ -1522,7 +1522,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
#if IPERL
if (wm != null)
{
wm.Q2ErrorWOCorrection = ihead.Q2ErrorWOCorrection;
wm.Q2ErrWOCorrection = ihead.Q2ErrWOCorrection;
wm.Q2CorrectionDone = ihead.Q2CorrectionDone;
wm.Q2Correction = ihead.Q2Correction;
wm.Q2CorrRFlow = ihead.Q2CorrRFlow;
@ -1544,7 +1544,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="ihead">Water meter object</param>
/// <param name="resultStr">String passed to caller</param>
/// <returns>true on success</returns>
static CommErr Write2HzCorrection(IperlHead ihead, WaterMeters.WaterMeter.WaterMeter wm, ref string resultStr)
static CommErr Write2HzCorrection(IperlHead ihead, Results.Entities.WaterMeter wm, ref string resultStr)
{
if (ihead.CommFailed) return CommErr.CommFailed;
@ -1571,13 +1571,13 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
if (0 == WriteRequestPort(ihead, MessageID.MetrologyMemory, Hz2CorrFactorsAddr, wrData.Length, wrData, cfg.CommTimeout))
{
error = CommErr.None;
ihead.Hz2CorrectionFactor = hz2CorrectionFactor;
ihead.Hz2Correction = hz2CorrectionFactor;
ihead.Hz2CorrectionDone = true;
#if IPERL
if (wm != null)
{
wm.Hz2CorrectionDone = ihead.Hz2CorrectionDone;
wm.Hz2CorrectionFactor = ihead.Hz2CorrectionFactor;
wm.Hz2Correction = ihead.Hz2Correction;
}
#endif
break;
@ -1621,13 +1621,13 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
resultStr = string.Format("2Hz correction = {0}", (SByte)hz2CorrectionByte);
rfidDataLogger.Warn(ihead.Name + ": " + resultStr);
ihead.Hz2CorrectionDone = true;
ihead.Hz2CorrectionFactor = hz2CorrectionFactor;
ihead.Hz2Correction = hz2CorrectionFactor;
#if IPERL
if (wm != null)
{
wm.Diff2Hz8Hz = ihead.Diff2Hz8Hz;
wm.Hz2CorrectionDone = ihead.Hz2CorrectionDone;
wm.Hz2Correction = ihead.Hz2CorrectionFactor;
wm.Hz2Correction = ihead.Hz2Correction;
}
#endif
}

View File

@ -105,10 +105,10 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
}
CalibrationStruct calibrationStruct;
public ushort OriginalCalibFactor;
public ushort CalibrationFactor { get { return (CalibrationStruct != null) ? CalibrationStruct.Calibration : (ushort)0; } }
public ushort OrigCalibFactor;
public ushort CalibFactor { get { return (CalibrationStruct != null) ? CalibrationStruct.Calibration : (ushort)0; } }
public double Q2ErrorWOCorrection;
public double Q2ErrWOCorrection;
public bool Q2CorrectionDone;
public double Q2Correction;
public int Q2CorrRFlow;
@ -116,7 +116,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
public double Diff2Hz8Hz;
public bool Hz2CorrectionDone;
public int Hz2CorrectionFactor;
public int Hz2Correction;
public string FWVersion { get { return (CalibrationStruct != null) ? CalibrationStruct.FWVersionStr() : string.Empty; } }
@ -148,37 +148,43 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
/// <summary>
/// New calibration factor calculated from the original factor (argument)
/// and results of the last test.
/// and results of any test(s).
/// </summary>
/// <param name="adjustTestResult">Test result for calculations</param>
/// <param name="originalCalibrationFactor">Original calibration factor</param>
/// <param name="FactorLimitLo">Lower limit for the calibration factor</param>
/// <param name="FactorLimitHi">Upper limit for the calibration factor</param>
/// <returns>New calibration factor or 0 (= Out of range)</returns>
public UInt16 CalculateNewCalibFactor(UInt16 originalCalibrationFactor, UInt16 FactorLimitLo, UInt16 FactorLimitHi)
{
OriginalCalibFactor = originalCalibrationFactor;
public UInt16 CalculateNewCalibFactor(Results.Entities.MeterTestRslt adjustTestResult, UInt16 originalCalibrationFactor, UInt16 FactorLimitLo, UInt16 FactorLimitHi)
{
double meterVolume = adjustTestResult.VolumeMeter;
double refVolume = adjustTestResult.VolumeRef;
double volumeMeter = Math.Abs(VolumeLtrEnd - VolumeLtrStart);
OrigCalibFactor = originalCalibrationFactor;
if (volumeMeter > 1E-2)
{
PositiveCounting = VolumeLtrEnd > VolumeLtrStart;
if (meterVolume > 1E-2)
{
PositiveCounting = VolumeLtrEnd > VolumeLtrStart;
UInt16 newFactor = (UInt16)((double)originalCalibrationFactor * VolumeLtrRef / volumeMeter + 0.5);
log.InfoFormat("Calibration factor: orig={0} new={1} V_1={2} V_2={3} Vdiff={4} Vref={5}",
originalCalibrationFactor, newFactor,
VolumeLtrStart.ToString("F3"), VolumeLtrEnd.ToString("F3"), volumeMeter.ToString("F3"),
VolumeLtrRef.ToString("F3"));
UInt16 newFactor = (UInt16)((double)originalCalibrationFactor * refVolume / meterVolume + 0.5);
log.InfoFormat("Calibration factor: orig={0} new={1} V_iperl={2} V_ref={3}",
originalCalibrationFactor,
newFactor,
meterVolume.ToString("F3"),
refVolume.ToString("F3"));
if (newFactor < FactorLimitLo || newFactor > FactorLimitHi) return 0;
return newFactor;
}
else
{
log.ErrorFormat("Calibration factor: orig={0} new={0} (unchanged!) Vdiff={1}",
originalCalibrationFactor, volumeMeter.ToString("F3"));
return originalCalibrationFactor; /// Too small volume in the denominator -> no correction at all
}
}
}
else
{
log.ErrorFormat("Calibration factor: orig={0} new={0} (unchanged!) V_iperl={1}",
originalCalibrationFactor,
meterVolume.ToString("F3"));
return originalCalibrationFactor; /// Too small volume in the denominator -> no correction at all
}
}
/// <summary>
@ -188,19 +194,19 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
/// <param name="q2TestResult">Test result from which to calculate the factor</param>
/// <param name="q2CorrectionFactor">The calculated Q2 correction factor</param>
/// <returns>true = OK, false = failed</returns>
public bool CalculateQ2CorrectionFactor(Results.Entities.MeterTestRslt q2TestResult, out double q2CorrectionFactor)
public bool CalculateQ2CorrectionFactor(Results.Entities.MeterTestRslt q2adjTestResult, Results.Entities.TestData q2adjTestData, out double q2CorrectionFactor)
{
q2CorrectionFactor = 0;
if (q2TestResult == null) return false; /// Q2 test result is missing ==> water meter failed
if (q2adjTestResult == null) return false; /// Q2 test result is missing ==> water meter failed
double errLimitLo = q2TestResult.ErrLimLo() + q2TestResult.Uncertainty();
double errLimitHi = q2TestResult.ErrLimHi() - q2TestResult.Uncertainty();
double errLimitLo = q2adjTestData.ErrLimLo + q2adjTestData.Uncertainty;
double errLimitHi = q2adjTestData.ErrLimHi - q2adjTestData.Uncertainty;
if ((q2TestResult.Error < errLimitLo) || (q2TestResult.Error > errLimitHi))
{
return false; /// Q2 error too large ==> water meter failed
}
if ((q2adjTestResult.Error < errLimitLo) || (q2adjTestResult.Error > errLimitHi))
{
return false; /// Q2 error too large ==> water meter failed
}
double A = 16.0 / ScalingFactor(); /// Raw units per ml: DN15=16, DN20=8, DN25=4, DN32=2, DN40=1
const double B = 8.0; /// Raw units per minute, 8
@ -209,13 +215,13 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
double F = D / (NominalTestFlowLph * 10.0); /// Error corrected with 8 Raw Units per minute [%]
double G = F / B; /// Error corrected with 1 Raw Unit per minute [%]
q2CorrectionFactor = (-1) * (q2TestResult.Error / G) * (q2TestResult.VolumeRef / q2TestResult.VolumeMeter);
q2CorrectionFactor = (-1) * (q2adjTestResult.Error / G) * (q2adjTestResult.VolumeRef / q2adjTestResult.VolumeMeter);
log.WarnFormat("Q2 correction: Pos={0}, PCB#={1}, corrFactor={2}, error={3}% [Lo={4}%, Hi={5}%]",
Name,
SerialNr,
q2CorrectionFactor.ToString("F1"),
q2TestResult.Error.ToString("F2"),
q2adjTestResult.Error.ToString("F2"),
errLimitLo.ToString("F1"),
errLimitHi.ToString("F1"));
@ -368,8 +374,8 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
LastTestResult = null;
NominalTestFlowLph = 0;
OriginalCalibFactor = 0;
Q2ErrorWOCorrection = 0;
OrigCalibFactor = 0;
Q2ErrWOCorrection = 0;
Q2CorrectionDone = false;
Q2CorrRFlow = 0;