private void ProcessTSSCMeasurements(IFrame frame)
{
lock (m_tsscSyncLock)
{
try
{
if (!Enabled)
{
return;
}
if ((object)m_tsscEncoder == null || m_resetTsscEncoder)
{
m_resetTsscEncoder = false;
m_tsscEncoder = new TsscEncoder();
m_tsscWorkingBuffer = new byte[32 * 1024];
OnStatusMessage(MessageLevel.Info, $"TSSC algorithm reset before sequence number: {m_tsscSequenceNumber}", "TSSC");
m_tsscSequenceNumber = 0;
m_tsscEncoder.SetBuffer(m_tsscWorkingBuffer, 0, m_tsscWorkingBuffer.Length);
}
else
{
m_tsscEncoder.SetBuffer(m_tsscWorkingBuffer, 0, m_tsscWorkingBuffer.Length);
}
int count = 0;
foreach (IMeasurement measurement in frame.Measurements.Values)
{
ushort index = m_signalIndexCache.GetSignalIndex(measurement.Key);
if (!m_tsscEncoder.TryAddMeasurement(index, measurement.Timestamp.Value, (uint)measurement.StateFlags, (float)measurement.AdjustedValue))
{
SendTSSCPayload(frame.Timestamp, count);
count = 0;
m_tsscEncoder.SetBuffer(m_tsscWorkingBuffer, 0, m_tsscWorkingBuffer.Length);
// This will always succeed
m_tsscEncoder.TryAddMeasurement(index, measurement.Timestamp.Value, (uint)measurement.StateFlags, (float)measurement.AdjustedValue);
}
count++;
}
if (count > 0)
{
SendTSSCPayload(frame.Timestamp, count);
}
// Update latency statistics
long publishTime = DateTime.UtcNow.Ticks;
m_parent.UpdateLatencyStatistics(frame.Measurements.Values.Select(m => (long)(publishTime - m.Timestamp)));
}
catch (Exception ex)
{
string message = $"Error processing measurements: {ex.Message}";
OnProcessException(MessageLevel.Info, new InvalidOperationException(message, ex));
}
}
}