init
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// this attribute allows us to associate a max input range in mV for a gain
|
||||
/// note that this can be computed using the gain itself and the input range
|
||||
/// but this allows us to more tightly control things (say by using 2450 instead of 2500 for full range or something similar)
|
||||
/// http://fogbugz/fogbugz/default.asp?10080
|
||||
/// </summary>
|
||||
public class MaxInputRangeAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// returns the max input range in mV for gain
|
||||
/// http://fogbugz/fogbugz/default.asp?10080
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
/// <returns></returns>
|
||||
public static double GetMaxInputRangemV(object o)
|
||||
{
|
||||
if (o == null) return 0D;
|
||||
var mi = o.GetType().GetMember(o.ToString());
|
||||
if (mi.Length <= 0) return 0D;
|
||||
return GetCustomAttribute(mi[0], typeof(MaxInputRangeAttribute)) is MaxInputRangeAttribute attr ? attr._maximumInputRangemV : 0D;
|
||||
}
|
||||
|
||||
private readonly double _maximumInputRangemV;
|
||||
public MaxInputRangeAttribute(double maxInputRangemV)
|
||||
{
|
||||
_maximumInputRangemV = maxInputRangemV;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
enum Trigger
|
||||
{
|
||||
PingAndConnect,
|
||||
Reset,
|
||||
ResolveChannelsAuto,
|
||||
ResolveChannelsManual,
|
||||
ApplyConfiguration,
|
||||
TurnOffExcitation,
|
||||
Cancel,
|
||||
Finish,
|
||||
Arm,
|
||||
StartRealtime,
|
||||
RequeryDevice,
|
||||
Download
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user