215 lines
7.7 KiB
C#
215 lines
7.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
|
|
{
|
|
/// <summary>
|
|
/// Check the positioning of the streaming LED to validate the quality of the communication line
|
|
/// </summary>
|
|
public class GenesisMeterStreamingQuality : GenesisMeter
|
|
{
|
|
/// <summary>
|
|
/// Backup of last quality
|
|
/// </summary>
|
|
public QualityResult LastQualityResult;
|
|
|
|
private StreamingDecoder _sd;
|
|
/// <summary>
|
|
/// Quality check is active
|
|
/// </summary>
|
|
public Boolean IsRunning;
|
|
private DateTimeOffset? _startTime;
|
|
private DateTimeOffset? _stopTime;
|
|
private List<String> _collectedRecords;
|
|
|
|
private Int32? _tillDecodedCount;
|
|
/// <summary>
|
|
/// Kick off the streaming quality check.
|
|
/// </summary>
|
|
/// <param name="tillDecodedCount"></param>
|
|
/// <exception cref="ApplicationException"></exception>
|
|
public void StartStreamingQualityCheck(Int32? 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.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);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stop the streaming check.
|
|
/// </summary>
|
|
/// <param name="sampleRateHz"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="ApplicationException"></exception>
|
|
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;
|
|
if (_stopTime != null && _startTime != null)
|
|
return new QualityResult(_collectedRecords, _stopTime.Value - _startTime.Value, sampleRateHz);
|
|
return new QualityResult();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class QualityResult
|
|
{
|
|
/// <summary>
|
|
/// Number of records received (read line for LED message)
|
|
/// </summary>
|
|
public readonly Int32 TotalLinesCount;
|
|
/// <summary>
|
|
/// Total records decoded
|
|
/// </summary>
|
|
public readonly Int32 TotalDecodedCount;
|
|
/// <summary>
|
|
/// Total errors
|
|
/// </summary>
|
|
public readonly Int32 TotalTransportErrorCount;
|
|
/// <summary>
|
|
/// Validated without errors
|
|
/// </summary>
|
|
public readonly Int32 TotalValidationWithoutErrorsCount;
|
|
/// <summary>
|
|
/// Expected lines
|
|
/// </summary>
|
|
public readonly Int32 ExpectedLinesCount;
|
|
/// <summary>
|
|
/// Time
|
|
/// </summary>
|
|
public readonly TimeSpan TotalTime;
|
|
/// <summary>
|
|
/// Error counter
|
|
/// </summary>
|
|
public readonly Dictionary<UInt16, Int32> ErrorOccurredCounter;
|
|
|
|
/// <summary>
|
|
/// The real result of quality check
|
|
/// </summary>
|
|
/// <param name="collectedRecords"></param>
|
|
/// <param name="ts"></param>
|
|
/// <param name="sampleRateHz"></param>
|
|
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;
|
|
var bendDetectRecord = sd.DataBendDetectTest;
|
|
|
|
if (flowTestRecord != null)
|
|
{
|
|
TotalValidationWithoutErrorsCount++;
|
|
continue;
|
|
}
|
|
|
|
if (bendDetectRecord != 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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The quality result as dummy zero
|
|
/// </summary>
|
|
public QualityResult()
|
|
{
|
|
TotalLinesCount = 0;
|
|
TotalTime = TimeSpan.Zero;
|
|
ErrorOccurredCounter = new Dictionary<UInt16, Int32>();
|
|
}
|
|
}
|
|
}
|
|
}
|