Files
laatzen/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeterStreamingQuality.cs
T
2021-10-01 11:09:20 +02:00

152 lines
5.7 KiB
C#

using System;
using System.Collections.Generic;
using Xylem.Common.CommonCore.Consts;
using Xylem.Common.Hardware.Interfaces.Ports.PortCore.EventArguments;
using Xylem.Common.Hardware.Interfaces.Ports.SerialPorts;
using Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol;
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
{
public class GenesisMeterStreamingQuality : GenesisMeter
{
public QualityResult LastQualityResult;
private StreamingDecoder sd;
public Boolean IsRunning;
private DateTimeOffset? _startTime;
private DateTimeOffset? _stopTime;
private List<String> _collectedRecords;
private int? TillDecodedCount = null;
public void StartStreamingQualityCheck(int? tillDecodedCount = null)
{
if (IsRunning)
{
return;
}
TillDecodedCount = tillDecodedCount;
if (TillDecodedCount.HasValue)
{
sd = new StreamingDecoder(false);
}
if (StreamingPort == null || !(StreamingPort is LedSerialPort))
{
throw new ApplicationException("No valid streaming port");
}
_stopTime = null;
_collectedRecords = new List<String>();
SyncStreamingBuffer(SyncMarkRecord.FlushBuffer);
SyncStreamingBuffer(SyncMarkRecord.DecodeEveryPackage);
((LedSerialPort)StreamingPort).OnRawRecordReceived += GenesisMeterStreamingQuality_OnRawRecordReceived;
_startTime = DateTimeOffset.UtcNow;
LogRawData(true);
IsRunning = true;
}
private void GenesisMeterStreamingQuality_OnRawRecordReceived(Object sender, BasePortDataEventArgs e)
{
_collectedRecords.Add(e.GetData().ToString());
if (TillDecodedCount.HasValue)
{
if (sd.DecodeMsg(e.GetData().ToString()))
{
TillDecodedCount = TillDecodedCount.Value - 1;
if (TillDecodedCount <= 0)
{
IsRunning = false;
LastQualityResult = StopStreamingQualityCheck(10);
}
}
}
}
public QualityResult StopStreamingQualityCheck(Int32 sampleRateHz)
{
_stopTime = DateTimeOffset.UtcNow;
if (!IsRunning && !_startTime.HasValue)
{
return new QualityResult();
}
if (StreamingPort == null || !(StreamingPort is LedSerialPort))
{
throw new ApplicationException("No valid streaming port");
}
LogRawData(false);
((LedSerialPort)StreamingPort).OnRawRecordReceived -= GenesisMeterStreamingQuality_OnRawRecordReceived;
SyncStreamingBuffer(SyncMarkRecord.SkipDecoding);
IsRunning = false;
return new QualityResult(_collectedRecords, _stopTime.Value - _startTime.Value, sampleRateHz);
}
public class QualityResult
{
public readonly Int32 TotalLinesCount;
public readonly Int32 TotalDecodedCount;
public readonly Int32 TotalTransportErrorCount;
public readonly Int32 TotalValidationWithoutErrorsCount;
public readonly Int32 ExpectedLinesCount;
public readonly TimeSpan TotalTime;
public readonly Dictionary<UInt16, Int32> ErrorOccurredCounter;
public QualityResult(List<String> collectedRecords, TimeSpan ts, Int32 sampleRateHz)
{
TotalLinesCount = collectedRecords.Count;
TotalTime = ts;
ExpectedLinesCount = (Int32)(Math.Round( ts.TotalSeconds * sampleRateHz, 0));
ErrorOccurredCounter = new Dictionary<UInt16, Int32>();
foreach (var rawText in collectedRecords)
{
var sd = new StreamingDecoder(false);
if (!sd.DecodeMsg(rawText))
{
TotalTransportErrorCount++;
continue;
}
//here the decoding is valid including the CRC
TotalDecodedCount++;
//the DecodeMsg has assigned either a DataCalib or DataFlowTest data set
var calibrationRecord = sd.DataCalib;
var flowTestRecord = sd.DataFlowTest;
if (flowTestRecord != null)
{
TotalValidationWithoutErrorsCount++;
continue;
}
if (calibrationRecord != null)
{
if (calibrationRecord.Validation == 0)
{
TotalValidationWithoutErrorsCount++;
}
else
{
if (ErrorOccurredCounter.ContainsKey(calibrationRecord.Validation))
{
ErrorOccurredCounter[calibrationRecord.Validation] += 1;
}
else
{
ErrorOccurredCounter.Add(calibrationRecord.Validation, 1);
}
}
}
}
}
public QualityResult()
{
TotalLinesCount = 0;
TotalTime = TimeSpan.Zero;
ErrorOccurredCounter = new Dictionary<UInt16, Int32>();
}
}
}
}