Files
DP44/DataPRO/IService/StateMachine/StatusAndParameters/Realtime/RealtimeStatusInformation.cs

172 lines
7.2 KiB
C#
Raw Normal View History

2026-04-17 14:55:32 -04:00
using DTS.Common.Enums.DASFactory;
using DTS.Common.Interface.DASFactory;
using DTS.Common.Interface.StatusAndProgressBar;
using DTS.Common.Utilities.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static DTS.DASLib.Service.ServiceBase;
namespace DTS.DASLib.Service.StateMachine
{
public class RealtimeStatusInformation : IStatusInfo
{
private readonly ManualResetEvent stopRealtimeEvent = new ManualResetEvent(true);
//this is a wait handle that is set when we get a callback from realtime service saying it's done
private readonly ManualResetEvent realtimeDoneFromService = new ManualResetEvent(false);
/// <summary>
/// action to take on completion of Realtime start
/// </summary>
public Action CompleteAction { get; set; }
public void Reset()
{
CompleteAction = null;
realtimeDoneFromService.Reset();
stopRealtimeEvent.Set();
CouldNotStartRealtime = false;
}
public Action<double, double> SetRealtimeSampleRateAAF { get; set; }
public bool CouldNotStartRealtime { get; set; }
public Callback StartRealtimeCallback { get; set; }
/// <summary>
/// returns the Anti-Alias Filter (AAF) for the DAS in question
/// this is dependent on the sample rate for the hardware and a ratio in the config file
/// (RealtimeSampleRateAAFilterRatio)
/// </summary>
/// <param name="das"></param>
/// <returns></returns>
private float GetRealtimeAAFForHardware(IDASCommunication idas, double samplerate)
{
var param = States.Instance.Realtime.Status.RealtimeParams;
if (param.SliceTurnOffAAFRealtime && DFConstantsAndEnums.SupportsTurnOffAAFRealtime(idas))
{
return Common.Constants.SLICE2_NO_AAF_REALTIME_RATE;
}
//for now there is no additional work done
if (0 == param.RealtimeSampleRateAAFilterRatio) { return Convert.ToSingle(samplerate); }
return (float)samplerate / param.RealtimeSampleRateAAFilterRatio;
}
public bool IsInRealtime
{
get { return !stopRealtimeEvent.WaitOne(2, false); }
}
public void StopRealtime()
{
stopRealtimeEvent.Set();
}
Task _realtimeTask;
public void StartRealtime()
{
_realtimeTask = Task.Run(() =>
{
var param = States.Instance.Realtime.Status.RealtimeParams;
var status = States.Instance.Realtime.Status.RealtimeStatus;
var global = States.Instance.Realtime.Status.GlobalStatusParameters;
StartRealtime(param.UnitsToStartRealtime, param.ModuleIndices, param.UseSingleSampleMode,
param.RealtimeSampleRate, param.RealtimeDelayBetweenPollsInMilliSecond, param.AllowMultipleSampleRealtime, status.SetRealtimeSampleRateAAF, status.CompleteAction,
param.IdasToActiveChannels, status.StartRealtimeCallback);
});
}
public void StartRealtime(List<IDASCommunication> ldas, List<int> moduleArrayIndicies, bool useSingleSampleMode,
double realtimeSampleRate, int realtimeDelayBetweenPolls, bool allowMultipleSampleRealtime, Action<double, double> SetRealtimeSampleRateAAF, Action CompleteAction,
Dictionary<IDASCommunication, byte[]> idasToActiveChannels, Callback StartRealtimeCallback
)
{
var startRealtimeCallback = new Callback(StartRealtimeCallback);
startRealtimeCallback += (data) =>
{
if (data.Status == CallbackData.CallbackStatus.AllFinished)
{
//service is done, mark it
realtimeDoneFromService.Set();
}
if (data.Status == CallbackData.CallbackStatus.Failure)
{
}
};
stopRealtimeEvent.Reset();
using (var realtimeService = new RealtimeService())
{
try
{
if (ldas.Count > 0)
{
if (useSingleSampleMode)
{
realtimeDoneFromService.Reset();
realtimeService.StartActivePolling(ldas, startRealtimeCallback, ldas,
stopRealtimeEvent, idasToActiveChannels);
SetRealtimeSampleRateAAF(double.NaN, double.NaN);
}
else
{
realtimeDoneFromService.Reset();
realtimeService.Start(ldas,
Convert.ToInt32(realtimeSampleRate),
realtimeDelayBetweenPolls,
startRealtimeCallback,
ldas,
allowMultipleSampleRealtime,
moduleArrayIndicies.ToArray(),
stopRealtimeEvent,
idasToActiveChannels,
GetRealtimeAAFForHardware);
if (ldas.Any())
{
SetRealtimeSampleRateAAF(realtimeSampleRate,
GetRealtimeAAFForHardware(ldas[0], realtimeSampleRate));
}
else
{
SetRealtimeSampleRateAAF(double.NaN, double.NaN);
}
}
}
}
catch (Exception ex)
{
APILogger.Log(ex);
CouldNotStartRealtime = true;
//there was an exception , stop the realtime and service
stopRealtimeEvent.Set();
realtimeDoneFromService.Set();
}
finally
{
CompleteAction();
}
var mr = new ManualResetEvent(false);
realtimeService.ServiceAvailable += delegate
{
realtimeService.ServiceAvailable -= delegate { };
mr.Set();
};
while (!stopRealtimeEvent.WaitOne(30, false) && !mr.WaitOne(1, false))
{
Thread.Sleep(1);
}
//either realtime event was signalled to stop (datapro) or the service actually did already stop
//go and set the event handle to stopped to notify service in case it's running
stopRealtimeEvent.Set();
//now wait for the event from the service saying it's stopped
realtimeDoneFromService.WaitOne();
}
}
}
}