103 lines
3.2 KiB
C#
103 lines
3.2 KiB
C#
///
|
|
/// Copyright (c) 2018 Sensus Slovensko a.s.
|
|
///
|
|
using System;
|
|
using Config.Entities;
|
|
|
|
namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
|
|
{
|
|
public class FlowDirectionDetection
|
|
{
|
|
readonly int fifoSize = 32;
|
|
|
|
Int64[] volumeRawFifo; /// Volume FIFO buffer
|
|
Int64[] timestampFifo; /// Timestamp FIFO buffer
|
|
///
|
|
int fifoCount; /// Number of valid FIFO items
|
|
int fifoIx; /// Index of the next FIFO item
|
|
DateTime lastFifoWriteTime; /// Time of the last write to FIFO
|
|
|
|
|
|
public FlowDirectionDetection(int fifoSize)
|
|
{
|
|
this.fifoSize = fifoSize;
|
|
volumeRawFifo = new Int64[fifoSize];
|
|
timestampFifo = new Int64[fifoSize];
|
|
ClearFifo();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Clear FIFO data
|
|
/// </summary>
|
|
public void ClearFifo()
|
|
{
|
|
fifoCount = 0;
|
|
fifoIx = 0;
|
|
lastFifoWriteTime = DateTime.MinValue;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Write data to FIFO
|
|
/// </summary>
|
|
/// <param name="volumeRaw">Volume</param>
|
|
/// <param name="timestamp">Time stamp</param>
|
|
public void WriteToFifo(Int64 volumeRaw, Int64 timestamp)
|
|
{
|
|
volumeRawFifo[fifoIx] = volumeRaw;
|
|
timestampFifo[fifoIx] = timestamp;
|
|
fifoIx = (fifoIx + 1) % fifoSize;
|
|
fifoCount = Math.Min(fifoCount + 1, fifoSize);
|
|
lastFifoWriteTime = DateTime.Now;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Determine whether there are enough recent FIFO data
|
|
/// </summary>
|
|
/// <returns>true when data valid</returns>
|
|
public bool AreFifoDataValid()
|
|
{
|
|
return (DateTime.Now.Subtract(lastFifoWriteTime).TotalSeconds <= 2.5) && (fifoCount == fifoSize);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Verify whether the flow direction is correct
|
|
/// </summary>
|
|
/// <returns>OptoHeadState.OptoAndDirOK, OptoHeadState.OptoNok or OptoHeadState.DirNok</returns>
|
|
public OptoHeadState CheckFlowDirection(FlowDir flowDir)
|
|
{
|
|
if (!AreFifoDataValid()) return OptoHeadState.OptoNok;
|
|
|
|
int positiveCount = 0;
|
|
int negativeCount = 0;
|
|
for (int i = fifoIx; i < fifoIx + fifoSize - 1; i++)
|
|
{
|
|
if (volumeRawFifo[(i + 1) % fifoSize] - volumeRawFifo[i % fifoSize] > 0)
|
|
{
|
|
positiveCount++;
|
|
}
|
|
else if (volumeRawFifo[(i + 1) % fifoSize] - volumeRawFifo[i % fifoSize] < 0)
|
|
{
|
|
negativeCount++;
|
|
}
|
|
}
|
|
|
|
if ((positiveCount > negativeCount) && flowDir == FlowDir.R_L)
|
|
{
|
|
return OptoHeadState.OptoAndDirOK;
|
|
}
|
|
else if ((positiveCount < negativeCount) && flowDir == FlowDir.L_R)
|
|
{
|
|
return OptoHeadState.OptoAndDirOK;
|
|
}
|
|
else
|
|
{
|
|
return OptoHeadState.DirNok;
|
|
}
|
|
}
|
|
}
|
|
}
|