init
This commit is contained in:
@@ -0,0 +1,721 @@
|
||||
using DTS.Common.Interface.Channels;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.Interface.StatusAndProgressBar;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Service.StateMachine.StatusAndParameters.Configure;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class ConfigureStatusInformation : IStatusInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// all possible status that can be relayed to consumers
|
||||
/// </summary>
|
||||
public enum StatusValues
|
||||
{
|
||||
ApplyingConfiguration,
|
||||
AutoResolvingChannels,
|
||||
ManuallyResolvedChannels,
|
||||
Completed,
|
||||
Cancelling,
|
||||
Cancelled,
|
||||
ChannelOutOfPosition,
|
||||
NoChannelsAssigned,
|
||||
AllChannelsResolved,
|
||||
EIDNotFound,
|
||||
ApplyConfigFailed,
|
||||
AppliedConfiguration,
|
||||
PrepareForDiagnostics,
|
||||
PrepareForDiagnosticsFailed,
|
||||
PrepareForDiagnosticsSuccess,
|
||||
LowPower,
|
||||
LowPowerSuccess,
|
||||
LowPowerFailure
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// no channels are currently assigned
|
||||
/// </summary>
|
||||
public bool NoChannelsAssigned { get; internal set; } = true;
|
||||
/// <summary>
|
||||
/// all channels to be resolved are resolved
|
||||
/// </summary>
|
||||
public bool AllChannelsResolved { get; internal set; } = false;
|
||||
/// <summary>
|
||||
/// one or more channels are out of position with respect to how
|
||||
/// they requested to be positioned (they are on a different channel than they were specified to be on)
|
||||
/// </summary>
|
||||
public bool ChannelsOutOfPosition { get; internal set; } = false;
|
||||
/// <summary>
|
||||
/// all units that were to be configured were configured
|
||||
/// </summary>
|
||||
public bool HaveAppliedConfigAllUnits { get; set; } = false;
|
||||
/// <summary>
|
||||
/// signals a cancel request
|
||||
/// </summary>
|
||||
public ManualResetEvent CancelEvent = new ManualResetEvent(false);
|
||||
/// <summary>
|
||||
/// signals when work is finished
|
||||
/// </summary>
|
||||
public ManualResetEvent DoneEvent = new ManualResetEvent(false);
|
||||
/// <summary>
|
||||
/// action to take on completion of work
|
||||
/// </summary>
|
||||
public ActionCompleteDelegate CompleteAction { get; set; }
|
||||
/// <summary>
|
||||
/// action to take on progress notification
|
||||
/// </summary>
|
||||
public SetProgressValueDelegate ProgressAction { get; set; }
|
||||
/// <summary>
|
||||
/// action to take on a status notification
|
||||
/// </summary>
|
||||
public StatusIntDelegate StatusAction { get; set; }
|
||||
/// <summary>
|
||||
/// action to take on extended status notification
|
||||
/// </summary>
|
||||
public StatusExIntDelegate StatusExAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// holds references to all units which were successfully configured
|
||||
/// </summary>
|
||||
public IDASCommunication[] UnitsConfigured { get; set; } = new IDASCommunication[0];
|
||||
/// <summary>
|
||||
/// task for turning excitation on/off, used for monitoring task or interrupting
|
||||
/// </summary>
|
||||
private Task _ExcitationTask = null;
|
||||
/// <summary>
|
||||
/// task for applying configuration, used for monitoring task or interrupting
|
||||
/// </summary>
|
||||
private Task _ApplyConfigTask = null;
|
||||
/// <summary>
|
||||
/// used to canel running task
|
||||
/// returns when task is cancelled or completed
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task Cancel()
|
||||
{
|
||||
CancelEvent.Set();
|
||||
StatusAction?.Invoke((int)StatusValues.Cancelling);
|
||||
//simulate time spent waiting for cancel to be acknowledged
|
||||
Thread.Sleep(100);
|
||||
DoneEvent.WaitOne();
|
||||
StatusAction?.Invoke((int)StatusValues.Cancelled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// turns on power (if requested and appropriate)
|
||||
/// </summary>
|
||||
private void PrepareForDiagnostics()
|
||||
{
|
||||
var param = States.Instance.Configure.Status.ConfigureParameters;
|
||||
var status = States.Instance.Configure.Status.ConfigureStatus;
|
||||
var global = States.Instance.Configure.Status.GlobalStatusInformation;
|
||||
var dasFactory = States.Instance.Configure.DASFactory;
|
||||
|
||||
//make sure we have some units to turn on, if not fail task
|
||||
if (!status.UnitsConfigured.Any())
|
||||
{
|
||||
StatusAction?.Invoke((int)StatusValues.PrepareForDiagnosticsFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
ProgressAction?.Invoke(0D);
|
||||
StatusAction?.Invoke((int)StatusValues.PrepareForDiagnostics);
|
||||
|
||||
//record if any units fail to turn on excitation
|
||||
var bPassed = true;
|
||||
var mre = new ManualResetEvent(false);
|
||||
try
|
||||
{
|
||||
using (var diagnosticsService = new DiagnosticsService())
|
||||
{
|
||||
var units = status.UnitsConfigured.ToList();
|
||||
diagnosticsService.PrepareForDiagnostics(units,
|
||||
PrePostResults.PreEventDiagnosticsResult,
|
||||
param.SampleRateLookup,
|
||||
param.AAFRateLookup,
|
||||
(ServiceBase.CallbackData data) =>
|
||||
{
|
||||
switch (data.Status)
|
||||
{
|
||||
case ServiceBase.CallbackData.CallbackStatus.Success:
|
||||
StatusExAction?.Invoke((int)StatusValues.PrepareForDiagnosticsSuccess, data.Target);
|
||||
global.AddUnitAtHighPower(data.Target);
|
||||
break;
|
||||
case ServiceBase.CallbackData.CallbackStatus.Failure:
|
||||
bPassed = false;
|
||||
StatusExAction?.Invoke((int)StatusValues.PrepareForDiagnosticsFailed, data.Target);
|
||||
break;
|
||||
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
|
||||
mre.Set();
|
||||
break;
|
||||
}
|
||||
},
|
||||
units);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
bPassed = false;
|
||||
throw ex;
|
||||
}
|
||||
|
||||
var timeWaited = 0;
|
||||
while (!mre.WaitOne(PREPARE_SPIN_TIME, false))
|
||||
{
|
||||
timeWaited += PREPARE_SPIN_TIME;
|
||||
ProgressAction?.Invoke(100D * timeWaited / EXPECTED_PREPARE_TIME);
|
||||
}
|
||||
if (bPassed)
|
||||
{
|
||||
StatusAction?.Invoke((int)StatusValues.PrepareForDiagnosticsSuccess);
|
||||
States.Instance.ConfigureStart.Status.GlobalStatusInformation.ExcitationOn = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusAction?.Invoke((int)StatusValues.PrepareForDiagnosticsFailed);
|
||||
}
|
||||
}
|
||||
|
||||
private const int PREPARE_SPIN_TIME = 200;
|
||||
private const int EXPECTED_PREPARE_TIME = 8000;
|
||||
/// <summary>
|
||||
/// lock used to control thread access to shared resources
|
||||
/// [like UnitsConfigured]
|
||||
/// </summary>
|
||||
private static readonly object MyLock = new object();
|
||||
private void AddConfiguredDevice(IDASCommunication device)
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (UnitsConfigured.Contains(device)) { return; }
|
||||
var list = new List<IDASCommunication>();
|
||||
list.AddRange(UnitsConfigured);
|
||||
list.Add(device);
|
||||
UnitsConfigured = list.ToArray();
|
||||
}
|
||||
StatusExAction?.Invoke((int)StatusValues.AppliedConfiguration, device);
|
||||
}
|
||||
/// <summary>
|
||||
/// Turns off excitation, returns immediately
|
||||
/// </summary>
|
||||
public void TurnOffExcitation()
|
||||
{
|
||||
var param = States.Instance.ConfigureStart.Status.ConfigureParameters;
|
||||
//reset the flag that got us here
|
||||
param.TurnOffExcitation = false;
|
||||
var status = States.Instance.ConfigureStart.Status.ConfigureStatus;
|
||||
var dasFactory = States.Instance.ConfigureStart.DASFactory;
|
||||
|
||||
_ExcitationTask = Task.Run(() =>
|
||||
{
|
||||
StatusAction?.Invoke((int)StatusValues.LowPower);
|
||||
var units = dasFactory.GetDASList();
|
||||
var anyFailed = false;
|
||||
try
|
||||
{
|
||||
var mre = new ManualResetEvent(false);
|
||||
using (var service = new ArmingService())
|
||||
{
|
||||
service.EnterLowPowerMode(units, (ServiceBase.CallbackData data) =>
|
||||
{
|
||||
switch (data.Status)
|
||||
{
|
||||
case ServiceBase.CallbackData.CallbackStatus.Success:
|
||||
StatusExAction?.Invoke((int)StatusValues.LowPowerSuccess, data.Target);
|
||||
break;
|
||||
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
|
||||
mre.Set();
|
||||
break;
|
||||
case ServiceBase.CallbackData.CallbackStatus.Failure:
|
||||
anyFailed = true;
|
||||
StatusExAction?.Invoke((int)StatusValues.LowPowerFailure, data.Target);
|
||||
break;
|
||||
}
|
||||
}, units);
|
||||
}
|
||||
|
||||
mre.WaitOne();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
|
||||
//if any failed to turn off record the error
|
||||
//if all turned off, then set the global status param that excitation is now known off
|
||||
if (anyFailed)
|
||||
{
|
||||
StatusAction?.Invoke((int)StatusValues.LowPowerFailure);
|
||||
}
|
||||
else
|
||||
{
|
||||
States.Instance.ConfigureStart.Status.GlobalStatusInformation.ExcitationOn = false;
|
||||
StatusAction?.Invoke((int)StatusValues.LowPowerSuccess);
|
||||
}
|
||||
|
||||
StatusAction?.Invoke((int)StatusValues.Completed);
|
||||
CompleteAction?.Invoke();
|
||||
DoneEvent.Set();
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
/// starts ApplyConfig process, returns immediately
|
||||
/// </summary>
|
||||
public void ApplyConfig()
|
||||
{
|
||||
DoneEvent.Reset();
|
||||
var param = States.Instance.ConfigureStart.Status.ConfigureParameters;
|
||||
if (param.TurnOffExcitation)
|
||||
{
|
||||
TurnOffExcitation();
|
||||
return;
|
||||
}
|
||||
var unitsToConfigure = param.UnitsToConfigure.ToList();
|
||||
var dasFactory = States.Instance.ConfigureStart.DASFactory;
|
||||
|
||||
_ApplyConfigTask = Task.Run(() =>
|
||||
{
|
||||
//the user could just be turning on power, in which case the configuration is already set
|
||||
//if the flag for set configuration is set, then set the configuration, otherwise don't
|
||||
if (param.SetConfiguration)
|
||||
{
|
||||
HaveAppliedConfigAllUnits = false;
|
||||
StatusAction?.Invoke((int)StatusValues.ApplyingConfiguration);
|
||||
|
||||
//check if we are supposed to configure a unit, but it's not available
|
||||
//mark it failed if the unit is not available
|
||||
var units = dasFactory.GetDASList();
|
||||
foreach (var unit in unitsToConfigure)
|
||||
{
|
||||
if (!units.Contains(unit))
|
||||
{
|
||||
unitsToConfigure.Remove(unit);
|
||||
StatusExAction?.Invoke((int)StatusValues.ApplyConfigFailed, unit);
|
||||
}
|
||||
}
|
||||
|
||||
var mre = new ManualResetEvent(false);
|
||||
if (unitsToConfigure.Any())
|
||||
{
|
||||
using (var configService = new ConfigurationService())
|
||||
{
|
||||
configService.SetConfiguration(unitsToConfigure, param.DoStrictCheck, param.EventConfig,
|
||||
(data) =>
|
||||
{
|
||||
switch (data.Status)
|
||||
{
|
||||
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
|
||||
mre.Set();
|
||||
break;
|
||||
case ServiceBase.CallbackData.CallbackStatus.Progress:
|
||||
ProgressAction?.Invoke(data.ProgressValue);
|
||||
break;
|
||||
case ServiceBase.CallbackData.CallbackStatus.Failure:
|
||||
StatusExAction?.Invoke((int)StatusValues.ApplyConfigFailed, data.Target,
|
||||
data.ErrorMessage, data.ErrorException);
|
||||
break;
|
||||
case ServiceBase.CallbackData.CallbackStatus.Success:
|
||||
AddConfiguredDevice(data.Target);
|
||||
break;
|
||||
}
|
||||
}, unitsToConfigure,
|
||||
param.ErrorRequiringActionAction,
|
||||
param.DummyConfig,
|
||||
param.MaxAAF,
|
||||
param.ConfigureDigitalOutputs,
|
||||
param.TurnOffAAFRealtime,
|
||||
param.DSPFilterType,
|
||||
param.DiscardDiagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
mre.WaitOne();
|
||||
//check that all the units that should have been configured were
|
||||
var allConfigured = Array.TrueForAll(param.UnitsToConfigure, d => UnitsConfigured.Contains(d));
|
||||
HaveAppliedConfigAllUnits = allConfigured;
|
||||
}
|
||||
//finally turn on power UNLESS the user has specified not to (most likely by pressing "Low Power" button)
|
||||
//but also potentially by a property setting
|
||||
if (!CancelEvent.WaitOne(1, false))
|
||||
{
|
||||
if (param.PrepareForDiagnostics && !param.SkipTurnOnPower)
|
||||
{
|
||||
PrepareForDiagnostics();
|
||||
}
|
||||
CompleteAction?.Invoke();
|
||||
}
|
||||
|
||||
StatusAction?.Invoke((int)StatusValues.Completed);
|
||||
DoneEvent.Set();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// holds channels that are not resolved for one reason or another
|
||||
/// </summary>
|
||||
private readonly List<GroupChannelWithMeta> _unresolvedChannels = new List<GroupChannelWithMeta>();
|
||||
/// <summary>
|
||||
/// holds channels that are now resolved/assigned
|
||||
/// </summary>
|
||||
private readonly List<GroupChannelWithMeta> _resolvedChannels = new List<GroupChannelWithMeta>();
|
||||
|
||||
private bool IsUnresolved(IGroupChannel ch)
|
||||
{
|
||||
return _unresolvedChannels.Exists(channel => channel.Channel == ch);
|
||||
}
|
||||
|
||||
private bool IsResolved(IGroupChannel ch)
|
||||
{
|
||||
return _resolvedChannels.Exists(channel => channel.Channel == ch);
|
||||
}
|
||||
private void AddResolvedChannel(IGroupChannel channel,
|
||||
IDASChannel hwChannel,
|
||||
bool eidOutOfPlace,
|
||||
ConfigureStatusParameters param,
|
||||
IDictionary<IDASChannel, IDASCommunication> lookupChannelToDAS,
|
||||
ISensorData sd,
|
||||
bool missingEID)
|
||||
{
|
||||
//remove any possible duplicates
|
||||
_resolvedChannels.RemoveAll(ch => ch.Channel == channel);
|
||||
_unresolvedChannels.RemoveAll(ch => ch.Channel == channel);
|
||||
|
||||
var meta = new GroupChannelWithMeta()
|
||||
{
|
||||
Channel = channel,
|
||||
ChannelConflict = false,
|
||||
ConflictingChannel = null,
|
||||
DASChannel = hwChannel,
|
||||
EIDOutOfPlace = eidOutOfPlace,
|
||||
HWChannelIncompatible = false,
|
||||
MissingID = missingEID,
|
||||
MissingSensor = false
|
||||
};
|
||||
_resolvedChannels.Add(meta);
|
||||
|
||||
//set the hardware in the group if needed
|
||||
var includedHardware = channel.Group.IncludedHardware.ToList();
|
||||
var hwId = param.GetDatabaseIdAction(lookupChannelToDAS[hwChannel]);
|
||||
if (!includedHardware.Contains(hwId))
|
||||
{
|
||||
includedHardware.Add(hwId);
|
||||
}
|
||||
channel.Group.SetIncludedHardware(includedHardware.ToArray());
|
||||
|
||||
//set the calibration
|
||||
if (hwChannel is AnalogInputDASChannel aic)
|
||||
{
|
||||
foreach (var e in sd.SupportedExcitation)
|
||||
{
|
||||
if (!aic.IsSupported(e))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var sc = param.GetCalibrationAction(sd, e);
|
||||
if (null == sc) { continue; }
|
||||
param.SetSensorCalibrationAction(sd, sc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void AddUnresolvedChannel(IGroupChannel ch,
|
||||
bool bChannelConflict,
|
||||
IGroupChannel conflictingChannel,
|
||||
bool EIDOutOfPlace,
|
||||
bool hwChannelIncompatible,
|
||||
bool hwNotFound,
|
||||
bool missingId,
|
||||
bool missingSensor)
|
||||
{
|
||||
//remove any possible duplicates
|
||||
_resolvedChannels.RemoveAll(channel => channel.Channel == ch);
|
||||
_unresolvedChannels.RemoveAll(channel => channel.Channel == ch);
|
||||
|
||||
var meta = new GroupChannelWithMeta()
|
||||
{
|
||||
Channel = ch,
|
||||
ChannelConflict = bChannelConflict,
|
||||
ConflictingChannel = conflictingChannel,
|
||||
DASChannel = null,
|
||||
EIDOutOfPlace = EIDOutOfPlace,
|
||||
HWChannelIncompatible = hwChannelIncompatible,
|
||||
HWNotFound = hwNotFound,
|
||||
MissingID = missingId,
|
||||
MissingSensor = missingSensor
|
||||
};
|
||||
_unresolvedChannels.Add(meta);
|
||||
}
|
||||
|
||||
private bool IsHWChannelResolved(IDASChannel channel)
|
||||
{
|
||||
return _resolvedChannels.Exists(ch => ch.DASChannel == channel);
|
||||
}
|
||||
|
||||
public void ManuallyUnresolveChannel(IGroupChannel channel)
|
||||
{
|
||||
if (!IsResolved(channel))
|
||||
{
|
||||
throw new InvalidAssignmentException(channel, InvalidAssignmentException.Reasons.ChannelNotAssigned);
|
||||
}
|
||||
|
||||
var resolvedChannel = _resolvedChannels.First(ch => ch.Channel == channel);
|
||||
if (resolvedChannel.AssignedByEID)
|
||||
{
|
||||
throw new InvalidAssignmentException(channel, InvalidAssignmentException.Reasons.EID_Locked);
|
||||
}
|
||||
|
||||
AddUnresolvedChannel(channel, false, null, false, false, resolvedChannel.HWNotFound, resolvedChannel.MissingID,
|
||||
false);
|
||||
}
|
||||
public void ManuallyResolveChannel(IGroupChannel channel, IDASChannel hardwareChannel)
|
||||
{
|
||||
var param = States.Instance.ConfigureStart.Status.ConfigureParameters;
|
||||
GetIdToHardwareLookup(param, out var lookupIDToHardware, out var lookupChannelToDAS,
|
||||
out var lookupDAStoChannel);
|
||||
if (channel.IsBlank())
|
||||
{
|
||||
throw new InvalidAssignmentException(channel, InvalidAssignmentException.Reasons.BlankChannel);
|
||||
}
|
||||
if (channel.IsDisabled)
|
||||
{
|
||||
throw new InvalidAssignmentException(channel, InvalidAssignmentException.Reasons.ChannelDisabled);
|
||||
}
|
||||
if (channel.SensorId < 0)
|
||||
{
|
||||
throw new InvalidAssignmentException(channel, InvalidAssignmentException.Reasons.NoSensor);
|
||||
}
|
||||
|
||||
var sd = param.GetSensorAction(channel);
|
||||
if (null == sd)
|
||||
{
|
||||
throw new InvalidAssignmentException(channel, InvalidAssignmentException.Reasons.SensorNotFound);
|
||||
}
|
||||
|
||||
var compatible = IsSensorHwCompatible(hardwareChannel, sd);
|
||||
if (SensorCompatiblilityResponse.Compatible != compatible)
|
||||
{
|
||||
throw new InvalidAssignmentException(channel, InvalidAssignmentException.Reasons.IncompatibleHardware);
|
||||
}
|
||||
//alright, looks ok ... unless there's something on that channel already ...
|
||||
if (IsHWChannelResolved(hardwareChannel))
|
||||
{
|
||||
throw new InvalidAssignmentException(channel, InvalidAssignmentException.Reasons.ChannelAlreadyAssigned);
|
||||
}
|
||||
//ok, well make sure it's we didn't find the EID for the channel already on a channel, if so ... it's locked on
|
||||
//that channel
|
||||
bool bFoundEID = false;
|
||||
if (IsResolved(channel))
|
||||
{
|
||||
var resolvedChannel = _resolvedChannels.First(ch => ch.Channel == channel);
|
||||
if (resolvedChannel.AssignedByEID)
|
||||
{
|
||||
if (resolvedChannel.DASChannel != hardwareChannel)
|
||||
{
|
||||
throw new InvalidAssignmentException(channel, InvalidAssignmentException.Reasons.EID_Locked);
|
||||
}
|
||||
//nothing to do ...
|
||||
bFoundEID = true;
|
||||
}
|
||||
}
|
||||
|
||||
//determine if we should have found an EID and didn't
|
||||
var bMissingEID = !string.IsNullOrWhiteSpace(sd.EID) && !bFoundEID;
|
||||
//if we are missing an ID, and aren't allowed to assign to a channel without an id, then don't allow it
|
||||
if (bMissingEID && !param.AllowSensorIdToBlankChannel)
|
||||
{
|
||||
throw new InvalidAssignmentException(channel, InvalidAssignmentException.Reasons.EIDRequiredAndMissing);
|
||||
}
|
||||
//add as a resolved channel
|
||||
AddResolvedChannel(channel, hardwareChannel, false, param, lookupChannelToDAS, sd, bMissingEID);
|
||||
AllChannelsResolved = _unresolvedChannels.Any();
|
||||
}
|
||||
/// <summary>
|
||||
/// thrown by manually resolve/unresolve functions
|
||||
/// </summary>
|
||||
public class InvalidAssignmentException : Exception
|
||||
{
|
||||
public enum Reasons
|
||||
{
|
||||
BlankChannel,
|
||||
NoSensor,
|
||||
ChannelDisabled,
|
||||
SensorNotFound,
|
||||
IncompatibleHardware,
|
||||
ChannelAlreadyAssigned,
|
||||
EID_Locked, //sensor is already locked by EID to a different channel
|
||||
EIDRequiredAndMissing,
|
||||
ChannelNotAssigned
|
||||
}
|
||||
public IGroupChannel GroupChannel { get; private set; }
|
||||
public Reasons Reason { get; private set; }
|
||||
|
||||
public InvalidAssignmentException(IGroupChannel channel, Reasons reason)
|
||||
: base($"{reason.ToString()} - {channel}")
|
||||
{
|
||||
Reason = reason;
|
||||
GroupChannel = channel;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// sensor is not compatible with hardware, but maybe in the future we'll want to know why
|
||||
/// even though right now it's just "hw incompatible"
|
||||
/// </summary>
|
||||
internal enum SensorCompatiblilityResponse
|
||||
{
|
||||
Compatible,
|
||||
DigitalInputNotSupportedOnHWChannel,
|
||||
DigitalInputModeNotSupportedOnHWChannel,
|
||||
BridgeModeNotSupportedOnHWChannel,
|
||||
SquibFireModeNotSupportedOnHWChannel,
|
||||
NoSupportedExcitationOnHWChannel
|
||||
}
|
||||
/// <summary>
|
||||
/// check if sensor can run on the channel in question
|
||||
/// checks excitation, bridge, sensor type, etc
|
||||
/// </summary>
|
||||
/// <param name="hwid"></param>
|
||||
/// <param name="sd"></param>
|
||||
/// <returns></returns>
|
||||
private SensorCompatiblilityResponse IsSensorHwCompatible(IDASChannel hwChannel, ISensorData sd)
|
||||
{
|
||||
switch (hwChannel)
|
||||
{
|
||||
case AnalogInputDASChannel aic:
|
||||
if (aic.SupportedBridges.Contains(sd.Bridge))
|
||||
{
|
||||
if (aic.DigitalInputChannel)
|
||||
{
|
||||
if (!sd.IsDigitalInput())
|
||||
{
|
||||
//hardware is digital, sensor is not, it's not compatible
|
||||
return SensorCompatiblilityResponse.DigitalInputNotSupportedOnHWChannel;
|
||||
}
|
||||
else if (!aic.SupportedDigitalInputModes.Contains(sd.InputMode))
|
||||
{
|
||||
//sensor and hardware are digital, but the input mode is not supported
|
||||
return SensorCompatiblilityResponse.DigitalInputModeNotSupportedOnHWChannel;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var param = States.Instance.ConfigureStart.Status.ConfigureParameters;
|
||||
var excitationPassed = (from e in sd.SupportedExcitation
|
||||
where aic.SupportedExcitation.Contains(e)
|
||||
select param.GetCalibrationAction(sd, e)).Any(sc => null != sc);
|
||||
if (!excitationPassed)
|
||||
{
|
||||
//there's no supported excitation match
|
||||
return SensorCompatiblilityResponse.NoSupportedExcitationOnHWChannel;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//the hardware does not support the bridge mode of the sensor ...
|
||||
return SensorCompatiblilityResponse.BridgeModeNotSupportedOnHWChannel;
|
||||
}
|
||||
|
||||
break;
|
||||
case OutputSquibChannel _:
|
||||
var squibChannel = (OutputSquibChannel)hwChannel;
|
||||
if (!sd.IsSquib())
|
||||
{
|
||||
//hardware channel is squib, sensor is not
|
||||
return SensorCompatiblilityResponse.BridgeModeNotSupportedOnHWChannel;
|
||||
}
|
||||
else if (!squibChannel.SupportedSquibFireModes.Contains(sd.SquibFireMode))
|
||||
{
|
||||
//hardware and sensor are squib, but fire mode not supported by hardware
|
||||
return SensorCompatiblilityResponse.SquibFireModeNotSupportedOnHWChannel;
|
||||
}
|
||||
|
||||
break;
|
||||
case OutputTOMDigitalChannel _:
|
||||
if (!sd.IsDigitalOutput())
|
||||
{
|
||||
//hardware channel is digital output, sensor is not
|
||||
return SensorCompatiblilityResponse.BridgeModeNotSupportedOnHWChannel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return SensorCompatiblilityResponse.Compatible;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns sensor EID to hardware channel mapping as determined from connected units
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="lookupChannelToDAS">hardware channel to IDASCommunication</param>
|
||||
/// <param name="lookupIDToHardware">eid to hardware channel</param>
|
||||
/// <returns></returns>
|
||||
private void GetIdToHardwareLookup(ConfigureStatusParameters param,
|
||||
out IDictionary<string, IDASChannel> lookupIDToHardware,
|
||||
out IDictionary<IDASChannel, IDASCommunication> lookupChannelToDAS,
|
||||
out IDictionary<int, IDictionary<int, IDASChannel>> lookupDASToChannel
|
||||
)
|
||||
{
|
||||
lookupIDToHardware = new Dictionary<string, IDASChannel>();
|
||||
lookupChannelToDAS = new Dictionary<IDASChannel, IDASCommunication>();
|
||||
lookupDASToChannel = new Dictionary<int, IDictionary<int, IDASChannel>>();
|
||||
|
||||
foreach (var unit in param.UnitsToConfigure)
|
||||
{
|
||||
//why is there no config data?
|
||||
if (null == unit.ConfigData)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var dasid = param.GetDatabaseIdAction(unit);
|
||||
if (!lookupDASToChannel.ContainsKey(dasid))
|
||||
{
|
||||
lookupDASToChannel.Add(dasid, new Dictionary<int, IDASChannel>());
|
||||
}
|
||||
|
||||
foreach (var module in unit.ConfigData.Modules)
|
||||
{
|
||||
foreach (var channel in module.Channels)
|
||||
{
|
||||
lookupChannelToDAS[channel] = unit;
|
||||
lookupDASToChannel[dasid][channel.Number] = channel;
|
||||
if (null != channel.IDs && channel.IDs.Length > 0)
|
||||
{
|
||||
var id = channel.IDs[0].ID;
|
||||
if (!string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
lookupIDToHardware[id] = channel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// resets all status to defaults
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
NoChannelsAssigned = true;
|
||||
AllChannelsResolved = false;
|
||||
ChannelsOutOfPosition = false;
|
||||
HaveAppliedConfigAllUnits = false;
|
||||
StatusAction = null;
|
||||
CompleteAction = null;
|
||||
ProgressAction = null;
|
||||
UnitsConfigured = new IDASCommunication[0];
|
||||
_unresolvedChannels.Clear();
|
||||
_resolvedChannels.Clear();
|
||||
_ExcitationTask = null;
|
||||
_ApplyConfigTask = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,988 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.DASLib.Command;
|
||||
using DTS.DASLib.Service;
|
||||
using DTS.Slice.Service;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.Common.DASResource;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Interface.DASFactory.Download;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public partial class TDAS<T> : Communication<T>,
|
||||
IDASCommunication,
|
||||
IConfigurationActions,
|
||||
IDiagnosticsActions,
|
||||
ITriggerCheckActions,
|
||||
IRealTimeActions,
|
||||
IArmActions,
|
||||
IDownloadActions where T : IConnection, new()
|
||||
{
|
||||
#region Downloading
|
||||
|
||||
public class TDASSetEventInfoAsync : TDASServiceAsyncInfo
|
||||
{
|
||||
public int EventIndex { get; set; }
|
||||
public UInt32 EventHasDownloaded { get; set; }
|
||||
public TDASSetEventInfoAsync(ServiceCallback callback,
|
||||
object userData,
|
||||
int eventIndex,
|
||||
UInt32 eventHasDownloaded)
|
||||
: base(callback, userData)
|
||||
{
|
||||
EventIndex = eventIndex;
|
||||
EventHasDownloaded = eventHasDownloaded;
|
||||
}
|
||||
}
|
||||
public void CorrectT0s(ServiceCallback callback, object userData)
|
||||
{
|
||||
var asyncInfo = new TDASServiceAsyncInfo(callback, userData);
|
||||
asyncInfo.Error("Not supported");
|
||||
return;
|
||||
}
|
||||
void IDownloadActions.SetEventInfo(int eventindex,
|
||||
string id,
|
||||
Guid guid,
|
||||
ulong totalSamples,
|
||||
ulong[] triggerSamples,
|
||||
ulong startRecordSample,
|
||||
UInt32 eventHasDownloaded,
|
||||
ServiceCallback callback,
|
||||
object userData)
|
||||
{
|
||||
var info = new TDASSetEventInfoAsync(callback, userData, eventindex, eventHasDownloaded);
|
||||
LaunchAsyncWorker("TDAS.SetEventInfo", new WaitCallback(AsyncSetEventInfo), info);
|
||||
}
|
||||
|
||||
private void AsyncSetEventInfo(object asyncInfo)
|
||||
{
|
||||
var info = asyncInfo as TDASSetEventInfoAsync;
|
||||
try
|
||||
{
|
||||
if (UInt32.MaxValue != info.EventHasDownloaded)
|
||||
{
|
||||
foreach (DASModule module in ConfigData.Modules)
|
||||
{
|
||||
if (DASInfo.Modules[module.ModuleArrayIndex].TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Command.TDAS.ClearDataAvailable cda = new DTS.DASLib.Command.TDAS.ClearDataAvailable(this);
|
||||
cda.ModuleIndex = module.ModuleArrayIndex;
|
||||
cda.SyncExecute();
|
||||
if (cda.IsErrored) { throw new Exception(string.Format("{0}:{1}", SerialNumber, cda.ResponseData)); }
|
||||
// Only need to do once for G5
|
||||
if (IsG5()) { break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
info.Error("Failed to set event downloaded status", ex);
|
||||
return;
|
||||
}
|
||||
info.Success();
|
||||
}
|
||||
|
||||
void IDownloadActions.Download(ServiceCallback callback, object userData)
|
||||
{
|
||||
if (!Connected)
|
||||
{
|
||||
// "Slice.Download: Not currently connected"
|
||||
throw new Exception(string.Format(Strings.TDAS_Download_NotConnected, ((InfoResult)DASInfo).OwningDAS.SerialNumber));
|
||||
}
|
||||
var state = new TDASDownloadState(callback, userData, WhatToDownload);
|
||||
LaunchAsyncWorker("TDAS.Download", new WaitCallback(TDASDownload), state);
|
||||
}
|
||||
private class TDASDownloadState : TDASServiceAsyncInfo
|
||||
{
|
||||
public IDownloadRequest Request;
|
||||
public ulong SamplesDownloaded; // how many samples have we downloaded so far
|
||||
|
||||
public Command.TDAS.Download DownloadCommand;
|
||||
|
||||
public TDASDownloadState(ServiceCallback cb, object cbObj, IDownloadRequest _Request)
|
||||
: base(cb, cbObj)
|
||||
{
|
||||
Request = _Request;
|
||||
SamplesDownloaded = 0;
|
||||
DownloadCommand = null;
|
||||
}
|
||||
}
|
||||
private static string ToByteFormat(int valIn, int digits)
|
||||
{
|
||||
var bitsString = new StringBuilder(digits);
|
||||
int mask = (1 << digits - 1);
|
||||
for (int i = 0; i < digits; i++)
|
||||
{
|
||||
bitsString.Append((valIn & mask) != 0 ? "1" : "0");
|
||||
mask >>= 1;
|
||||
}
|
||||
return bitsString.ToString();
|
||||
}
|
||||
/// <summary>
|
||||
/// reflects the number of channels on a TOM module (4 SQUIB x 2 channels (squib + current) + 8 digital)
|
||||
/// </summary>
|
||||
private const int TOM_CHANNEL_COUNT = 16;
|
||||
private void TDASDownload(object asyncInfo)
|
||||
{
|
||||
var state = asyncInfo as TDASDownloadState;
|
||||
|
||||
try
|
||||
{
|
||||
int NumberOfChannels = 0;
|
||||
ulong moduleZerosT0 = 0;
|
||||
foreach (var module in EventInfo.Events[WhatToDownload.EventNumber].Modules)
|
||||
{
|
||||
//Since "What to Download" was calculated using the last module with configured channel's trigger point,
|
||||
//set moduleZerosT0 here on the same basis so that the delta calculation below is correct.
|
||||
if ((module.TriggerSampleNumbers != null) && (module.NumberOfConfiguredChannels() > 0))
|
||||
{
|
||||
moduleZerosT0 = module.TriggerSampleNumbers[0];
|
||||
}
|
||||
//if ((module.Channels.Length > 0) && module.Channels[0].ConfigurationMode != DASChannel.ConfigMode.DummyArm)
|
||||
//20088 TDAS Download with unused TOM fails.
|
||||
//TOM modules are included in NewData even if they are dummy armed
|
||||
//so include them in the count
|
||||
if (module.IsDummyArmed() && (!IsG5()) && !IsTom(module)) { continue; }
|
||||
else
|
||||
{
|
||||
NumberOfChannels += module.NumberOfChannels();
|
||||
}
|
||||
}
|
||||
|
||||
ulong totalNumberOfSamples = 1 + WhatToDownload.EndSample - WhatToDownload.StartSample;
|
||||
//const uint downloadChunkSize = 16384;
|
||||
|
||||
ulong downloadChunkSize = 1 + WhatToDownload.EndSample - WhatToDownload.StartSample;
|
||||
|
||||
ulong samplesDownloaded = 0;
|
||||
|
||||
int channelsToDownload = 0;
|
||||
foreach (var iDASModule in EventInfo.Events[WhatToDownload.EventNumber].Modules)
|
||||
{
|
||||
var m = (DASModule)iDASModule;
|
||||
if ((m.Channels.Length > 0) && (!(IsTom(m) && (m.Channels[0].ConfigurationMode == DFConstantsAndEnums.ConfigMode.DummyArm))))
|
||||
{
|
||||
//If DummyArm and a G5, then count the channels; if a TOM don't
|
||||
foreach (var ch in m.Channels)
|
||||
{
|
||||
if (ch is DTS.DASLib.Service.AnalogInputDASChannel)
|
||||
{
|
||||
var aic = ch as DTS.DASLib.Service.AnalogInputDASChannel;
|
||||
if (aic.ConfigurationMode == DFConstantsAndEnums.ConfigMode.Normal)
|
||||
{
|
||||
channelsToDownload++;
|
||||
}
|
||||
}
|
||||
else if (ch is DTS.DASLib.Service.OutputSquibChannel)
|
||||
{
|
||||
var osc = ch as DTS.DASLib.Service.OutputSquibChannel;
|
||||
if (osc.ConfigurationMode == DFConstantsAndEnums.ConfigMode.Normal)
|
||||
{
|
||||
channelsToDownload++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int channelsDownloaded = 0;
|
||||
for (ulong z = WhatToDownload.StartSample; z <= WhatToDownload.EndSample; z += downloadChunkSize)
|
||||
{
|
||||
ulong end = z + downloadChunkSize;
|
||||
bool bDigitalDownload = false;
|
||||
|
||||
if (end > WhatToDownload.EndSample) { end = WhatToDownload.EndSample; }
|
||||
short[][] newData = new short[NumberOfChannels][];
|
||||
for (int i = 0; i < NumberOfChannels; i++)
|
||||
{
|
||||
newData[i] = new short[end + 1 - z];
|
||||
}
|
||||
int channelIdx = -1;
|
||||
for (int i = 0; i < EventInfo.Events[WhatToDownload.EventNumber].Modules.Length && z < WhatToDownload.EndSample; i++)
|
||||
{
|
||||
if (EventInfo.Events[WhatToDownload.EventNumber].Modules[i].IsDummyArmed())
|
||||
{
|
||||
if (IsG5())
|
||||
{
|
||||
//Unlike modules in a rack that don't have channels, G5 modules that don't have channels must all be downloaded (and then purged)
|
||||
channelIdx += EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Count();
|
||||
}
|
||||
|
||||
//20088A TDAS Download with unused TOM fails.
|
||||
//TOM channels are included in the NewData structure
|
||||
//even when dummyarmed, so we must account for it if we see it
|
||||
if (IsTom(EventInfo.Events[WhatToDownload.EventNumber].Modules[i]))
|
||||
{
|
||||
channelIdx += TOM_CHANNEL_COUNT;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
DASModule mod = (DASModule)EventInfo.Events[WhatToDownload.EventNumber].Modules[i];
|
||||
//tdas wants start, end, but wants it specified in terms of - = pretrigger,
|
||||
//+ = post trigger, so we have to convert.
|
||||
|
||||
long start = 0;
|
||||
long stop = 0;
|
||||
|
||||
//we make the adjustment here because the "What to Download" was calculated using
|
||||
//the last module with configured channel's trigger point, but trigger points in tdas are module specific
|
||||
//so we just adjust by the difference in triggers.
|
||||
double delta = mod.TriggerSampleNumbers[0] - (double)moduleZerosT0;
|
||||
|
||||
//hack to move everything to the the left in the window (by moving the data download to the right
|
||||
//this seems inaccurate but is consistent with the TDC viewer.
|
||||
//http://fogbugz/fogbugz/default.asp?7084#45268
|
||||
//DTM - 2016-09-28 we are now _UNDOING_ thing change, per TJK
|
||||
double startSample = (double)(z + delta);
|
||||
double endSample = (double)(end + delta) + 1;
|
||||
|
||||
startSample -= mod.PreTriggerSeconds * mod.SampleRateHz;
|
||||
endSample -= 1 + mod.PreTriggerSeconds * mod.SampleRateHz;
|
||||
|
||||
start = Convert.ToInt64(startSample);
|
||||
stop = Convert.ToInt64(endSample);
|
||||
|
||||
//also per CPB and TJK we are one sample too far, so don't do the below adjustment...
|
||||
//start -= 1;
|
||||
//stop -= 1;
|
||||
|
||||
//NOW per TJK, ADD a sample, for
|
||||
//http://fogbugz/fogbugz/default.asp?8747
|
||||
start += 1;
|
||||
stop += 1;
|
||||
|
||||
short[] dimData = new short[0];
|
||||
bool bIsDIM = !IsG5() &&
|
||||
EventInfo.Events[WhatToDownload.EventNumber].Modules[i].SerialNumber()
|
||||
.StartsWith("DIM");
|
||||
|
||||
if (bIsDIM)
|
||||
{
|
||||
Command.TDAS.Download download = new Command.TDAS.Download(this);
|
||||
download.ChannelIndex = 0;
|
||||
download.ModuleIndex = mod.ModuleArrayIndex;
|
||||
download.FirstPoint = start;
|
||||
download.LastPoint = stop;
|
||||
|
||||
download.SyncExecute();
|
||||
dimData = download.GetData();
|
||||
}
|
||||
|
||||
for (int k = 0; k < EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Length; k++)
|
||||
{
|
||||
channelIdx++;
|
||||
if (EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels[k].ConfigurationMode != DFConstantsAndEnums.ConfigMode.Normal)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//DIMS send there data with all 16 channels per each short
|
||||
//so to get one channel we've already gotten all channels, so to increase efficiency, we process all channels at the same time here as well
|
||||
if (bIsDIM)
|
||||
{
|
||||
if (dimData.Length > 0)
|
||||
{
|
||||
//note that k doesn't necessarily start at 0, so we just start wherever k started at
|
||||
//first we initialize the data structures since we know how much data we will have
|
||||
for (int curChannel = k;
|
||||
curChannel <
|
||||
EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Length;
|
||||
curChannel++)
|
||||
{
|
||||
//we also have to keep in mind, we might have started at 1, and we are adding in the "current" channel index
|
||||
//this is OK with digital channels, because at worse we'll write blank data into the next modules channels, which aren't downloaded yet
|
||||
//[ideally we'd keep track of which channel we are in the module as well, rather than just overall in the DAS]
|
||||
//but we need to make sure we don't index out of range ...
|
||||
if ((curChannel + channelIdx) < newData.Length)
|
||||
{
|
||||
newData[curChannel + channelIdx] = new short[dimData.Length];
|
||||
}
|
||||
}
|
||||
//for each data point, break out all the remaining channels and store the bits
|
||||
//we store them as ADC, which is wasteful, but consistent with Slice pro dim
|
||||
for (int iDataIndex = 0; iDataIndex < dimData.Length; iDataIndex++)
|
||||
{
|
||||
System.Collections.Specialized.BitVector32 bv =
|
||||
new System.Collections.Specialized.BitVector32(
|
||||
Convert.ToInt32(dimData[iDataIndex]));
|
||||
|
||||
for (int curChannel = k;
|
||||
curChannel <
|
||||
EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Length;
|
||||
curChannel++)
|
||||
{
|
||||
//bit vectors expect a bit mask, our bit mask is just the one channel we are interested in
|
||||
if (bv[(1 << curChannel)])
|
||||
{
|
||||
//cur channel starts at k, so we are inserting at just channelIdx, which is what we want
|
||||
//as we increase curChannel we are at channelIdx+1, +2, etc.
|
||||
newData[(curChannel - k) + channelIdx][iDataIndex] = short.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
newData[(curChannel - k) + channelIdx][iDataIndex] = short.MinValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
//update progress
|
||||
int numberOfDigitalIns = EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Length - k;
|
||||
channelsDownloaded += numberOfDigitalIns;
|
||||
state.Progress((int)(100D * channelsDownloaded / channelsToDownload));
|
||||
channelIdx += numberOfDigitalIns - 1;//we are ++ at the begining, so we have to subtract one here as numberOfDigitalIns is inclusive
|
||||
}
|
||||
//we've finished all channels in this module, since it's a DIM ...
|
||||
k = EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels.Length;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels[k] is DTS.DASLib.Service.AnalogInputDASChannel &&
|
||||
(EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels[k] as DTS.DASLib.Service.AnalogInputDASChannel).TypeOfBridge == SensorConstants.BridgeType.DigitalInput
|
||||
&& IsG5())
|
||||
{//download digital all at once
|
||||
bDigitalDownload = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Command.TDAS.Download download = new DTS.DASLib.Command.TDAS.Download(this);
|
||||
if (IsTom(mod))
|
||||
{
|
||||
OutputSquibChannel osc = EventInfo.Events[WhatToDownload.EventNumber].Modules[i].Channels[k] as OutputSquibChannel;
|
||||
if (null == osc) { continue; }
|
||||
switch (osc.MeasurementType)
|
||||
{
|
||||
case SquibMeasurementType.INIT_SIGNAL:
|
||||
case SquibMeasurementType.VOLTAGE:
|
||||
download.DoVoltageOrInsertionDownload = true;
|
||||
break;
|
||||
case SquibMeasurementType.CURRENT:
|
||||
case SquibMeasurementType.NONE:
|
||||
default:
|
||||
download.DoCurrentDownload = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
download.ModuleIndex = mod.ModuleArrayIndex;
|
||||
download.ChannelIndex = k;
|
||||
if (IsTom(mod))
|
||||
{
|
||||
download.ChannelIndex = Convert.ToInt32(System.Math.Floor(download.ChannelIndex / 2D));
|
||||
}
|
||||
|
||||
download.FirstPoint = start;
|
||||
download.LastPoint = stop;
|
||||
|
||||
try
|
||||
{
|
||||
download.SyncExecute();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to download: ", ex);
|
||||
download = new Command.TDAS.Download(this, download);
|
||||
download.SyncExecute();
|
||||
}
|
||||
|
||||
newData[channelIdx] = download.GetData();
|
||||
channelsDownloaded++;
|
||||
state.Progress((int)(100D * channelsDownloaded / channelsToDownload));
|
||||
}
|
||||
}
|
||||
if (bDigitalDownload && IsG5())
|
||||
{
|
||||
Command.TDAS.Download download = new DTS.DASLib.Command.TDAS.Download(this);
|
||||
download.ModuleIndex = 0;
|
||||
|
||||
var mod = EventInfo.Events[0].Modules[0];
|
||||
long start = 0;
|
||||
long stop = 0;
|
||||
|
||||
//we make the adjustment here because the "What to Download" was calculated using
|
||||
//the last module's trigger point, but trigger points in tdas are module specific
|
||||
//so we just adjust by the difference in triggers.
|
||||
double delta = mod.TriggerSampleNumbers[0] - (double)moduleZerosT0;
|
||||
|
||||
double startSample = (double)(z + delta);
|
||||
double endSample = (double)(end + delta);
|
||||
|
||||
startSample -= mod.PreTriggerSeconds * mod.SampleRateHz;
|
||||
endSample -= 1 + mod.PreTriggerSeconds * mod.SampleRateHz;
|
||||
|
||||
start = Convert.ToInt64(startSample);
|
||||
stop = Convert.ToInt64(endSample);
|
||||
|
||||
// Similar to analog channels, this is a somewhat emperically determined adjustment that is suspect.
|
||||
// In contrast, these adjustments are expected to be 1 more sample because the digital channels do not have a filter,
|
||||
// and therefore do not have the same phase delay.
|
||||
download.FirstPoint = start - 1;
|
||||
download.LastPoint = stop - 1;
|
||||
download.Digital = true;
|
||||
download.Bank = 1;
|
||||
try
|
||||
{
|
||||
download.SyncExecute();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log("failed; ", ex);
|
||||
download = new Command.TDAS.Download(this, download);
|
||||
download.SyncExecute();
|
||||
}
|
||||
short[] data = download.GetData();
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (newData[32 + i].Length < data.Length) { newData[32 + i] = new short[data.Length]; }
|
||||
}
|
||||
|
||||
//each short is actually 16 channels of binary data, so we have to parse it out and convert it to ADC for the purpose of the .chn files
|
||||
for (int iDataIndex = 0; iDataIndex < data.Length; iDataIndex++)
|
||||
{
|
||||
System.Collections.Specialized.BitVector32 bv = new System.Collections.Specialized.BitVector32(Convert.ToInt32(data[iDataIndex]));
|
||||
|
||||
//there's another trick in here that we've preserved from TDC, we invert the incoming bit. We do this so that the data appears like
|
||||
//contact closure normally open
|
||||
for (int iChannelIdx = 0; iChannelIdx < 16; iChannelIdx++)
|
||||
{
|
||||
//also note that the bitvector [] operator expects a bitmask, not an index ...
|
||||
if (bv[(1 << iChannelIdx)]) { newData[32 + iChannelIdx][iDataIndex] = short.MinValue; }
|
||||
else { newData[32 + iChannelIdx][iDataIndex] = short.MaxValue; }
|
||||
}
|
||||
}
|
||||
}
|
||||
state.SamplesDownloaded = end - z;
|
||||
|
||||
state.NewData(newData, state.SamplesDownloaded + 1, ulong.MinValue, ulong.MinValue);
|
||||
samplesDownloaded += downloadChunkSize;
|
||||
double ratio = Convert.ToDouble(samplesDownloaded) / Convert.ToDouble(totalNumberOfSamples);
|
||||
if (ratio > 1) { ratio = 1; }
|
||||
//double ratio = Math.Min(1.0, (double)end / (double)(state.Request.EndSample - state.Request.StartSample + 1));
|
||||
state.Progress((int)(ratio * 100.0));
|
||||
}
|
||||
|
||||
//foreach (DASModule module in ConfigData.Modules)
|
||||
foreach (DASModule module in EventInfo.Events[WhatToDownload.EventNumber].Modules)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DASInfo.Modules[module.ModuleArrayIndex].TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK
|
||||
|| module.IsDummyArmed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Command.TDAS.ClearDataAvailable cda = new DTS.DASLib.Command.TDAS.ClearDataAvailable(this);
|
||||
cda.ModuleIndex = module.ModuleArrayIndex;
|
||||
cda.SyncExecute();
|
||||
|
||||
if (IsG5()) { continue; } // only need to do it once
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to set event downloaded status", ex);
|
||||
}
|
||||
}
|
||||
//state.NewData(data.ToArray(), WhatToDownload.EndSample-WhatToDownload.StartSample);
|
||||
state.Progress(100);
|
||||
// send data to user
|
||||
state.Success();
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
state.Cancel();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
state.Error(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Query download
|
||||
void IDownloadActions.QueryDownload(ServiceCallback callback, object userData, int eventIndex, TDASServiceSetupInfo setupInfo)
|
||||
{
|
||||
var info = new TDASServiceAsyncInfo(callback, userData);
|
||||
TDASDownloadServiceAsyncInfo dlSetupInfo = new TDASDownloadServiceAsyncInfo(info, setupInfo);
|
||||
|
||||
if (eventIndex > 0) { info.Error("only single event support for TDAS"); }
|
||||
else { LaunchAsyncWorker("TDAS.QueryDownload", new WaitCallback(AsyncQueryDownloadedStatus), dlSetupInfo); }
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Query downloaded status
|
||||
|
||||
void IDownloadActions.QueryDownloadedStatus(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TDASServiceAsyncInfo(callback, userData);
|
||||
var dlSetupInfo = new TDASDownloadServiceAsyncInfo(info, null);
|
||||
|
||||
LaunchAsyncWorker("TDAS.QueryDownloadedStatus", new WaitCallback(AsyncQueryDownloadedStatus), dlSetupInfo);
|
||||
|
||||
}
|
||||
|
||||
private void AsyncQueryDownloadedStatus(object asyncInfo)
|
||||
{
|
||||
var downloadInfo = asyncInfo as TDASDownloadServiceAsyncInfo;
|
||||
|
||||
var info = downloadInfo.info;
|
||||
var setupInfo = downloadInfo.setupInfo;
|
||||
|
||||
try
|
||||
{
|
||||
var eventDownloadStatus = new List<bool>();
|
||||
var eventIDs = new List<string>();
|
||||
var eventDescriptions = new List<string>();
|
||||
//List<string> eventDescriptions = new List<string>();
|
||||
var eventGUIDs = new List<Guid>();
|
||||
var faultFlags = new List<ushort>();
|
||||
var dasModulesPerEvent = new List<List<DASModule>>();
|
||||
DateTime eventStartTime = DateTime.Now;
|
||||
int levelTriggerAdjustment = 0;
|
||||
|
||||
//turn off lights & clear serial on racks
|
||||
//var qse = new Command.TDAS.QuerySerialNumberBroadcast(this, -1);
|
||||
//qse.SyncExecute();
|
||||
|
||||
for (int i = 0; i < DASInfo.Modules.Length; i++)
|
||||
{
|
||||
string testConfig = "";
|
||||
string testDescription = "";
|
||||
double actualSampleRate = 1D;
|
||||
float hardwareFilterRate = 1F;
|
||||
Command.TDAS.SetupDASLoad.ARMMode recordingMode = Command.TDAS.SetupDASLoad.ARMMode.WAIT;
|
||||
|
||||
if (DASInfo.Modules[i].TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK)
|
||||
{
|
||||
TDASModuleConfig tConfig = new TDASModuleConfig(DASInfo.Modules[i].SerialNumber + ".xml");
|
||||
|
||||
DASModule module = new DASModule(DASInfo.Modules[i].ModuleArrayIndex, this);
|
||||
|
||||
module.StartRecordSampleNumber = 0;
|
||||
|
||||
module.PreTriggerSeconds = 0;
|
||||
module.PostTriggerSeconds = 0;
|
||||
|
||||
module.NumberOfSamples = ulong.MaxValue;
|
||||
|
||||
module.TriggerSampleNumbers = new UInt64[1];
|
||||
module.TriggerSampleNumbers[0] = 0;
|
||||
|
||||
module.Channels = new DASChannel[DASInfo.Modules[i].NumberOfChannels];
|
||||
module.AAFilterRateHz = hardwareFilterRate;
|
||||
module.SampleRateHz = Convert.ToUInt32(System.Math.Abs(actualSampleRate));
|
||||
if (ConfigData != null)
|
||||
{
|
||||
module.Channels = (DASChannel[])ConfigData.Modules[i].Channels.Clone();
|
||||
}
|
||||
|
||||
// update the channel info
|
||||
|
||||
for (uint channelIdx = 0; channelIdx < module.Channels.Length; channelIdx++)
|
||||
{
|
||||
module.Channels[channelIdx].EventStartTime = eventStartTime;
|
||||
}
|
||||
if (dasModulesPerEvent.Count > 0)
|
||||
{
|
||||
//dasModulesPerEvent.Add(new List<DASModule>());
|
||||
dasModulesPerEvent[dasModulesPerEvent.Count - 1].Add(module);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Command.TDAS.QueryDataAvailable qda = new DTS.DASLib.Command.TDAS.QueryDataAvailable(this);
|
||||
qda.ModuleIndex = DASInfo.Modules[i].ModuleArrayIndex;
|
||||
|
||||
qda.SyncExecute();
|
||||
if (null == qda.EventCodes || qda.EventCodes.Length == 0) { APILogger.Log(string.Format("No events found on {0}:{1}", SerialNumber, DASInfo.Modules[i].SerialNumber)); continue; }
|
||||
|
||||
try
|
||||
{
|
||||
//if (IsTom(ConfigData.Modules[i]))
|
||||
if (IsTom(DASInfo.Modules[i].TypeOfModule))
|
||||
{
|
||||
if ((setupInfo == null) || ((setupInfo.CheckoutMode != null) && (setupInfo.SamplesPerSecond == null)))
|
||||
{
|
||||
//We were not called from the Download tile
|
||||
Command.TDAS.SetupTOMDASRead sdr = new DTS.DASLib.Command.TDAS.SetupTOMDASRead(this);
|
||||
sdr.ModuleIndex = DASInfo.Modules[i].ModuleArrayIndex;
|
||||
sdr.SyncExecute();
|
||||
string sTemp = sdr.TestConfig;
|
||||
string[] tokens = sTemp.Split(SETUPDASREAD_SENTINEL);
|
||||
if (tokens.Length >= 2) { testConfig = tokens[0]; testDescription = tokens[1]; }
|
||||
else { testConfig = tokens[0]; }
|
||||
|
||||
//testConfig = sdr.TestConfig;
|
||||
actualSampleRate = sdr.ActualSampleRate;
|
||||
if ((setupInfo != null) && ((bool)setupInfo.CheckoutMode))
|
||||
{
|
||||
actualSampleRate = Math.Abs(actualSampleRate);
|
||||
}
|
||||
hardwareFilterRate = sdr.HardwareFilter;
|
||||
recordingMode = sdr.ArmMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
//We were called from the Download tile, which means that SDL was not done, so SDR above would have failed
|
||||
GetUserSelectedSetupInfo(setupInfo, ref testConfig, ref testDescription, ref actualSampleRate, ref hardwareFilterRate, ref recordingMode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DASInfo.Modules[i].TypeOfModule == DFConstantsAndEnums.ModuleType.ProDIM && !IsG5())
|
||||
{
|
||||
if ((setupInfo == null) || ((setupInfo.CheckoutMode != null) && (setupInfo.SamplesPerSecond == null)))
|
||||
{
|
||||
//We were not called from the Download tile
|
||||
Command.TDAS.SetupDASReadDIM sdr = new DTS.DASLib.Command.TDAS.SetupDASReadDIM(this);
|
||||
|
||||
sdr.ModuleIndex = DASInfo.Modules[i].ModuleArrayIndex;
|
||||
sdr.SyncExecute();
|
||||
string sTemp = sdr.TestConfig;
|
||||
string[] tokens = sTemp.Split(SETUPDASREAD_SENTINEL);
|
||||
if (2 <= tokens.Length)
|
||||
{
|
||||
testConfig = tokens[0];
|
||||
testDescription = tokens[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
testConfig = tokens[0];
|
||||
testDescription = tokens[0];
|
||||
}
|
||||
|
||||
recordingMode = sdr.ArmMode;
|
||||
actualSampleRate = sdr.ActualSampleRate;
|
||||
}
|
||||
else
|
||||
{
|
||||
//We were called from the Download tile, which means that SDL was not done, so SDR above would have failed
|
||||
GetUserSelectedSetupInfo(setupInfo, ref testConfig, ref testDescription, ref actualSampleRate, ref hardwareFilterRate, ref recordingMode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((setupInfo == null) || ((setupInfo.CheckoutMode != null) && (setupInfo.SamplesPerSecond == null)))
|
||||
{
|
||||
//We were not called from the Download tile
|
||||
Command.TDAS.SetupDASRead sdr = new DTS.DASLib.Command.TDAS.SetupDASRead(this);
|
||||
|
||||
sdr.ModuleIndex = DASInfo.Modules[i].ModuleArrayIndex;
|
||||
sdr.SyncExecute();
|
||||
string sTemp = sdr.TestConfig;
|
||||
string[] tokens = sTemp.Split(SETUPDASREAD_SENTINEL);
|
||||
if (2 <= tokens.Length)
|
||||
{
|
||||
testConfig = tokens[0];
|
||||
testDescription = tokens[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
testConfig = tokens[0];
|
||||
testDescription = tokens[0];
|
||||
}
|
||||
|
||||
actualSampleRate = sdr.ActualSampleRate;
|
||||
hardwareFilterRate = sdr.HardwareFilter;
|
||||
recordingMode = sdr.ArmMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
//We were called from the Download tile, which means that SDL was not done, so SDR above would have failed
|
||||
GetUserSelectedSetupInfo(setupInfo, ref testConfig, ref testDescription, ref actualSampleRate, ref hardwareFilterRate, ref recordingMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log("Error get SDR", ex);
|
||||
}
|
||||
//Command.TDAS.QueryDataAvailable qda = new DTS.DASLib.Command.TDAS.QueryDataAvailable(this);
|
||||
//qda.ModuleIndex = DASInfo.Modules[i].ModuleArrayIndex;
|
||||
|
||||
//qda.SyncExecute();
|
||||
TDASModuleConfig tConfig = new TDASModuleConfig(DASInfo.Modules[i].SerialNumber + ".xml");
|
||||
//if (null != qda.eventCodes && qda.eventCodes.Length > 0)
|
||||
{
|
||||
foreach (string eventCode in qda.EventCodes)
|
||||
{
|
||||
if (!eventIDs.Contains(eventCode))
|
||||
{
|
||||
if (testConfig.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
eventGUIDs.Add(new Guid("11111111111111111111111111111111"));
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log("invalid test guid - ", testConfig, ex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else { continue; }
|
||||
eventIDs.Add(eventCode);
|
||||
eventDescriptions.Add(testDescription);
|
||||
|
||||
//eventGUIDs.Add(Guid.Empty);
|
||||
faultFlags.Add(0);
|
||||
eventDownloadStatus.Add(qda.IsDownloaded);
|
||||
dasModulesPerEvent.Add(new List<DASModule>());
|
||||
}
|
||||
DASModule module = new DASModule(DASInfo.Modules[i].ModuleArrayIndex, this);
|
||||
|
||||
switch (recordingMode)
|
||||
{
|
||||
case Command.TDAS.SetupDASLoad.ARMMode.WAIT:
|
||||
module.RecordingMode = DFConstantsAndEnums.RecordingMode.CircularBuffer;
|
||||
break;
|
||||
case Command.TDAS.SetupDASLoad.ARMMode.TAPE:
|
||||
module.RecordingMode = DFConstantsAndEnums.RecordingMode.RecorderMode;
|
||||
break;
|
||||
}
|
||||
module.StartRecordSampleNumber = 0;
|
||||
module.PreTriggerSeconds = System.Math.Truncate(100D * qda.PreTriggerSamples / actualSampleRate) / 100D;
|
||||
module.PostTriggerSeconds = System.Math.Truncate(100D * qda.PostTriggerSamples / actualSampleRate) / 100D;
|
||||
|
||||
module.NumberOfSamples = Convert.ToUInt64(qda.PreTriggerSamples + qda.PostTriggerSamples);
|
||||
module.TriggerSampleNumbers = new UInt64[1];
|
||||
module.TriggerSampleNumbers[0] = Convert.ToUInt64(qda.PreTriggerSamples + 1);
|
||||
|
||||
ulong phaseshift = GetPhaseShiftSamples(Convert.ToUInt32(module.ModuleArrayIndex), actualSampleRate, Convert.ToUInt32(hardwareFilterRate), module.TriggerSampleNumbers[0]);
|
||||
|
||||
module.TriggerSampleNumbers[0] += phaseshift;
|
||||
|
||||
module.Channels = new DASChannel[DASInfo.Modules[i].NumberOfChannels];
|
||||
module.AAFilterRateHz = hardwareFilterRate;
|
||||
module.SampleRateHz = Convert.ToUInt32(System.Math.Abs(actualSampleRate));
|
||||
if (null != ConfigData)
|
||||
{
|
||||
module.Channels = (DASChannel[])ConfigData.Modules[i].Channels.Clone();
|
||||
|
||||
// update the channel info
|
||||
|
||||
for (uint channelIdx = 0; channelIdx < module.Channels.Length; channelIdx++)
|
||||
{
|
||||
module.Channels[channelIdx].EventStartTime = eventStartTime;
|
||||
}
|
||||
dasModulesPerEvent[eventIDs.IndexOf(eventCode)].Add(module);
|
||||
}
|
||||
|
||||
if (qda.LevelTriggerOffset > levelTriggerAdjustment)
|
||||
{
|
||||
levelTriggerAdjustment = qda.LevelTriggerOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < dasModulesPerEvent.Count() && 0 < dasModulesPerEvent[0].Count())
|
||||
{
|
||||
foreach (DASModule tempModule in dasModulesPerEvent[0])
|
||||
{
|
||||
foreach (var channel in tempModule.Channels)
|
||||
{
|
||||
channel.LevelTriggerT0AdjustmentSamples = levelTriggerAdjustment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetEventGuids(eventGUIDs.ToArray());
|
||||
SetEventFaultFlags(faultFlags.ToArray());
|
||||
DownloadReport dlReport = new DownloadReport();
|
||||
dlReport.Events = new DownloadReport.EventInfo[EventGuids.Length];
|
||||
for (int eventIndex = 0; eventIndex < EventGuids.Length; eventIndex++)
|
||||
{
|
||||
dlReport.Events[eventIndex] = new DownloadReport.EventInfo();
|
||||
dlReport.Events[eventIndex].Description = eventDescriptions[eventIndex];
|
||||
dlReport.Events[eventIndex].EventNumber = eventIndex;
|
||||
dlReport.Events[eventIndex].TestID = eventIDs[eventIndex];
|
||||
dlReport.Events[eventIndex].HasBeenDownloaded = false;
|
||||
dlReport.Events[eventIndex].WasTriggered = false;
|
||||
dlReport.Events[eventIndex].TestGUID = EventGuids[eventIndex];
|
||||
dlReport.Events[eventIndex].ClearFaults();
|
||||
dlReport.Events[eventIndex].Modules = dasModulesPerEvent[eventIndex].ToArray();
|
||||
}
|
||||
|
||||
for (int eventIndex = 0; eventIndex < EventGuids.Length; eventIndex++)
|
||||
{
|
||||
double minPre = double.MaxValue;
|
||||
double minPost = double.MaxValue;
|
||||
bool dummyArmed = true;
|
||||
foreach (var module in dasModulesPerEvent[eventIndex])
|
||||
{
|
||||
if (DASInfo.Modules[module.ModuleArrayIndex].TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK) { continue; }
|
||||
if ((module.PreTriggerSeconds >= 0) && (module.PostTriggerSeconds >= 0))
|
||||
{
|
||||
// Negative trigger seconds are from dummy-armed modules
|
||||
minPre = System.Math.Min(module.PreTriggerSeconds, minPre);
|
||||
minPost = System.Math.Min(module.PostTriggerSeconds, minPost);
|
||||
dummyArmed = false;
|
||||
}
|
||||
}
|
||||
if (0 == dlReport.Events[eventIndex].Modules.Length) { }
|
||||
else
|
||||
{
|
||||
if (!dummyArmed)
|
||||
{
|
||||
ulong numberOfSamples = Convert.ToUInt64((minPre + minPost) * dlReport.Events[eventIndex].Modules[0].SampleRateHz);
|
||||
for (int i = 0; i < dlReport.Events[eventIndex].Modules.Length; i++)
|
||||
{
|
||||
DASModule module = (DASModule)dlReport.Events[eventIndex].Modules[i];
|
||||
module.PreTriggerSeconds = minPre;
|
||||
module.PostTriggerSeconds = minPost;
|
||||
module.TriggerSampleNumbers = new ulong[]
|
||||
{
|
||||
Convert.ToUInt64(minPre*System.Math.Abs(module.SampleRateHz))
|
||||
};
|
||||
// If not triggered, racks return 0 and G5s return number of samples
|
||||
if ((module.TriggerSampleNumbers[0] > 0) && (module.TriggerSampleNumbers[0] < numberOfSamples))
|
||||
{
|
||||
dlReport.Events[eventIndex].WasTriggered = true;
|
||||
}
|
||||
//the above statement the pretrigger seconds appears to be off by one sample, so I adjust it here as
|
||||
//there might already be a lot of different side effects to changing the pre trigger time.
|
||||
if (module.TriggerSampleNumbers[0] > 0) { module.TriggerSampleNumbers[0] = module.TriggerSampleNumbers[0] - 1; }
|
||||
|
||||
module.NumberOfSamples = numberOfSamples;
|
||||
//module.NumberOfSamples = Convert.ToUInt64(qda.PreTriggerSamples + qda.PostTriggerSamples);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//normalize the data here just for sanity sake.
|
||||
//IE, set start to min(abs(preTrigger))
|
||||
//set end to min(abs(posttrigger))
|
||||
//set t0 to min(abs(preTrigger))
|
||||
|
||||
SetEventInfo(dlReport);
|
||||
SetEventDownloadStatus(eventDownloadStatus.ToArray());
|
||||
if (null != EventInfo && EventInfo.Events.Length > 0)
|
||||
{
|
||||
for (int i = 0; i < EventInfo.Events.Length && i < EventDownloadedStatus.Length; i++)
|
||||
{
|
||||
if (EventInfo.Events[i].TestID == "TESTTRIG") { EventDownloadedStatus[i] = true; }
|
||||
}
|
||||
}
|
||||
|
||||
info.Success();
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
info.Cancel();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
info.Error(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetUserSelectedSetupInfo(TDASServiceSetupInfo setupInfo, ref string testConfig, ref string testDescription, ref double actualSampleRate,
|
||||
ref float hardwareFilterRate, ref Command.TDAS.SetupDASLoad.ARMMode recordingMode)
|
||||
{
|
||||
if (setupInfo == null)
|
||||
{
|
||||
testConfig = "";
|
||||
testDescription = "";
|
||||
actualSampleRate = 1D;
|
||||
hardwareFilterRate = 1F;
|
||||
recordingMode = Command.TDAS.SetupDASLoad.ARMMode.WAIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this was from the Download tile, use the SETUP that the user selected
|
||||
testConfig = "UsingUser-specifiedTestSetup";
|
||||
testDescription = setupInfo.SetupDescription;
|
||||
actualSampleRate = (double)setupInfo.SamplesPerSecond;
|
||||
hardwareFilterRate = setupInfo.HardwareFilterRateHz;
|
||||
switch (setupInfo.RecordingMode)
|
||||
{
|
||||
case DFConstantsAndEnums.RecordingMode.CircularBuffer:
|
||||
case DFConstantsAndEnums.RecordingMode.CircularBufferPlusUART:
|
||||
recordingMode = Command.TDAS.SetupDASLoad.ARMMode.WAIT;
|
||||
break;
|
||||
case DFConstantsAndEnums.RecordingMode.RecorderMode:
|
||||
case DFConstantsAndEnums.RecordingMode.RecorderModePlusUART:
|
||||
case DFConstantsAndEnums.RecordingMode.a14_NormalRecorderAndStreamSubSampleMode:
|
||||
recordingMode = Command.TDAS.SetupDASLoad.ARMMode.TAPE;
|
||||
break;
|
||||
default:
|
||||
recordingMode = Command.TDAS.SetupDASLoad.ARMMode.WAIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Set trigger sample numbers
|
||||
|
||||
void IDownloadActions.SetTriggerSampleNumbers(ServiceCallback callback, object userData)
|
||||
{
|
||||
throw new NotSupportedException("SetTriggerSampleNumbers not supported for TDAS");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Set downloaded
|
||||
void IDownloadActions.SetDownloaded(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TDASSetEventInfoAsync(callback, userData, 0, 1);
|
||||
//FB12656: Launch synchronously. This call needs the full round-trip (4s) before proceeding with other commands
|
||||
CallSyncMethod("TDAS.SetDownloaded", SendClearDataAvailable, info);
|
||||
}
|
||||
|
||||
private void SendClearDataAvailable(object asyncInfo)
|
||||
{
|
||||
var info = asyncInfo as TDASSetEventInfoAsync;
|
||||
try
|
||||
{
|
||||
if (UInt32.MaxValue != info.EventHasDownloaded)
|
||||
{
|
||||
foreach (DASModule module in ConfigData.Modules)
|
||||
{
|
||||
if (DASInfo.Modules[module.ModuleArrayIndex].TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK
|
||||
|| module.IsDummyArmed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Command.TDAS.ClearDataAvailable cda = new DTS.DASLib.Command.TDAS.ClearDataAvailable(this);
|
||||
cda.ModuleIndex = module.ModuleArrayIndex;
|
||||
cda.SyncExecute();
|
||||
if (cda.IsErrored) { throw new Exception(string.Format("{0}:{1}", SerialNumber, cda.ResponseData)); }
|
||||
// Only need to do once for G5
|
||||
if (IsG5()) { break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
info.Error("Failed to set event downloaded status", ex);
|
||||
return;
|
||||
}
|
||||
info.Success();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user