(1) IDatastreamReader iface in IperlHead and SerialStream, (2) SerialStream buffer size, (3) TimeFieldFormat==FieldFormat.None implemented, ver. 2.18.911

This commit is contained in:
Milan Hanajik
2018-06-04 08:15:27 +02:00
parent 385825c9e8
commit 392a02b83c
12 changed files with 220 additions and 166 deletions
@@ -0,0 +1,16 @@
///
/// Copyright (c) 2018 Sensus Slovensko a.s.
///
using System;
namespace TBF.BenchControl.GenericDevices
{
interface IDatastreamReader : IRegisterReader
{
bool NoSamples { get; }
double VolumeLtrStart { get; }
double VolumeLtrEnd { get; }
double TimestampSecStart { get; }
double TimestampSecEnd { get; }
}
}
@@ -23,7 +23,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
public float RefFlow; /// [m3/h]
public int Counter;
const int MaxDataLength = 256;
const int MaxDataLength = 512;
char[] data = new char[MaxDataLength];
int dataLength;
@@ -106,56 +106,72 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
/// Copy data into the fixed size buffer
dataLength = frame.Length - 2;
for (int i = 0; i < Math.Min(MaxDataLength, dataLength); i++) data[i] = frame[i];
bool f1 = true;
bool f2 = true;
bool f3 = true;
bool f1 = UInt32.TryParse(frame.Substring(ff.VolumeFieldStart, ff.VolumeFieldLength), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
bool f2 = UInt32.TryParse(frame.Substring(ff.TimeFieldStart, ff.TimeFieldLength), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Timestamp);
bool f3 = byte.TryParse(frame.Substring(ff.FrameLength - 4, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out CheckSum);
if (ff.VolumeFieldFormat == FieldFormat.HexadecimalWindow)
{
f1 = UInt32.TryParse(frame.Substring(ff.VolumeFieldStart, ff.VolumeFieldLength), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
///
/// Cope with 'VolumeRaw' overflow
///
Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & ff.VolumeWindowMask) | VolumeRaw);
if (Math.Abs(uncorrected - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + ff.VolumeWrapIncrement - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected + ff.VolumeWrapIncrement;
}
else if (Math.Abs(uncorrected - ff.VolumeWrapIncrement - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected - ff.VolumeWrapIncrement;
}
else
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
}
if (ff.TimeFieldFormat == FieldFormat.HexadecimalWindow)
{
f2 = UInt32.TryParse(frame.Substring(ff.TimeFieldStart, ff.TimeFieldLength), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Timestamp);
///
/// Cope with 'Timestamp' overflow
///
Int64 uncorrected = (Int64)(((UInt64)timestampExtLast & ff.TimeWindowMask) | Timestamp);
if (Math.Abs(uncorrected - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + ff.TimeWrapIncrement - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected + ff.TimeWrapIncrement;
}
else if (Math.Abs(uncorrected - ff.TimeWrapIncrement - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected - ff.TimeWrapIncrement;
}
else
{
TimestampExt = timestampExtLast = uncorrected;
}
}
else if (ff.TimeFieldFormat == FieldFormat.None)
{
TimestampExt = ff.RawTimeIncrementPerFrame * counter;
}
f3 = byte.TryParse(frame.Substring(ff.FrameLength - 4, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out CheckSum);
bool allOk = f1 && f2 && f3;
Flags = allOk ? FrameFlags.OK : FrameFlags.InvalidFrame;
///
/// Cope with 'VolumeRaw' overflow
///
Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & ff.VolumeWindowMask) | VolumeRaw);
if (Math.Abs(uncorrected - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + ff.VolumeWrapIncrement - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected + ff.VolumeWrapIncrement;
}
else if (Math.Abs(uncorrected - ff.VolumeWrapIncrement - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected - ff.VolumeWrapIncrement;
}
else
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
///
/// Cope with 'Timestamp' overflow
///
uncorrected = (Int64)(((UInt64)timestampExtLast & ff.TimeWindowMask) | Timestamp);
if (Math.Abs(uncorrected - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + ff.TimeWrapIncrement - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected + ff.TimeWrapIncrement;
}
else if (Math.Abs(uncorrected - ff.TimeWrapIncrement - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected - ff.TimeWrapIncrement;
}
else
{
TimestampExt = timestampExtLast = uncorrected;
}
return allOk;
}
@@ -8,15 +8,16 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
public class FrameFormat
{
public int FrameLength; /// Frame length in characters/bytes, 0 = unknown
public double FrameFrequency; /// Number of frames per second (Hz)
public readonly Config.Unit VolumeUnits;
public readonly double VolumeScaleFactor; /// Volume =
public readonly double VolumeScaleFactor; /// Volume in VolumeInits = volmeRaw / VolumeScaleFactor
public readonly int VolumeFieldStart; /// Start of the volume field: 0-based index of the first character, -1 = no volume field in the frame
public readonly int VolumeFieldEnd; /// End of the volume field: 0-based index of the last character
public readonly FieldFormat VolumeFieldFormat; /// Hexadecimal or Decimal
public readonly Config.Unit TimeUnits;
public readonly double TimeScaleFactor; /// Time =
public readonly double TimeScaleFactor; /// Time in TimeUnits = timeRaw / TimeScaleFactor
public readonly int TimeFieldStart; /// Start of the time field: 0-based index of the first character, -1 = no time field in the frame
public readonly int TimeFieldEnd; /// End of the time field: 0-based index of the last character
public readonly FieldFormat TimeFieldFormat; /// Hexadecimal or Decimal
@@ -34,13 +35,16 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
public readonly Int64 TimeWrapIncrement;
public readonly Int64 TimeWrapThreshold;
public FrameFormat(int frameLength,
public readonly long RawTimeIncrementPerFrame;
public FrameFormat(int frameLength, double frameFrequency,
Config.Unit volumeUnits, double volumeScaleFactor,
int volumeFieldStart, int volumeFieldEnd, FieldFormat volumeFieldFormat,
Config.Unit timeUnits, double timeScaleFactor,
int timeFieldStart, int timeFieldEnd, FieldFormat timeFieldFormat)
{
FrameLength = frameLength;
FrameFrequency = frameFrequency;
VolumeUnits = volumeUnits;
VolumeScaleFactor = volumeScaleFactor;
@@ -54,6 +58,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
TimeFieldEnd = timeFieldEnd;
TimeFieldFormat = timeFieldFormat;
RawTimeIncrementPerFrame = (FrameFrequency != 0) ? (long)Math.Round(TimeScaleFactor / FrameFrequency) : 1L;
VolumeFieldLength = VolumeFieldEnd - VolumeFieldStart + 1;
@@ -13,7 +13,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
/// <summary>
/// This component = instance of this class is a placeholder for a combined main watermeter
/// </summary>
public class SerialStream : ComponentBase, IDevice, GenericDevices.IRegisterReader, GenericDevices.IHasTestName, IOperation
public class SerialStream : ComponentBase, IDevice, GenericDevices.IDatastreamReader, GenericDevices.IHasTestName, IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(SerialStream));
public override string ToString() { return string.Format("RegisterReaders.SerialStream({0})", Cfg.ToString(1)); }
@@ -100,9 +100,10 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
private double volumeLtr; ///
private double volumeLtr0;
public double VolumeLtrStart; /// Test start volume for metrology
public double VolumeLtrEnd; /// Test end volume for metrology
public double VolumeLtrRef; /// Reference volume or metrology
public double VolumeLtrStart { get { return volumeLtrStart; } } /// Test start volume for metrology
public double VolumeLtrEnd { get { return volumeLtrEnd; } } /// Test end volume for metrology
double volumeLtrStart; /// Test start volume for metrology
double volumeLtrEnd; /// Test end volume for metrology
double volumeLtrEnd1; /// auxiliary buffer1 to keep the end volume before test stops
double volumeLtrEnd2; /// auxiliary buffer2 to keep the end volume before test stops
double volumeLtrEnd3; /// auxiliary buffer3 to keep the end volume before test stops
@@ -130,7 +131,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
DatastreamFrame[] datastreamFrames;
const int MaxDatastreamFramesCount = 40000;
const int MaxDatastreamFramesCount = 80000; /// almost 3h at 8 Hz
int datastreamFramesCount;
string datastreamLogFileName;
@@ -194,7 +195,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
if (DebugLevel == DebugMode.Normal)
{
datastreamParsingEnabled = false;
currentFrameFormat = new FrameFormat(FrameLength,
currentFrameFormat = new FrameFormat(FrameLength, FrameFrequency,
VolumeUnits, VolumeScaleFactor,
VolumeFieldStart, VolumeFieldEnd, VolumeFieldFormat,
TimeUnits, TimeScaleFactor,
@@ -322,7 +323,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
testName,
repetitionNr);
StartParsingDatastream(new FrameFormat(FrameLength,
StartParsingDatastream(new FrameFormat(FrameLength, FrameFrequency,
VolumeUnits, VolumeScaleFactor,
VolumeFieldStart, VolumeFieldEnd, VolumeFieldFormat,
TimeUnits, TimeScaleFactor,
@@ -338,13 +339,13 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
if (sampleNr == 4)
{
/// Take the test start sample
VolumeLtrStart = volumeLtr;
volumeLtrStart = volumeLtr;
timestampSecStart = timestampSec;
TestStartFrameIx = frameIx;
}
/// Shift data in pipelines
VolumeLtrEnd = volumeLtrEnd3;
volumeLtrEnd = volumeLtrEnd3;
volumeLtrEnd3 = volumeLtrEnd2;
volumeLtrEnd2 = volumeLtrEnd1;
volumeLtrEnd1 = volumeLtr;
@@ -493,7 +494,8 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
synchronized = true;
}
// CR+LF found and (pos >= OptoTelegramRaw.Length - 2)
else if (datastreamFrames[datastreamFramesCount].UpdateFromString(allRcvd.Substring(pos - ff.FrameLength + 2, ff.FrameLength), ff, datastreamFramesCount, ref volumeRawExtLast, ref timestampExtLast))
else if (datastreamFrames[datastreamFramesCount].UpdateFromString(allRcvd.Substring(pos - ff.FrameLength + 2, ff.FrameLength),
ff, datastreamFramesCount, ref volumeRawExtLast, ref timestampExtLast))
{
OptoTelegramRreceived(datastreamFramesCount++, synchronized2);
synchronized2 = synchronized;
@@ -390,7 +390,8 @@ namespace TBF.BenchControl.TestMethods.Endurance
Results.Entities.MeterTestRslt meterRslt = BatchRslts.GetMeterTestRslt(testName, i, Config.Entities.CompoundMeterId.Single);
GenericDevices.IRegisterReader regReader = sensPath.RegisterReaders[i];
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IDatastreamReader dstrReader = regReader as GenericDevices.IDatastreamReader;
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
if (meterRslt != null && regReader != null)
{
@@ -399,21 +400,20 @@ namespace TBF.BenchControl.TestMethods.Endurance
meterRslt.PulsesMeter = Convert.ToDouble(regReader.WMPulses);
meterRslt.PulsesMaster = Convert.ToDouble(regReader.WMRefPulses);
if (iPerl != null)
if (dstrReader != null)
{
if (iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode & (int)Results.Entities.ResultCode.OptoErrorCodeMask) == 0)
if (iPerl != null && iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode & (int)Results.Entities.ResultCode.OptoErrorCodeMask) == 0)
{
meterRslt.WaterMeter.ResultCode |= iPerl.ResultCode;
}
meterRslt.TimestampStart = iPerl.TimestampSecStart;
meterRslt.TimestampEnd = iPerl.NoSamples ? (iPerl.TimestampSecStart + tstRslt.TestTime) : iPerl.TimestampSecEnd;
meterRslt.TestTime = iPerl.NoSamples ? tstRslt.TestTime : (meterRslt.TimestampEnd - meterRslt.TimestampStart);
meterRslt.VolumeStart = iPerl.VolumeLtrStart; /// liter
meterRslt.VolumeEnd = iPerl.VolumeLtrEnd; /// liter
meterRslt.VolumeMeter = Math.Abs(iPerl.VolumeLtrEnd - iPerl.VolumeLtrStart);
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;
iPerl.VolumeLtrRef = meterRslt.VolumeRef;
}
else
{
@@ -636,8 +636,9 @@ namespace TBF.BenchControl.TestMethods.FlyingStart
Results.Entities.MeterTestRslt meterRslt = BatchRslts.GetMeterTestRslt(testName, i, Config.Entities.CompoundMeterId.Single);
GenericDevices.IRegisterReader regReader = sensPath.RegisterReaders[i];
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IRoi cameraRoi = regReader as GenericDevices.IRoi;
GenericDevices.IDatastreamReader dstrReader = regReader as GenericDevices.IDatastreamReader;
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IRoi cameraRoi = regReader as GenericDevices.IRoi;
if (meterRslt != null && regReader != null)
{
@@ -646,30 +647,32 @@ namespace TBF.BenchControl.TestMethods.FlyingStart
meterRslt.PulsesMeter = Convert.ToDouble(regReader.WMPulses);
meterRslt.PulsesMaster = Convert.ToDouble(regReader.WMRefPulses);
if (iPerl != null)
if (dstrReader != null)
{
if (iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode & (int)Results.Entities.ResultCode.OptoErrorCodeMask) == 0)
{
meterRslt.WaterMeter.ResultCode |= iPerl.ResultCode;
}
meterRslt.TimestampStart = iPerl.TimestampSecStart;
meterRslt.TimestampEnd = iPerl.NoSamples ? (iPerl.TimestampSecStart + tstRslt.TestTime) : iPerl.TimestampSecEnd;
meterRslt.TestTime = iPerl.NoSamples ? tstRslt.TestTime : (meterRslt.TimestampEnd - meterRslt.TimestampStart);
meterRslt.VolumeStart = iPerl.VolumeLtrStart; /// liter
meterRslt.VolumeEnd = iPerl.VolumeLtrEnd; /// liter
meterRslt.VolumeMeter = Math.Abs(iPerl.VolumeLtrEnd - iPerl.VolumeLtrStart);
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;
iPerl.VolumeLtrRef = meterRslt.VolumeRef;
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.CalibrationStruct != null) ? iPerl.CalibrationStruct.Calibration : 0;
meterRslt.WaterMeter.Q2Correction = iPerl.Q2Correction;
meterRslt.WaterMeter.Q2CorrRFlow = iPerl.Q2CorrRFlow;
meterRslt.WaterMeter.Q2CorrLFlow = iPerl.Q2CorrLFlow;
meterRslt.WaterMeter.CalibFactor = (iPerl.CalibrationStruct != null) ? iPerl.CalibrationStruct.Calibration : 0;
meterRslt.WaterMeter.Q2Correction = iPerl.Q2Correction;
meterRslt.WaterMeter.Q2CorrRFlow = iPerl.Q2CorrRFlow;
meterRslt.WaterMeter.Q2CorrLFlow = iPerl.Q2CorrLFlow;
#endif
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
iPerl.NominalTestFlowLph = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
iPerl.NominalTestFlowLph = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
}
}
else if (cameraRoi != null)
{
@@ -1003,7 +1003,8 @@ namespace TBF.BenchControl.TestMethods.FlyingStartFirstRepetWithMassColl
Results.Entities.MeterTestRslt meterRslt = BatchRslts.GetMeterTestRslt(testName, i, Config.Entities.CompoundMeterId.Single);
GenericDevices.IRegisterReader regReader = sensPath.RegisterReaders[i];
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IDatastreamReader dstrReader = regReader as GenericDevices.IDatastreamReader;
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IRoi cameraRoi = regReader as GenericDevices.IRoi;
if (meterRslt != null && regReader != null)
@@ -1013,30 +1014,32 @@ namespace TBF.BenchControl.TestMethods.FlyingStartFirstRepetWithMassColl
meterRslt.PulsesMeter = Convert.ToDouble(regReader.WMPulses);
meterRslt.PulsesMaster = Convert.ToDouble(regReader.WMRefPulses);
if (iPerl != null)
if (dstrReader != null)
{
if (iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode & (int)Results.Entities.ResultCode.OptoErrorCodeMask) == 0)
{
meterRslt.WaterMeter.ResultCode |= iPerl.ResultCode;
}
meterRslt.TimestampStart = iPerl.TimestampSecStart;
meterRslt.TimestampEnd = iPerl.NoSamples ? (iPerl.TimestampSecStart + tstRslt.TestTime) : iPerl.TimestampSecEnd;
meterRslt.TestTime = iPerl.NoSamples ? tstRslt.TestTime : (meterRslt.TimestampEnd - meterRslt.TimestampStart);
meterRslt.VolumeStart = iPerl.VolumeLtrStart; /// liter
meterRslt.VolumeEnd = iPerl.VolumeLtrEnd; /// liter
meterRslt.VolumeMeter = Math.Abs(iPerl.VolumeLtrEnd - iPerl.VolumeLtrStart);
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;
iPerl.VolumeLtrRef = meterRslt.VolumeRef;
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.CalibrationStruct != null) ? iPerl.CalibrationStruct.Calibration : 0;
meterRslt.WaterMeter.Q2Correction = iPerl.Q2Correction;
meterRslt.WaterMeter.Q2CorrRFlow = iPerl.Q2CorrRFlow;
meterRslt.WaterMeter.Q2CorrLFlow = iPerl.Q2CorrLFlow;
meterRslt.WaterMeter.CalibFactor = (iPerl.CalibrationStruct != null) ? iPerl.CalibrationStruct.Calibration : 0;
meterRslt.WaterMeter.Q2Correction = iPerl.Q2Correction;
meterRslt.WaterMeter.Q2CorrRFlow = iPerl.Q2CorrRFlow;
meterRslt.WaterMeter.Q2CorrLFlow = iPerl.Q2CorrLFlow;
#endif
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
iPerl.NominalTestFlowLph = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
iPerl.NominalTestFlowLph = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
}
}
else if (cameraRoi != null)
{
@@ -973,8 +973,9 @@ namespace TBF.BenchControl.TestMethods.FlyingStartMassCollProlonged
/// MetersKind.Single meters
Results.Entities.MeterTestRslt meterRslt = BatchRslts.GetMeterTestRslt(testName, i, Config.Entities.CompoundMeterId.Single);
GenericDevices.IRegisterReader regReader = sensPath.RegisterReaders[i];
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IRoi cameraRoi = regReader as GenericDevices.IRoi;
GenericDevices.IDatastreamReader dstrReader = regReader as GenericDevices.IDatastreamReader;
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IRoi cameraRoi = regReader as GenericDevices.IRoi;
if (meterRslt != null && regReader != null)
{
@@ -983,30 +984,32 @@ namespace TBF.BenchControl.TestMethods.FlyingStartMassCollProlonged
meterRslt.PulsesMeter = Convert.ToDouble(regReader.WMPulses);
meterRslt.PulsesMaster = Convert.ToDouble(regReader.WMRefPulses);
if (iPerl != null)
if (dstrReader != null)
{
if (iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode & (int)Results.Entities.ResultCode.OptoErrorCodeMask) == 0)
{
meterRslt.WaterMeter.ResultCode |= iPerl.ResultCode;
}
meterRslt.TimestampStart = iPerl.TimestampSecStart;
meterRslt.TimestampEnd = iPerl.NoSamples ? (iPerl.TimestampSecStart + tstRslt.TestTime) : iPerl.TimestampSecEnd;
meterRslt.TestTime = iPerl.NoSamples ? tstRslt.TestTime : (meterRslt.TimestampEnd - meterRslt.TimestampStart);
meterRslt.VolumeStart = iPerl.VolumeLtrStart; /// liter
meterRslt.VolumeEnd = iPerl.VolumeLtrEnd; /// liter
meterRslt.VolumeMeter = Math.Abs(iPerl.VolumeLtrEnd - iPerl.VolumeLtrStart);
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;
iPerl.VolumeLtrRef = meterRslt.VolumeRef;
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.CalibrationStruct != null) ? iPerl.CalibrationStruct.Calibration : 0;
meterRslt.WaterMeter.Q2Correction = iPerl.Q2Correction;
meterRslt.WaterMeter.Q2CorrRFlow = iPerl.Q2CorrRFlow;
meterRslt.WaterMeter.Q2CorrLFlow = iPerl.Q2CorrLFlow;
meterRslt.WaterMeter.CalibFactor = (iPerl.CalibrationStruct != null) ? iPerl.CalibrationStruct.Calibration : 0;
meterRslt.WaterMeter.Q2Correction = iPerl.Q2Correction;
meterRslt.WaterMeter.Q2CorrRFlow = iPerl.Q2CorrRFlow;
meterRslt.WaterMeter.Q2CorrLFlow = iPerl.Q2CorrLFlow;
#endif
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
iPerl.NominalTestFlowLph = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
iPerl.NominalTestFlowLph = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
}
}
else if (cameraRoi != null)
{
@@ -1019,8 +1019,9 @@ namespace TBF.BenchControl.TestMethods.FlyingStartMassCollection
/// MetersKind.Single meters
Results.Entities.MeterTestRslt meterRslt = BatchRslts.GetMeterTestRslt(testName, i, Config.Entities.CompoundMeterId.Single);
GenericDevices.IRegisterReader regReader = sensPath.RegisterReaders[i];
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IRoi cameraRoi = regReader as GenericDevices.IRoi;
GenericDevices.IDatastreamReader dstrReader = regReader as GenericDevices.IDatastreamReader;
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IRoi cameraRoi = regReader as GenericDevices.IRoi;
if (meterRslt != null && regReader != null)
{
@@ -1029,31 +1030,34 @@ namespace TBF.BenchControl.TestMethods.FlyingStartMassCollection
meterRslt.PulsesMeter = Convert.ToDouble(regReader.WMPulses);
meterRslt.PulsesMaster = Convert.ToDouble(regReader.WMRefPulses);
if (iPerl != null)
if (dstrReader != null)
{
if (iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode & (int)Results.Entities.ResultCode.OptoErrorCodeMask) == 0)
{
meterRslt.WaterMeter.ResultCode |= iPerl.ResultCode;
}
meterRslt.TimestampStart = iPerl.TimestampSecStart;
meterRslt.TimestampEnd = iPerl.NoSamples ? (iPerl.TimestampSecStart + tstRslt.TestTime) : iPerl.TimestampSecEnd;
meterRslt.TestTime = iPerl.NoSamples ? tstRslt.TestTime : (meterRslt.TimestampEnd - meterRslt.TimestampStart);
meterRslt.VolumeStart = iPerl.VolumeLtrStart; /// liter
meterRslt.VolumeEnd = iPerl.VolumeLtrEnd; /// liter
meterRslt.VolumeMeter = Math.Abs(iPerl.VolumeLtrEnd - iPerl.VolumeLtrStart);
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;
iPerl.VolumeLtrRef = meterRslt.VolumeRef;
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.CalibrationStruct != null) ? iPerl.CalibrationStruct.Calibration : 0;
meterRslt.WaterMeter.Q2Correction = iPerl.Q2Correction;
meterRslt.WaterMeter.Q2CorrRFlow = iPerl.Q2CorrRFlow;
meterRslt.WaterMeter.Q2CorrLFlow = iPerl.Q2CorrLFlow;
meterRslt.WaterMeter.CalibFactor = (iPerl.CalibrationStruct != null) ? iPerl.CalibrationStruct.Calibration : 0;
meterRslt.WaterMeter.Q2Correction = iPerl.Q2Correction;
meterRslt.WaterMeter.Q2CorrRFlow = iPerl.Q2CorrRFlow;
meterRslt.WaterMeter.Q2CorrLFlow = iPerl.Q2CorrLFlow;
#endif
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
iPerl.NominalTestFlowLph = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
}
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
iPerl.LastTestResult = meterRslt; /// Save this test result
iPerl.NominalTestFlowLph = 500.0 * (test.Qfrom + test.Qto); /// Ave. + convert to liter/hour
}
}
else if (cameraRoi != null)
{
meterRslt.TimestampStart = cameraRoi.TimestampStart; /// second
@@ -18,7 +18,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
/// <summary>
/// This component = instance of this class is a placeholder for a combined main watermeter
/// </summary>
public class IperlHead : ComponentBase, IDevice, GenericDevices.IRegisterReader, GenericDevices.IHasTestName, IOperation
public class IperlHead : ComponentBase, IDevice, GenericDevices.IDatastreamReader, GenericDevices.IHasTestName, IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(IperlHead));
public override string ToString() { return string.Format("iPerl({0})", Cfg.ToString(1)); }
@@ -173,7 +173,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
if (meterVolume > 1E-2)
{
PositiveCounting = VolumeLtrEnd > VolumeLtrStart;
PositiveCounting = volumeLtrEnd > volumeLtrStart;
UInt16 newFactor = (UInt16)((double)originalCalibrationFactor * targetVolume / meterVolume + 0.5);
log.InfoFormat("Calibration factor: orig={0} new={1} V_iperl={2} V_ref={3} V_target={4}",
@@ -300,9 +300,10 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
private double volumeLtr; ///
private double volumeLtr0;
public double VolumeLtrStart; /// Test start volume for metrology
public double VolumeLtrEnd; /// Test end volume for metrology
public double VolumeLtrRef; /// Reference volume or metrology
public double VolumeLtrStart { get { return volumeLtrStart; } } /// Test start volume for metrology
public double VolumeLtrEnd { get { return volumeLtrEnd; } } /// Test end volume for metrology
double volumeLtrStart; /// Test start volume for metrology
double volumeLtrEnd; /// Test end volume for metrology
double volumeLtrEnd1; /// auxiliary buffer1 to keep the end volume before test stops
double volumeLtrEnd2; /// auxiliary buffer2 to keep the end volume before test stops
double volumeLtrEnd3; /// auxiliary buffer3 to keep the end volume before test stops
@@ -551,13 +552,13 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
if (sampleNr == 4)
{
/// Take the test start sample
VolumeLtrStart = volumeLtr;
volumeLtrStart = volumeLtr;
timestampSecStart = timestampSec;
TestStartTelegramIx = telegramIx;
}
/// Shift data in pipelines
VolumeLtrEnd = volumeLtrEnd3;
volumeLtrEnd = volumeLtrEnd3;
volumeLtrEnd3 = volumeLtrEnd2;
volumeLtrEnd2 = volumeLtrEnd1;
volumeLtrEnd1 = volumeLtr;
@@ -594,7 +595,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
{
resultCode |= (int)Results.Entities.ResultCode.MissingOptoData;
}
else if (VolumeLtrEnd == VolumeLtrStart)
else if (volumeLtrEnd == volumeLtrStart)
{
resultCode |= (int)Results.Entities.ResultCode.OptoDataWithZeroFlow;
}
+2 -2
View File
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("2.18.910.0")]
[assembly: AssemblyFileVersion("2.18.910.0")]
[assembly: AssemblyVersion("2.18.911.0")]
[assembly: AssemblyFileVersion("2.18.911.0")]
+1
View File
@@ -534,6 +534,7 @@
<Compile Include="BenchControl\GenericDevices\INetworkAdapter.cs" />
<Compile Include="BenchControl\GenericDevices\ISequenceCondition.cs" />
<Compile Include="BenchControl\GenericDevices\ISimultTestMethod.cs" />
<Compile Include="BenchControl\GenericDevices\IDatastreamReader.cs" />
<Compile Include="BenchControl\GenericDevices\ITankDraining.cs" />
<Compile Include="BenchControl\GenericDevices\ITankDrainingCfg.cs" />
<Compile Include="BenchControl\GenericDevices\ITestMethodWith2ndPass.cs" />