Update GenesisSmartReader for refined start/end marker logic, add _endDeltaSeconds property, and improve telegram index resolution methods. Increment assembly version to 3.9.3031.1.

This commit is contained in:
Michal Buzik 2026-04-02 09:40:19 +02:00
parent 64cafc088a
commit 93e207c211
2 changed files with 108 additions and 31 deletions

View File

@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("3.9.3030.1")]
[assembly: AssemblyFileVersion("3.9.3030.1")]
[assembly: AssemblyVersion("3.9.3031.1")]
[assembly: AssemblyFileVersion("3.9.3031.1")]

View File

@ -678,6 +678,14 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
OptoTelegramRaw[] optoData;
int optoDataCount;
private double _endDeltaSeconds = 1.0;
public double EndDeltaSeconds
{
get => _endDeltaSeconds;
set => _endDeltaSeconds = value < 0 ? 0 : value;
}
/// Real opto deta count, can be larger then optoData.Length
///
OptoTelegramRaw toBeFlushed;
@ -984,24 +992,26 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
timeFromStart += StateMachine.Period;
ReadPulses();
// Start sample after 1 second
if (!startSampleAcquired && (timeFromStart >= 1) && (currentTelegramIx >= 0))
if (TestStartTelegramIx < 0)
{
startSampleAcquired = true;
TestStartTelegramIx = currentTelegramIx;
// initialize end at the same point
TestEndTelegramIx = currentTelegramIx;
log.DebugFormat(
"Test start acquired at ix={0}, timeFromStart={1}",
TestStartTelegramIx,
timeFromStart);
TestStartTelegramIx = FindFirstValidTelegramIx();
if (TestStartTelegramIx >= 0)
{
log.DebugFormat("TestStartTelegramIx set to first valid sample: {0}", TestStartTelegramIx);
}
}
else if (startSampleAcquired && currentTelegramIx >= 0)
if (optoDataCount > 0)
{
// always keep latest telegram as end
TestEndTelegramIx = currentTelegramIx;
TestEndTelegramIx = FindEndTelegramIxByMeterTime(_endDeltaSeconds);
if (TestEndTelegramIx >= 0)
{
log.DebugFormat(
"TestEndTelegramIx set by meter time: {0}, delta={1:F3}s",
TestEndTelegramIx,
_endDeltaSeconds);
}
}
}
@ -1020,35 +1030,28 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
lock (this)
{
// 1. stop new reads from serial
StopOptoReadLoop();
// 2. clear data stream processing
ClearReceivedLines();//Empty othrs
// 2. process everything already queued
//DrainQueuedLines();
ClearReceivedLines();
ResetDataBuffer();
// 3. now it is safe to close the port
CloseOptoSerialPort();
// 4. mark state as stopped
dataStreamState = DataStreamState.Flush;
startDataProcessing = false;
// 5. add marks using fully processed data
if (TestStartTelegramIx < 0)
TestStartTelegramIx = FindFirstValidTelegramIx();
TestEndTelegramIx = FindEndTelegramIxByMeterTime(_endDeltaSeconds);
AddTestStartEndMarksToData(out startIx, out endIx);
}
DataStreamPostProcessing();
log.WarnFormat("Genesis.Stop() startIx={0} endIx={1} len={2} no raw data file",
startIx, endIx, optoData.Length);
if (TestStartTelegramIx == 0 || optoDataCount < 100)
if (TestStartTelegramIx < 0 || TestEndTelegramIx < 0 || optoDataCount < 100)
{
ResultCode |= (int)Results.Entities.ResultCode.MissingOptoData;
}
@ -1058,6 +1061,80 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
}
}
private int FindFirstValidTelegramIx()
{
for (int i = 0; i < optoDataCount; i++)
{
int wrappedIx = BufferIdx(i);
var record = optoData[wrappedIx];
if (IsValidVolumeRecord(record))
return i;
}
return -1;
}
private double FindLastMeterTimestamp()
{
double maxTs = double.NaN;
for (int i = 0; i < optoDataCount; i++)
{
int wrappedIx = BufferIdx(i);
var record = optoData[wrappedIx];
if (!IsValidVolumeRecord(record))
continue;
if (double.IsNaN(maxTs) || record.TimestampExt > maxTs)
maxTs = record.TimestampExt;
}
return maxTs;
}
private int FindEndTelegramIxByMeterTime(double endDeltaSeconds)
{
if (optoDataCount <= 0)
return -1;
double lastTime = FindLastMeterTimestamp();
if (double.IsNaN(lastTime))
return -1;
double targetTime = lastTime - endDeltaSeconds;
int foundIx = -1;
for (int i = 0; i < optoDataCount; i++)
{
int wrappedIx = BufferIdx(i);
var record = optoData[wrappedIx];
if (!IsValidVolumeRecord(record))
continue;
if (record.TimestampExt <= targetTime)
{
foundIx = i;
}
}
// fallback: if delta is too large and nothing matches, use last valid record
if (foundIx < 0)
{
for (int i = optoDataCount - 1; i >= 0; i--)
{
int wrappedIx = BufferIdx(i);
var record = optoData[wrappedIx];
if (IsValidVolumeRecord(record))
return i;
}
}
return foundIx;
}
private volatile bool _stopQueueData = false;