172 lines
7.2 KiB
C#
172 lines
7.2 KiB
C#
|
|
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();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|