init
This commit is contained in:
2208
DataPRO/IService/Classes/TDAS Service/Arming.cs
Normal file
2208
DataPRO/IService/Classes/TDAS Service/Arming.cs
Normal file
File diff suppressed because it is too large
Load Diff
2437
DataPRO/IService/Classes/TDAS Service/Callibration.cs
Normal file
2437
DataPRO/IService/Classes/TDAS Service/Callibration.cs
Normal file
File diff suppressed because it is too large
Load Diff
846
DataPRO/IService/Classes/TDAS Service/Config.Attributes.cs
Normal file
846
DataPRO/IService/Classes/TDAS Service/Config.Attributes.cs
Normal file
@@ -0,0 +1,846 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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.ICommunication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
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()
|
||||
{
|
||||
long IDASCommunication.MaxMemory()
|
||||
{
|
||||
long result = 0;
|
||||
if ((DASInfo.MaxEventStorageSpaceInBytes == null) && (DASInfo.Modules.Count() > 0))
|
||||
{
|
||||
result = long.MaxValue;
|
||||
foreach (InfoResult.Module module in DASInfo.Modules)
|
||||
{
|
||||
if (module.SerialNumber != "EMPTY")
|
||||
{
|
||||
result = (long)Math.Min(result, (decimal)(module.MaxEventStorageSpaceInBytes / module.NumberOfBytesPerSampleClock));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((DASInfo.MaxEventStorageSpaceInBytes != null) && (DASInfo.NumberOfBytesPerSampleClock != null))
|
||||
{
|
||||
result = (long)(DASInfo.MaxEventStorageSpaceInBytes / DASInfo.NumberOfBytesPerSampleClock);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
uint IDASCommunication.MinSampleRate()
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
|
||||
private const double _MaxG5SamplingRate = 100000.0;
|
||||
private const double _MaxSamplingRate = 305000.0; //FB16312 changed to 305kHz to match TDC "Version 5.1B"
|
||||
uint IDASCommunication.MaxSampleRate(int numberOfConfiguredChannels)
|
||||
{
|
||||
return MaxSampleRate(IsG5(), numberOfConfiguredChannels);
|
||||
}
|
||||
|
||||
uint IDASCommunication.MaxAAFilterRate()
|
||||
{
|
||||
return MaxAAFilterRateHz;
|
||||
}
|
||||
//FB16312: surface calculation for generic use
|
||||
public static uint MaxSampleRate(bool isG5, int numberOfConfiguredChannels)
|
||||
{
|
||||
if (isG5)
|
||||
{
|
||||
//return Convert.ToUInt32(System.Math.Floor(_MaxSamplingRate / 32D));
|
||||
return Convert.ToUInt32(_MaxG5SamplingRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (numberOfConfiguredChannels > 0) ?
|
||||
Convert.ToUInt32(Math.Floor(_MaxSamplingRate / numberOfConfiguredChannels)) :
|
||||
Convert.ToUInt32(Math.Floor(_MaxSamplingRate / 1));
|
||||
}
|
||||
}
|
||||
/*
|
||||
private class ConfigAttributes
|
||||
{
|
||||
ICommunication com { get; set; }
|
||||
|
||||
public ConfigAttributes(DTS.Common.Interface.DASFactory.ICommunication _com)
|
||||
{
|
||||
com = _com;
|
||||
}
|
||||
|
||||
public void PurgeStaleData(IDASCommunication das)
|
||||
{
|
||||
var cmd = new SetArmAttributesToDefaults(com);
|
||||
cmd.SyncExecute();
|
||||
|
||||
// get bridge stuff
|
||||
var dacValues = new UInt16[das.ConfigData.NumberOfChannels()];
|
||||
foreach (var module in das.DASInfo.Modules)
|
||||
{
|
||||
var odQuery = new QuerySystemAttribute_Bridge(com);
|
||||
odQuery.DeviceID = (byte)(module.ModuleArrayIndex + 1);
|
||||
|
||||
odQuery.Key = AttributeTypes.SystemAttributes_Bridge.OffsetDACA_Midscale;
|
||||
odQuery.SyncExecute();
|
||||
dacValues[module.ModuleArrayIndex * 3 + 0] = (UInt16)odQuery.Value;
|
||||
|
||||
odQuery.Key = AttributeTypes.SystemAttributes_Bridge.OffsetDACB_Midscale;
|
||||
odQuery.SyncExecute();
|
||||
dacValues[module.ModuleArrayIndex * 3 + 1] = (UInt16)odQuery.Value;
|
||||
|
||||
odQuery.Key = AttributeTypes.SystemAttributes_Bridge.OffsetDACC_Midscale;
|
||||
odQuery.SyncExecute();
|
||||
dacValues[module.ModuleArrayIndex * 3 + 2] = (UInt16)odQuery.Value;
|
||||
}
|
||||
|
||||
// set base stuff
|
||||
var odSet = new SetArmAttribute(com);
|
||||
odSet.SetValue(AttributeTypes.ArmAndEventAttributes.StackChannelOffsetDACSettings, dacValues, true);
|
||||
odSet.SyncExecute();
|
||||
}
|
||||
|
||||
#region Arm attribute helpers
|
||||
|
||||
private void SetArmAttribute(AttributeTypes.ArmAndEventAttributes key, object value, bool ShouldOverwrite)
|
||||
{
|
||||
var set = new SetArmAttribute(com);
|
||||
set.SetValue(key, value, ShouldOverwrite);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes key, Test.Module.RecordingMode value)
|
||||
{
|
||||
SetArmAttribute(key, (byte)value, true);
|
||||
}
|
||||
|
||||
public void SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes key, UInt32 value)
|
||||
{
|
||||
SetArmAttribute(key, value, true);
|
||||
}
|
||||
|
||||
public void SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes key, float value)
|
||||
{
|
||||
SetArmAttribute(key, value, true);
|
||||
}
|
||||
|
||||
public void SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes key, string value)
|
||||
{
|
||||
var set = new SetArmAttribute(com);
|
||||
var ByteArrayData = Encoding.UTF8.GetBytes(value);
|
||||
set.SetValue(key, ByteArrayData, true);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes key, UInt64 value)
|
||||
{
|
||||
SetArmAttribute(key, value, true);
|
||||
}
|
||||
|
||||
public void GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes key, out Test.Module.RecordingMode value)
|
||||
{
|
||||
var query = new QueryArmAttribute(com);
|
||||
query.Key = key;
|
||||
query.SyncExecute();
|
||||
if ((AttributeTypes.AttributeDataTypes)query.DataType != AttributeTypes.AttributeDataTypes.UInt8)
|
||||
throw new System.Exception("ConfigurationService.GetArmAttribute.RecordingMode: Found type " + (AttributeTypes.AttributeDataTypes)query.DataType);
|
||||
value = (Test.Module.RecordingMode)query.Value;
|
||||
}
|
||||
|
||||
public void GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes key, out UInt32 value)
|
||||
{
|
||||
var query = new QueryArmAttribute(com);
|
||||
query.Key = key;
|
||||
query.SyncExecute();
|
||||
if ((AttributeTypes.AttributeDataTypes)query.DataType != AttributeTypes.AttributeDataTypes.UInt32)
|
||||
throw new System.Exception("ConfigurationService.GetArmAttribute.UInt32: Found type " + (AttributeTypes.AttributeDataTypes)query.DataType);
|
||||
value = (UInt32)query.Value;
|
||||
}
|
||||
|
||||
public void GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes key, out float value)
|
||||
{
|
||||
var query = new QueryArmAttribute(com);
|
||||
query.Key = key;
|
||||
query.SyncExecute();
|
||||
if ((AttributeTypes.AttributeDataTypes)query.DataType != AttributeTypes.AttributeDataTypes.Float32)
|
||||
throw new System.Exception("ConfigurationService.GetArmAttribute.float: Found type " + (AttributeTypes.AttributeDataTypes)query.DataType);
|
||||
value = (float)query.Value;
|
||||
}
|
||||
|
||||
public void GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes key, out string value)
|
||||
{
|
||||
var query = new QueryArmAttribute(com);
|
||||
query.Key = key;
|
||||
query.SyncExecute();
|
||||
if ((AttributeTypes.AttributeDataTypes)query.DataType != AttributeTypes.AttributeDataTypes.Unicode)
|
||||
{
|
||||
throw new System.Exception("ConfigurationService.GetArmAttribute.string: Found type " + (AttributeTypes.AttributeDataTypes)query.DataType);
|
||||
}
|
||||
var values = query.Value as byte[];
|
||||
value = Encoding.UTF8.GetString(values);
|
||||
}
|
||||
|
||||
public void GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes key, out UInt64 value)
|
||||
{
|
||||
var query = new QueryArmAttribute(com);
|
||||
query.Key = key;
|
||||
query.SyncExecute();
|
||||
if ((AttributeTypes.AttributeDataTypes)query.DataType != AttributeTypes.AttributeDataTypes.UInt64)
|
||||
throw new System.Exception("ConfigurationService.GetArmAttribute.UInt64: Found type " + (AttributeTypes.AttributeDataTypes)query.DataType);
|
||||
value = (UInt64)query.Value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region XML attributes
|
||||
|
||||
public void StoreXMLConfig(string data, SliceServiceAsyncInfo info, double ProgressSteps)
|
||||
{
|
||||
if (string.IsNullOrEmpty(data))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// since this might contain multi byte characters, we need to convert it to a byte array first
|
||||
var ByteArrayData = Encoding.UTF8.GetBytes(data);
|
||||
|
||||
// calc how many we need
|
||||
var NumBlocks = ByteArrayData.Length / DTS.Slice.Service.Attribute.MaxSingleAttributeSize;
|
||||
if ((ByteArrayData.Length % DTS.Slice.Service.Attribute.MaxSingleAttributeSize) != 0)
|
||||
{
|
||||
NumBlocks++;
|
||||
}
|
||||
|
||||
// write the blocks
|
||||
// for progress, assume that we'll have about 40 blocks to write
|
||||
var blockWeight = 40.0 / (double)NumBlocks;
|
||||
for (int BlockIdx = 0; BlockIdx < NumBlocks; BlockIdx++)
|
||||
{
|
||||
// contruct the current block
|
||||
int blockLength = ByteArrayData.Length - (BlockIdx * DTS.Slice.Service.Attribute.MaxSingleAttributeSize);
|
||||
if (blockLength > DTS.Slice.Service.Attribute.MaxSingleAttributeSize)
|
||||
{
|
||||
blockLength = DTS.Slice.Service.Attribute.MaxSingleAttributeSize;
|
||||
}
|
||||
var block = new byte[blockLength];
|
||||
Array.Copy(ByteArrayData, BlockIdx * DTS.Slice.Service.Attribute.MaxSingleAttributeSize, block, 0, blockLength);
|
||||
|
||||
// write it to firmware
|
||||
var AttrSet = new SetArmAttribute(com);
|
||||
var attrNum = (AttributeTypes.ArmAndEventAttributes)(DTS.Slice.Service.Attribute.BulkAttributeStartNumber + BlockIdx);
|
||||
AttrSet.SetValue(attrNum, block, AttributeTypes.AttributeDataTypes.Unicode, true);
|
||||
AttrSet.SyncExecute();
|
||||
info.Progress((int)((12.0 + blockWeight * (double)BlockIdx) / ProgressSteps * 100.0));
|
||||
}
|
||||
|
||||
// write our speacial header attribute
|
||||
var InvariantCulture = new System.Globalization.CultureInfo("");
|
||||
var BlockList = new StringBuilder(DTS.Slice.Service.Attribute.BulkAttributeStartNumber.ToString(InvariantCulture),
|
||||
DTS.Slice.Service.Attribute.MaxSingleAttributeSize);
|
||||
for (int BlockIdx = 1; BlockIdx < NumBlocks; BlockIdx++)
|
||||
{
|
||||
BlockList.Append("," + (DTS.Slice.Service.Attribute.BulkAttributeStartNumber + BlockIdx).ToString(InvariantCulture));
|
||||
}
|
||||
var HeaderAttrSet = new SetArmAttribute(com);
|
||||
// this attribute only contains digits and commas so it's OK to keep it as Ascii
|
||||
HeaderAttrSet.SetValue(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.StoredConfigIndex,
|
||||
BlockList.ToString(), AttributeTypes.AttributeDataTypes.Ascii, true);
|
||||
HeaderAttrSet.SyncExecute();
|
||||
}
|
||||
|
||||
public string RetrieveXMLConfig()
|
||||
{
|
||||
// first get our special header attribute
|
||||
var AttrGet = new QueryArmAttribute(com);
|
||||
AttrGet.Key = AttributeTypes.ArmAndEventAttributes.StoredConfigIndex;
|
||||
AttrGet.SyncExecute();
|
||||
// this attribute only contains digits and commas so it's OK to keep it as Ascii (see above)
|
||||
var BlockListStr = AttrGet.Value as string;
|
||||
|
||||
// still there?
|
||||
if (string.IsNullOrEmpty(BlockListStr))
|
||||
{
|
||||
// "Slice.RetrieveAttributes: Header attribute as string is empty"
|
||||
throw new System.Exception(Strings.Slice_RetrieveAttributes_Err2);
|
||||
}
|
||||
|
||||
var InvariantCulture = new System.Globalization.CultureInfo("");
|
||||
var BlockListStrArr = BlockListStr.Split(',');
|
||||
var BlockList = new List<ushort>();
|
||||
foreach (string NumStr in BlockListStrArr)
|
||||
{
|
||||
ushort Number = 0;
|
||||
if (!ushort.TryParse(NumStr, System.Globalization.NumberStyles.Integer, InvariantCulture, out Number))
|
||||
{
|
||||
// "Slice.RetrieveAttributes: Header attribute is invalid"
|
||||
throw new System.Exception(Strings.Slice_RetrieveAttributes_Err3);
|
||||
}
|
||||
BlockList.Add(Number);
|
||||
}
|
||||
var AllStrings = new StringBuilder(BlockList.Count * DTS.Slice.Service.Attribute.MaxSingleAttributeSize);
|
||||
|
||||
foreach (var AttrNumber in BlockList)
|
||||
{
|
||||
AttrGet.Key = (AttributeTypes.ArmAndEventAttributes)AttrNumber;
|
||||
AttrGet.SyncExecute();
|
||||
// old version stored the data as Ascii
|
||||
if (AttrGet.DataType == AttributeTypes.AttributeDataTypes.Ascii)
|
||||
{
|
||||
var values = AttrGet.Value as string;
|
||||
AllStrings.Append(values);
|
||||
}
|
||||
// new version uses Unicode (basically byte[])
|
||||
else if (AttrGet.DataType == AttributeTypes.AttributeDataTypes.Unicode)
|
||||
{
|
||||
var values = AttrGet.Value as byte[];
|
||||
var str = Encoding.UTF8.GetString(values);
|
||||
AllStrings.Append(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is really bad!
|
||||
throw new System.Exception(string.Format("RetrieveXMLConfig: Unknown datatype {0}", AttrGet.DataType.ToString()));
|
||||
}
|
||||
}
|
||||
var WholeStr = AllStrings.ToString();
|
||||
if (string.IsNullOrEmpty(WholeStr))
|
||||
{
|
||||
// "Slice.RetrieveAttributes: Attributes are empty"
|
||||
throw new System.Exception(Strings.Slice_RetrieveAttributes_Err4);
|
||||
}
|
||||
return WholeStr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the XML string that was split and stored in the Arm attributes
|
||||
/// </summary>
|
||||
/// <param name="eventNum">The event number to get it from</param>
|
||||
/// <param name="progress"></param>
|
||||
/// <returns>The combined XML string</returns>
|
||||
public string RetrieveEventXMLConfig(int eventNum, QueryDownloadProgress progress)
|
||||
{
|
||||
// first get our special header attribute
|
||||
var AttrGet = new QueryEventAttribute(com);
|
||||
AttrGet.EventNumber = (ushort)eventNum;
|
||||
AttrGet.Key = AttributeTypes.ArmAndEventAttributes.StoredConfigIndex;
|
||||
AttrGet.SyncExecute();
|
||||
progress.Step();
|
||||
|
||||
var BlockListStr = AttrGet.Value as string;
|
||||
|
||||
// still there?
|
||||
if (string.IsNullOrEmpty(BlockListStr))
|
||||
{
|
||||
// "Slice.RetrieveEventAttributes: Header attribute is empty"
|
||||
throw new System.Exception(Strings.Slice_RetrieveEventAttributes_Err1);
|
||||
}
|
||||
|
||||
var InvariantCulture = new System.Globalization.CultureInfo("");
|
||||
var BlockListStrArr = BlockListStr.Split(',');
|
||||
var BlockList = new List<ushort>();
|
||||
foreach (string NumStr in BlockListStrArr)
|
||||
{
|
||||
ushort Number = 0;
|
||||
if (!ushort.TryParse(NumStr, System.Globalization.NumberStyles.Integer, InvariantCulture, out Number))
|
||||
{
|
||||
// "Slice.RetrieveEventAttributes: Header attribute is invalid"
|
||||
throw new System.Exception(Strings.Slice_RetrieveEventAttributes_Err2);
|
||||
}
|
||||
BlockList.Add(Number);
|
||||
}
|
||||
var AllStrings = new StringBuilder(BlockList.Count * DTS.Slice.Service.Attribute.MaxSingleAttributeSize);
|
||||
|
||||
foreach (var AttrNumber in BlockList)
|
||||
{
|
||||
AttrGet.Key = (AttributeTypes.ArmAndEventAttributes)AttrNumber;
|
||||
AttrGet.SyncExecute();
|
||||
progress.Step();
|
||||
// old version stored the data as Ascii
|
||||
if (AttrGet.DataType == AttributeTypes.AttributeDataTypes.Ascii)
|
||||
{
|
||||
var values = AttrGet.Value as string;
|
||||
AllStrings.Append(values);
|
||||
}
|
||||
// new version uses Unicode (basically byte[])
|
||||
else if (AttrGet.DataType == AttributeTypes.AttributeDataTypes.Unicode)
|
||||
{
|
||||
var values = AttrGet.Value as byte[];
|
||||
var str = Encoding.UTF8.GetString(values);
|
||||
AllStrings.Append(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is really bad!
|
||||
throw new System.Exception(string.Format("RetrieveEventXMLConfig(event={0}): Unknown datatype {1}",
|
||||
eventNum, AttrGet.DataType.ToString()));
|
||||
}
|
||||
}
|
||||
var WholeStr = AllStrings.ToString();
|
||||
if (string.IsNullOrEmpty(WholeStr))
|
||||
{
|
||||
// "Slice.RetrieveEventAttributes: Attributes are empty"
|
||||
throw new System.Exception(Strings.Slice_RetrieveEventAttributes_Err3);
|
||||
}
|
||||
return WholeStr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void ConfigureRange(float[] ranges)
|
||||
{
|
||||
// this function shall just set the range attribute for channel
|
||||
var set = new SetArmAttribute(com);
|
||||
set.SetValue(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.StackChannelRangesMillivolts, ranges, true);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void ConfigureBridge(bool[] IsHalfBridgeArray)
|
||||
{
|
||||
// we need to construct a byte array, true==1, false==0
|
||||
var byteArray = new byte[IsHalfBridgeArray.Length];
|
||||
for (int idx = 0; idx < IsHalfBridgeArray.Length; idx++)
|
||||
{
|
||||
byteArray[idx] = (byte)(IsHalfBridgeArray[idx] ? 1 : 0);
|
||||
}
|
||||
var set = new SetArmAttribute(com);
|
||||
set.SetValue(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.StackChannelBridgeCompletionEnable, byteArray, true);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void ConfigureBridgeResistance(UInt16[] BridgeResistanceArray)
|
||||
{
|
||||
// this function shall just set the bridge resistance for the channels
|
||||
var set = new SetArmAttribute(com);
|
||||
set.SetValue(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.StackChannelBridgeResistanceOhms, BridgeResistanceArray, true);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public float[] GetScaleFactors()
|
||||
{
|
||||
// this function shall just set the range attribute for channel
|
||||
var query = new QueryArmAttribute(com);
|
||||
query.Key = AttributeTypes.ArmAndEventAttributes.StackChannelScaleFactorsMillivoltsPerADC;
|
||||
query.SyncExecute();
|
||||
return query.Value as float[];
|
||||
}
|
||||
|
||||
#region Attributes
|
||||
|
||||
public UInt32 SampleRate
|
||||
{
|
||||
get
|
||||
{
|
||||
UInt32 Value;
|
||||
GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.SampleRate, out Value);
|
||||
return Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.SampleRate, value);
|
||||
}
|
||||
}
|
||||
|
||||
public float AAFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
float Value;
|
||||
GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.AAFilterFrequency, out Value);
|
||||
return Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.AAFilterFrequency, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string TestID
|
||||
{
|
||||
get
|
||||
{
|
||||
string Value;
|
||||
GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.Name, out Value);
|
||||
return Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.Name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string TestDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
string Value;
|
||||
GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.Description, out Value);
|
||||
return Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.Description, value);
|
||||
}
|
||||
}
|
||||
|
||||
public UInt64 PreTriggerSamples
|
||||
{
|
||||
get
|
||||
{
|
||||
UInt64 Value;
|
||||
GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.PreTriggerSamplesRequested, out Value);
|
||||
return Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.PreTriggerSamplesRequested, value);
|
||||
}
|
||||
}
|
||||
|
||||
public ulong PostTriggerSamples
|
||||
{
|
||||
get
|
||||
{
|
||||
UInt64 Value;
|
||||
GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.PostTriggerSamplesRequested, out Value);
|
||||
return Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.PostTriggerSamplesRequested, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Test.Module.RecordingMode TestType
|
||||
{
|
||||
get
|
||||
{
|
||||
Test.Module.RecordingMode Value;
|
||||
GetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.ArmMode, out Value);
|
||||
return Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetArmAttribute(DTS.DASLib.Command.SLICE.AttributeTypes.ArmAndEventAttributes.ArmMode, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper functions
|
||||
|
||||
public uint CalculateNumberOfModules(ConfigurationData config, uint numChannels)
|
||||
{
|
||||
// this is a shortcut for now
|
||||
return numChannels / 3;
|
||||
}
|
||||
|
||||
public UInt64 GetEventTotalSamples(int eventNum)
|
||||
{
|
||||
ulong samples = 0L;
|
||||
var eventSamples = new QueryEventAttribute(com);
|
||||
eventSamples.EventNumber = (ushort)eventNum;
|
||||
eventSamples.Key = AttributeTypes.ArmAndEventAttributes.TotalSamplesRecorded;
|
||||
try
|
||||
{
|
||||
eventSamples.SyncExecute();
|
||||
samples = (ulong)eventSamples.Value;
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
try
|
||||
{ //
|
||||
// Try to get enough info to proceed with a rump download.
|
||||
//
|
||||
var preSamplesRequested = new QueryEventAttribute(com);
|
||||
preSamplesRequested.EventNumber = (ushort)eventNum;
|
||||
preSamplesRequested.Key = AttributeTypes.ArmAndEventAttributes.PreTriggerSamplesRequested;
|
||||
preSamplesRequested.SyncExecute();
|
||||
|
||||
var postSamplesRequested = new QueryEventAttribute(com);
|
||||
postSamplesRequested.EventNumber = (ushort)eventNum;
|
||||
postSamplesRequested.Key = AttributeTypes.ArmAndEventAttributes.PostTriggerSamplesRequested;
|
||||
postSamplesRequested.SyncExecute();
|
||||
|
||||
samples = (ulong)preSamplesRequested.Value + (ulong)postSamplesRequested.Value + 1L;
|
||||
|
||||
var totalSamplesRecorded = new SetEventAttribute(com);
|
||||
totalSamplesRecorded.EventNumber = (ushort)eventNum;
|
||||
totalSamplesRecorded.SetValue(AttributeTypes.ArmAndEventAttributes.TotalSamplesRecorded, samples, true);
|
||||
totalSamplesRecorded.SyncExecute();
|
||||
}
|
||||
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw new System.ApplicationException("encountered problem re-querying pre/post samples after initial total sample request failure", ex);
|
||||
}
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
public UInt64 GetEventTriggerSampleNumber(int eventNum)
|
||||
{
|
||||
var eventTSN = new QueryEventAttribute(com);
|
||||
eventTSN.EventNumber = (ushort)eventNum;
|
||||
eventTSN.Key = AttributeTypes.ArmAndEventAttributes.TriggerSampleNumber;
|
||||
try { eventTSN.SyncExecute(); }
|
||||
catch (System.Exception) { return (ulong)0; }
|
||||
return (ulong)eventTSN.Value;
|
||||
}
|
||||
|
||||
public void SetEventTriggerSampleNumber(int eventNum, UInt64 sampleNumber)
|
||||
{
|
||||
var eventTSN = new SetEventAttribute(com);
|
||||
eventTSN.EventNumber = (ushort)eventNum;
|
||||
eventTSN.SetValue(AttributeTypes.ArmAndEventAttributes.TriggerSampleNumber, sampleNumber, true);
|
||||
eventTSN.SyncExecute();
|
||||
}
|
||||
|
||||
public UInt64 GetEventStartRecordSampleNumber(int eventNum)
|
||||
{
|
||||
var eventSRSN = new QueryEventAttribute(com);
|
||||
eventSRSN.EventNumber = (ushort)eventNum;
|
||||
eventSRSN.Key = AttributeTypes.ArmAndEventAttributes.StartRecordSampleNumber;
|
||||
try { eventSRSN.SyncExecute(); }
|
||||
catch (System.Exception) { return (ulong)0; }
|
||||
return (ulong)eventSRSN.Value;
|
||||
}
|
||||
|
||||
public uint GetEventSamplerate(int eventNum)
|
||||
{
|
||||
var eventSR = new QueryEventAttribute(com);
|
||||
eventSR.EventNumber = (ushort)eventNum;
|
||||
eventSR.Key = AttributeTypes.ArmAndEventAttributes.SampleRate;
|
||||
eventSR.SyncExecute();
|
||||
return (uint)eventSR.Value;
|
||||
}
|
||||
|
||||
public uint GetEventTotalChannels(int eventNum)
|
||||
{
|
||||
var eventTC = new QueryEventAttribute(com);
|
||||
eventTC.EventNumber = (ushort)eventNum;
|
||||
eventTC.Key = AttributeTypes.ArmAndEventAttributes.TotalChannels;
|
||||
eventTC.SyncExecute();
|
||||
return (uint)(byte)eventTC.Value;
|
||||
}
|
||||
|
||||
public DateTime GetEventStartTime(int eventNum)
|
||||
{
|
||||
var eventST = new QueryEventAttribute(com);
|
||||
eventST.EventNumber = (ushort)eventNum;
|
||||
eventST.Key = AttributeTypes.ArmAndEventAttributes.StartTime;
|
||||
try { eventST.SyncExecute(); }
|
||||
catch (System.Exception) { return new DateTime(0); }
|
||||
DateTime rv = new DateTime(0).AddSeconds((double)((uint)eventST.Value));
|
||||
return rv;
|
||||
}
|
||||
|
||||
public double GetEventAAFilter(int eventNum)
|
||||
{
|
||||
var eventFF = new QueryEventAttribute(com);
|
||||
eventFF.EventNumber = (ushort)eventNum;
|
||||
eventFF.Key = AttributeTypes.ArmAndEventAttributes.AAFilterFrequency;
|
||||
eventFF.SyncExecute();
|
||||
float aafilter = (float)eventFF.Value;
|
||||
return (double)aafilter;
|
||||
}
|
||||
|
||||
public double GetEventExcitation(int eventNum)
|
||||
{
|
||||
var eventExc = new QueryEventAttribute(com);
|
||||
eventExc.EventNumber = (ushort)eventNum;
|
||||
throw new ApplicationException("GetEventExcitation needs to be implemented by channel ...");
|
||||
//return (double)eventExc.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the number of "level triggered" samples required for a level trigger to be declared by the DAS.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="eventNum">
|
||||
/// The <see cref="int"/> event number for which we want level trigger qualification sample information.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// The <see cref="int"/> number of contiguous "level triggered" samples required for a level trigger event.
|
||||
/// </returns>
|
||||
///
|
||||
private int[] GetLevelTriggerQualificationSamples(int eventNum)
|
||||
{
|
||||
try
|
||||
{
|
||||
var eventLevTrigQlfSamps = new QueryEventAttribute(com);
|
||||
eventLevTrigQlfSamps.Key = AttributeTypes.ArmAndEventAttributes.LevelTriggerQualificationSamples;
|
||||
eventLevTrigQlfSamps.SyncExecute();
|
||||
return (int[])(eventLevTrigQlfSamps.Value);
|
||||
}
|
||||
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw new ApplicationException("encountered problem getting number of level trigger qualification samples from hardware for event " + eventNum.ToString(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get determination from hardware whether or not the associated DAS has directly experienced a level trigger event.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="eventNum">
|
||||
/// The <see cref="int"/> event number for which we want level trigger seen information.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// <see cref="bool"/> True if the associated DAS has experienced a level trigger event; False otherwise.
|
||||
/// </returns>
|
||||
///
|
||||
private bool[] GetLevelTriggerSeen(int eventNum)
|
||||
{
|
||||
try
|
||||
{
|
||||
var eventLevTrigSeen = new QueryEventAttribute(com);
|
||||
eventLevTrigSeen.Key = AttributeTypes.ArmAndEventAttributes.LevelTriggerSeen;
|
||||
eventLevTrigSeen.SyncExecute();
|
||||
return (bool[])(eventLevTrigSeen.Value);
|
||||
}
|
||||
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw new ApplicationException("encountered problem getting \"level trigger seen\" condition from hardware for event " + eventNum.ToString(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get number of samples that the associated hardware adjusted its level trigger time value from the time it
|
||||
/// actually issued a trigger fault. This adjustment is necessary because several contiguous level-triggered
|
||||
/// samples are necessary before some flavors of DAS will declare an actual level trigger. Once the hardware has
|
||||
/// determined that a trigger has occured, it must "backdate" the T0 to match the time of the first
|
||||
/// level-triggered sample. This number only exists for hardware that has directly experienced a level trigger
|
||||
/// condition.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="eventNum">
|
||||
/// The <see cref="int"/> number of the event we want the adjustment samples for.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// The number of samples that this DAS' trigger time value has been adjusted to compensate for time required
|
||||
/// by the hardware for level trigger evaluation. If the associated hardware did not directly experience the
|
||||
/// level trigger, this value will be null.
|
||||
/// </returns>
|
||||
///
|
||||
public int?[] GetEventLevelTriggerT0AdjustmentSamples(int eventNum)
|
||||
{
|
||||
try
|
||||
{
|
||||
var eventLevTrigT0AdjSamp = new QueryEventAttribute(com);
|
||||
eventLevTrigT0AdjSamp.EventNumber = (ushort)eventNum;
|
||||
eventLevTrigT0AdjSamp.Key = AttributeTypes.ArmAndEventAttributes.LevelTriggerT0AdjustmentSamples;
|
||||
eventLevTrigT0AdjSamp.SyncExecute();
|
||||
var levelTriggerAdjSamples = (int[])(eventLevTrigT0AdjSamp.Value);
|
||||
|
||||
var levelTriggerSeen = GetLevelTriggerSeen(eventNum);
|
||||
|
||||
var finalAdjustment = new int?[levelTriggerAdjSamples.Length];
|
||||
|
||||
for (int channel = 0; channel < finalAdjustment.Length; channel++)
|
||||
{
|
||||
finalAdjustment[channel] = levelTriggerSeen[channel] ? levelTriggerAdjSamples[channel] : (int?)null;
|
||||
}
|
||||
|
||||
return finalAdjustment;
|
||||
}
|
||||
|
||||
catch (System.Exception)
|
||||
{
|
||||
// CGO
|
||||
// This is a hacked change for now to support 00G8 and prior firmware
|
||||
// in the 1.04 release of SLICEWare. This and the other CGO commented
|
||||
// block of code need more general cleanup before 1.05.
|
||||
return (int?[])null;
|
||||
//throw new ApplicationException( "encountered problem getting event level trigger T0 adjustment samples from hardware for event " + eventNum.ToString( ), ex );
|
||||
}
|
||||
}
|
||||
|
||||
public bool EventHasBeenDownloaded(int eventNum, out uint flag)
|
||||
{
|
||||
try
|
||||
{
|
||||
var eventDLFlag = new QueryEventAttribute(com);
|
||||
eventDLFlag.EventNumber = (ushort)eventNum;
|
||||
eventDLFlag.Key = AttributeTypes.ArmAndEventAttributes.EventHasBeenDownloaded;
|
||||
eventDLFlag.SyncExecute();
|
||||
flag = (uint)eventDLFlag.Value;
|
||||
return true;
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
flag = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEventDownloaded(int eventNum, uint flag)
|
||||
{
|
||||
var eventDLFlag = new SetEventAttribute(com);
|
||||
eventDLFlag.EventNumber = (ushort)eventNum;
|
||||
eventDLFlag.SetValue(AttributeTypes.ArmAndEventAttributes.EventHasBeenDownloaded, flag, true);
|
||||
eventDLFlag.SyncExecute();
|
||||
}
|
||||
|
||||
public string GetEventID(int eventNum)
|
||||
{
|
||||
var eventName = new QueryEventAttribute(com);
|
||||
eventName.EventNumber = (ushort)eventNum;
|
||||
eventName.Key = AttributeTypes.ArmAndEventAttributes.Name;
|
||||
eventName.SyncExecute();
|
||||
var values = eventName.Value as byte[];
|
||||
if (null == values)
|
||||
{
|
||||
return eventName.Value as string;
|
||||
}
|
||||
else
|
||||
{
|
||||
var value = Encoding.UTF8.GetString(values);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public Guid GetEventGuid(int eventNum)
|
||||
{
|
||||
var eventGuid = new QueryEventAttribute(com);
|
||||
eventGuid.EventNumber = (ushort)eventNum;
|
||||
eventGuid.Key = AttributeTypes.ArmAndEventAttributes.EventGuid;
|
||||
eventGuid.SyncExecute();
|
||||
return new Guid(eventGuid.Value as string);
|
||||
}
|
||||
|
||||
public string GetEventDescription(int eventNum)
|
||||
{
|
||||
var eventDescr = new QueryEventAttribute(com);
|
||||
eventDescr.EventNumber = (ushort)eventNum;
|
||||
eventDescr.Key = AttributeTypes.ArmAndEventAttributes.Description;
|
||||
eventDescr.SyncExecute();
|
||||
var values = eventDescr.Value as byte[];
|
||||
if (values == null || values.Length == 0)
|
||||
return eventDescr.Value as string;
|
||||
var value = Encoding.UTF8.GetString(values);
|
||||
return value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
2202
DataPRO/IService/Classes/TDAS Service/Configuration.cs
Normal file
2202
DataPRO/IService/Classes/TDAS Service/Configuration.cs
Normal file
File diff suppressed because it is too large
Load Diff
988
DataPRO/IService/Classes/TDAS Service/Download.cs
Normal file
988
DataPRO/IService/Classes/TDAS Service/Download.cs
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
342
DataPRO/IService/Classes/TDAS Service/Public.cs
Normal file
342
DataPRO/IService/Classes/TDAS Service/Public.cs
Normal file
@@ -0,0 +1,342 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.DASLib.Command;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.SerialConnection;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.DASLib.Service.Classes.Diagnostics;
|
||||
using DTS.Common.Interface.DASFactory.ARM;
|
||||
using DTS.Common.Interface.DASFactory.Download;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using static DTS.Common.Enums.DASFactory.DFConstantsAndEnums;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
|
||||
public partial class TDAS<T> : Communication<T>,
|
||||
IDASCommunication,
|
||||
IConfigurationActions,
|
||||
IDiagnosticsActions,
|
||||
ITriggerCheckActions,
|
||||
IRealTimeActions,
|
||||
IArmActions,
|
||||
IDownloadActions where T : IConnection, new()
|
||||
{
|
||||
public ExcitationStatus ExcitationStatus { get; set; } = ExcitationStatus.Unknown;
|
||||
public HardwareTypes GetHardwareType()
|
||||
{
|
||||
if (SerialNumber.StartsWith("5M"))
|
||||
{
|
||||
switch (G5Mode)
|
||||
{
|
||||
case G5Modes.INDUMMY: return HardwareTypes.G5INDUMMY;
|
||||
case G5Modes.VDS:
|
||||
default:
|
||||
return HardwareTypes.G5VDS;
|
||||
}
|
||||
}
|
||||
else if (SerialNumber.StartsWith("DR")) { return HardwareTypes.TDAS_Pro_Rack; }
|
||||
else if (SerialNumber.StartsWith("SM")) { return HardwareTypes.SIM; }
|
||||
else if (SerialNumber.StartsWith("TOM")) { return HardwareTypes.TOM; }
|
||||
else if (SerialNumber.StartsWith("LR"))
|
||||
{
|
||||
return HardwareTypes.TDAS_LabRack;
|
||||
}
|
||||
else
|
||||
{
|
||||
//invalid serial number, just treat as rack?
|
||||
return HardwareTypes.TDAS_Pro_Rack;
|
||||
}
|
||||
}
|
||||
public bool StartRecord
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
public float InputLowVoltage { get; set; }
|
||||
public float InputMediumVoltage { get; set; }
|
||||
public float InputHighVoltage { get; set; }
|
||||
public float BatteryLowVoltage { get; set; }
|
||||
public float BatteryMediumVoltage { get; set; }
|
||||
public float BatteryHighVoltage { get; set; }
|
||||
public double MinimumValidInputVoltage { get; set; }
|
||||
public double MaximumValidInputVoltage { get; set; }
|
||||
public double MinimumValidBatteryVoltage { get; set; }
|
||||
public double MaximumValidBatteryVoltage { get; set; }
|
||||
public bool CheckAAF(float rate) { return true; }
|
||||
/// <summary>
|
||||
/// phase shift information not known for TDAS modules right now, so assuming 0
|
||||
/// </summary>
|
||||
/// <param name="ModuleIndex"></param>
|
||||
/// <param name="ActualSampleRate"></param>
|
||||
/// <param name="HardwareAAF"></param>
|
||||
/// <returns></returns>
|
||||
public ulong GetPhaseShiftSamples(uint ModuleIndex, double ActualSampleRate, uint HardwareAAF, ulong originalT0) { return 0; }
|
||||
#region Configuration
|
||||
|
||||
// our public configure member
|
||||
|
||||
public IConfigurationData ConfigData { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Diagnostics
|
||||
|
||||
// our public diagnostics member
|
||||
|
||||
public IDiagnosticActions[] ChannelDiagnostics { get; set; }
|
||||
public void SetChannelDiagnosticActions(IDiagnosticActions[] actions, bool setInDb = true)
|
||||
{
|
||||
DiagnosticsActions.SetChannelDiagnosticActions(this, actions, setInDb);
|
||||
}
|
||||
public IDiagnosticResult[] ChannelDiagnosticsResults { get; set; }
|
||||
public void ClearChannelDiagnosticsResults(bool bClearDb = true)
|
||||
{
|
||||
DiagnosticsResultActions.ClearChannelDiagnosticsResults(this, bClearDb);
|
||||
}
|
||||
|
||||
public void SetChannelDiagnosticsResults(IDiagnosticResult[] results, bool setInDb)
|
||||
{
|
||||
DiagnosticsResultActions.SetChannelDiagnosticsResults(this, results, setInDb);
|
||||
}
|
||||
public IBaseInputValues BaseInput { get; set; }
|
||||
public IOptimizationValues OptimizationValues { get; set; }
|
||||
#region Clock Sync
|
||||
public IDictionary<InputClockSource, bool> DASClockSyncStatus { get; set; } = null;
|
||||
public bool ClockSyncInUTC { get; set; } = false;
|
||||
|
||||
public ClockSyncProfile DASClockSyncProfile { get; set; }
|
||||
public byte PTPDomainID { get; set; }
|
||||
#endregion
|
||||
public IArmCheckActions ArmCheckActions { get; set; }
|
||||
public IArmCheckResults ArmCheckResults { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Trigger check
|
||||
|
||||
// our public trigger check member
|
||||
|
||||
public ITriggerCheckResult TriggerResult { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Real time
|
||||
|
||||
// our public real time member
|
||||
|
||||
public List<int> RealtimeDASChannels { get; set; }
|
||||
public List<double> TiltAxisData { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region FlashErase
|
||||
|
||||
public FlashEraseStatus DASFlashEraseStatus { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Arming
|
||||
public bool GetIsInArm()
|
||||
{
|
||||
if (null == DASArmStatus) { return false; }
|
||||
return DASArmStatus.IsArmed;
|
||||
}
|
||||
public bool GetIsInRealtime()
|
||||
{
|
||||
if (null == DASArmStatus) { return false; }
|
||||
return DASArmStatus.IsInRealtime;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns true if the unit is known to be streaming
|
||||
/// does not query the hardware, just returns a flag if it has been set
|
||||
/// </summary>
|
||||
/// <returns>true if known to be streaming, false otherwise</returns>
|
||||
public bool GetIsStreaming()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public void SetInArm(bool WriteToDb)
|
||||
{
|
||||
if (null == DASArmStatus)
|
||||
{
|
||||
var armStatus = new ArmStatus()
|
||||
{
|
||||
IsArmed = true
|
||||
};
|
||||
ArmStatus.SetArmStatus(this, armStatus, WriteToDb);
|
||||
}
|
||||
else
|
||||
{
|
||||
DASArmStatus.IsArmed = true;
|
||||
if (WriteToDb)
|
||||
{
|
||||
SetDASArmStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetInRealtime(bool WriteToDb, bool ExitRealtimeIfPossible)
|
||||
{
|
||||
if (null == DASArmStatus)
|
||||
{
|
||||
var armStatus = new ArmStatus()
|
||||
{
|
||||
IsInRealtime = true
|
||||
};
|
||||
ArmStatus.SetArmStatus(this, armStatus, WriteToDb);
|
||||
}
|
||||
else
|
||||
{
|
||||
DASArmStatus.IsInRealtime = true;
|
||||
if (WriteToDb)
|
||||
{
|
||||
SetDASArmStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
public IArmStatusData DASArmStatus { get; set; }
|
||||
public void SetDASArmStatus(IArmStatusData status, bool bSetInDb)
|
||||
{
|
||||
ArmStatus.SetArmStatus(this, status, bSetInDb);
|
||||
}
|
||||
public void SetDASArmStatus()
|
||||
{
|
||||
ArmStatus.SetArmStatus(this, DASArmStatus, true);
|
||||
}
|
||||
private DFConstantsAndEnums.CommandStatus _autoArmStatus = DFConstantsAndEnums.CommandStatus.StatusNoError;
|
||||
public DFConstantsAndEnums.CommandStatus AutoArmStatus
|
||||
{
|
||||
get { return _autoArmStatus; }
|
||||
set { _autoArmStatus = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Downloading
|
||||
|
||||
public IDownloadRequest WhatToDownload { get; set; }
|
||||
public void SetWhatToDownload(IDownloadRequest request, bool bSetInDb = true)
|
||||
{
|
||||
DownloadRequest.SetWhatToDownload(this, request, bSetInDb);
|
||||
}
|
||||
public IDownloadReport EventInfo { get; set; }
|
||||
public void SetEventInfo(IDownloadReport eventInfo, bool bSetInDb = true)
|
||||
{
|
||||
DownloadReport.SetEventInfo(this, eventInfo, bSetInDb);
|
||||
}
|
||||
public bool[] EventDownloadedStatus { get; set; }
|
||||
public void SetEventDownloadStatus(bool[] status, bool storeInDb = true)
|
||||
{
|
||||
DownloadReport.SetEventDownloadStatus(this, status, storeInDb);
|
||||
}
|
||||
public Guid[] EventGuids { get; set; }
|
||||
public void SetEventGuids(Guid[] guids, bool storeInDb = true)
|
||||
{
|
||||
DownloadReport.SetEventGuids(this, guids, storeInDb);
|
||||
}
|
||||
uint[] IDownload.ExtendedFaultFlags1 { get; set; }
|
||||
uint[] IDownload.ExtendedFaultFlags2 { get; set; }
|
||||
uint[] IDownload.ExtendedFaultFlags3 { get; set; }
|
||||
uint[] IDownload.ExtendedFaultFlags4 { get; set; }
|
||||
void IDownload.SetExtendedFaultFlags(uint[][] flags)
|
||||
{
|
||||
DownloadExtendedFaultFunctions.SetExtendedFaultFlags(flags, this);
|
||||
}
|
||||
public ushort[] FaultFlags { get; set; }
|
||||
public void SetEventFaultFlags(ushort[] flags, bool storeInDb = true)
|
||||
{
|
||||
DownloadReport.SetEventFaultFlags(this, flags, storeInDb);
|
||||
}
|
||||
public byte[] ArmAttempts { get; set; }
|
||||
public void SetEventArmAttemps(byte[] armAttempts, bool storeInDb = true)
|
||||
{
|
||||
DownloadReport.SetEventArmAttempts(this, armAttempts, storeInDb);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Information
|
||||
|
||||
/// <summary>
|
||||
/// note, this property hides a property inherited from ICommunication, but that
|
||||
/// one is declared with a different type (Communication_DASInfo), so I'm assuming this
|
||||
/// was intended to hide that property
|
||||
/// 6/29/2010 - dtm
|
||||
/// </summary>
|
||||
|
||||
public new IInfoResult DASInfo { get; set; }
|
||||
public void SetDASInfo(IInfoResult dasInfo, bool bSetInDb = true)
|
||||
{
|
||||
InfoResult.SetDASInfo(this, dasInfo, bSetInDb);
|
||||
}
|
||||
public void SetDASInfo() { InfoResult.SetDASInfo(this); }
|
||||
#endregion
|
||||
|
||||
#region Firmware Utility
|
||||
|
||||
#endregion
|
||||
|
||||
//I'm guessing hiding was not intended, this member hides an inherited member (from ICommunication)
|
||||
//public string SerialNumber { get; set; }
|
||||
public override string ToString()
|
||||
{
|
||||
var sn = SerialNumber;
|
||||
if (!string.IsNullOrEmpty(sn))
|
||||
return sn;
|
||||
return "Unknown DAS";
|
||||
}
|
||||
|
||||
public int NumberOfConfiguredChannels()
|
||||
{
|
||||
if (null == ConfigData) { return 0; }
|
||||
return ConfigData.NumberOfConfiguredChannels();
|
||||
}
|
||||
|
||||
|
||||
public int NumberOfChannels()
|
||||
{
|
||||
if (null == ConfigData) { return 0; }
|
||||
return ConfigData.NumberOfChannels();
|
||||
}
|
||||
|
||||
|
||||
public int CompareTo(IDASCommunication das)
|
||||
{
|
||||
if (das == null || string.IsNullOrEmpty(das.SerialNumber) || string.IsNullOrEmpty(SerialNumber))
|
||||
return 0;
|
||||
return SerialNumber.CompareTo(das.SerialNumber);
|
||||
}
|
||||
|
||||
public bool DiagnosticsHasBeenRun { get; set; }
|
||||
private bool _configureHasBeenRun = false;
|
||||
public bool ConfigureHasBeenRun
|
||||
{
|
||||
get { return _configureHasBeenRun; }
|
||||
set { _configureHasBeenRun = value; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#region Sub classes used for identification
|
||||
|
||||
public class EthernetTDAS : TDAS<EthernetConnection>
|
||||
{
|
||||
|
||||
public EthernetTDAS()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class SerialTDAS : TDAS<SerialConnection>
|
||||
{
|
||||
public SerialTDAS()
|
||||
{
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
674
DataPRO/IService/Classes/TDAS Service/Realtime.cs
Normal file
674
DataPRO/IService/Classes/TDAS Service/Realtime.cs
Normal file
@@ -0,0 +1,674 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.TDAS;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public partial class TDAS<T> : Communication<T>,
|
||||
IDASCommunication,
|
||||
IConfigurationActions,
|
||||
IDiagnosticsActions,
|
||||
ITriggerCheckActions,
|
||||
IRealTimeActions,
|
||||
IArmActions,
|
||||
IDownloadActions where T : IConnection, new()
|
||||
{
|
||||
#region Real time
|
||||
public bool ControlsDAQ() { return false; }
|
||||
public bool SupportsHardwareInputCheck() { return false; }
|
||||
public bool InvertStart
|
||||
{
|
||||
get { return false; }
|
||||
set { if (value) { throw new NotSupportedException("TDAS does not support inverted start"); } }
|
||||
}
|
||||
public bool InvertTrigger
|
||||
{
|
||||
get { return false; }
|
||||
set { if (value) { throw new NotSupportedException("TDAS does not support inverted trigger"); } }
|
||||
}
|
||||
public bool SupportsTriggerInversion() => HardwareConstants.SupportsTriggerInversion(GetHardwareType(), ProtocolVersion);
|
||||
public bool SupportsStartInversion() => HardwareConstants.SupportsStartInversion(GetHardwareType(), ProtocolVersion);
|
||||
public bool SupportsRealtime()
|
||||
{
|
||||
if (DFConstantsAndEnums.ModuleType.G5Analog == DASInfo.Modules[0].TypeOfModule)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var module in DASInfo.Modules)
|
||||
{
|
||||
switch (module.TypeOfModule)
|
||||
{
|
||||
case DFConstantsAndEnums.ModuleType.ProDIM:
|
||||
case DFConstantsAndEnums.ModuleType.ProSIM:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public bool IgnoreShortedStart
|
||||
{
|
||||
get { return false; }
|
||||
set { if (value) { throw new NotSupportedException("TDAS does not support ignore shorted start"); } }
|
||||
}
|
||||
public bool IgnoreShortedTrigger
|
||||
{
|
||||
get { return false; }
|
||||
set { if (value) { throw new NotSupportedException("TDAS does not support ignore shorted trigger"); } }
|
||||
}
|
||||
public bool SupportsAutoArm() { return false; }
|
||||
public bool SupportsLevelTrigger() { return false; }
|
||||
public bool SupportsMultipleEvents() { return false; }
|
||||
public bool SupportsMultipleSampleRealtime() { return false; }
|
||||
public bool SupportsMultiChannelRealtime() { return false; }
|
||||
|
||||
private class RealTimeAsyncPacket
|
||||
{
|
||||
public TDASServiceAsyncInfo info { get; set; }
|
||||
public System.Threading.Timer timer { get; set; }
|
||||
public int samplesPerSecond { get; set; }
|
||||
public int millisecBetweenSamples { get; set; }
|
||||
public bool realtimeMultipleSamplesEnabled { get; set; }
|
||||
public int ModuleIndex { get; set; }
|
||||
public System.Threading.ManualResetEvent StopEvent { get; set; }
|
||||
public bool CareAboutSampleNumber { get; set; }
|
||||
public int minCallbackUpdateTimeMs { get; set; }
|
||||
}
|
||||
|
||||
void IRealTimeActions.RealTimePolling(ServiceCallback callback,
|
||||
object userData,
|
||||
ManualResetEvent mre,
|
||||
byte[] channels)
|
||||
{
|
||||
var packet = new RealTimeAsyncPacket();
|
||||
packet.info = new TDASServiceAsyncInfo(callback, userData);
|
||||
packet.StopEvent = mre;
|
||||
if (IsG5())
|
||||
{
|
||||
packet.millisecBetweenSamples = 50;
|
||||
packet.samplesPerSecond = 1000;
|
||||
packet.CareAboutSampleNumber = false;
|
||||
LaunchAsyncWorker("TDAS.Realtime", new WaitCallback(AsyncRealTime), packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
LaunchAsyncWorker("TDAS.RealtimePolling", new WaitCallback(AsyncRealTimePolling), packet);
|
||||
}
|
||||
}
|
||||
|
||||
void IRealTimeActions.RealTime(int samplesPerSecond,
|
||||
int millisecBetweenSamples,
|
||||
ServiceCallback callback,
|
||||
object userData,
|
||||
bool realtimeMultipleSamplesEnabled,
|
||||
int moduleIndex,
|
||||
ManualResetEvent stopEvent,
|
||||
byte[] channels,
|
||||
double aaf,
|
||||
int minCallbackUpdateTimeMs,
|
||||
bool UseUDPStreaming,
|
||||
string hostIPAddress)
|
||||
{
|
||||
|
||||
var packet = new RealTimeAsyncPacket
|
||||
{
|
||||
info = new TDASServiceAsyncInfo(callback, userData),
|
||||
millisecBetweenSamples = millisecBetweenSamples,
|
||||
samplesPerSecond = samplesPerSecond,
|
||||
realtimeMultipleSamplesEnabled = realtimeMultipleSamplesEnabled,
|
||||
ModuleIndex = moduleIndex,
|
||||
CareAboutSampleNumber = true,
|
||||
StopEvent = stopEvent,
|
||||
minCallbackUpdateTimeMs = minCallbackUpdateTimeMs
|
||||
};
|
||||
LaunchAsyncWorker("TDAS.RealTime", new WaitCallback(AsyncRealTime), packet);
|
||||
}
|
||||
|
||||
void IRealTimeActions.RealTimeTiltPolling(ServiceCallback callback, object userData, ManualResetEvent stopEvent)
|
||||
{
|
||||
var info = new TDASServiceAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
|
||||
public string UDPStreamAddress { get; }
|
||||
void IRealTimeActions.SetUDPStreamProfile(ServiceCallback callback, object userData, UDPStreamProfile streamProfile, string udpAddress, ushort timeChannelId, ushort dataChannelId, uint[] tmnsConfig, ushort irigTimeDataPacketIntervalMs)
|
||||
{
|
||||
var info = new TDASServiceAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
void IRealTimeActions.GetUDPStreamProfile(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TDASServiceAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
|
||||
private object CallbackLock = new object();
|
||||
private DateTime lastUpdate = DateTime.MinValue;
|
||||
private const int MIN_CALLBACK_UPDATE_TIME = 10;
|
||||
private List<UInt64> _timeStamps = new List<ulong>();
|
||||
private List<UInt64> _sequenceNumbers = new List<ulong>();
|
||||
private List<UInt64> _sampleNumbers = new List<ulong>();
|
||||
private List<short[][]> _dataSamples = new List<short[][]>();
|
||||
|
||||
private const int BufferSize = 4096;
|
||||
private readonly byte[] _buffer = new byte[BufferSize];
|
||||
private RealTimeAsyncPacket _packet;
|
||||
private const int NumChannels = 8;
|
||||
private const int StartChannel = 0;
|
||||
|
||||
private void ProcessData(IAsyncResult ar)
|
||||
{
|
||||
lock (CallbackLock)
|
||||
{
|
||||
var bytes = sock.EndReceive(ar);
|
||||
if (0 == bytes) { return; }
|
||||
var s = Encoding.ASCII.GetString(_buffer, 0, bytes);
|
||||
s = s.Replace("\r\n", Convert.ToChar(0xBF).ToString());
|
||||
var lines = s.Split(Convert.ToChar(0xBF));
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var rtData = new short[NumChannels][];
|
||||
if (!line.Contains("MD")) { continue; }
|
||||
var tokens = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (tokens.Length < 8) { continue; }
|
||||
//0 = command, 1 = time, 2 = channel 0, etc
|
||||
for (var i = 0; i < NumChannels; i++)
|
||||
{
|
||||
rtData[i] = new short[1];
|
||||
rtData[i][0] = short.MaxValue;
|
||||
if (i >= StartChannel)
|
||||
{
|
||||
var index = i - StartChannel + 2;
|
||||
if (index < tokens.Length)
|
||||
{
|
||||
short.TryParse(tokens[i - StartChannel + 2], out rtData[i][0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
_dataSamples.Add(rtData);
|
||||
}
|
||||
//TDAS reporting interval is slow enough, don't restrict it further!
|
||||
//if (DateTime.Now.Subtract(lastUpdate).TotalMilliseconds > MIN_CALLBACK_UPDATE_TIME)
|
||||
{
|
||||
_packet.info.NewData(_dataSamples, _sampleNumbers, _timeStamps, _sequenceNumbers);
|
||||
|
||||
_dataSamples.Clear();
|
||||
//lastUpdate = DateTime.Now;
|
||||
}
|
||||
}
|
||||
sock.BeginReceive(_buffer, 0, BufferSize, new AsyncCallback(ProcessData), null);
|
||||
}
|
||||
/// <summary>
|
||||
/// only used with RACK,
|
||||
/// is a polling (sampleaverage/single sample) realtime mode
|
||||
/// </summary>
|
||||
/// <param name="asyncInfo"></param>
|
||||
private void AsyncRealTimePolling(object asyncInfo)
|
||||
{
|
||||
var packet = asyncInfo as RealTimeAsyncPacket;
|
||||
|
||||
//List<ulong> sampleNumbers = new List<ulong>();
|
||||
//List<short[][]> data = new List<short[][]>();
|
||||
const int numTDASDIMChannels = 16;
|
||||
|
||||
ulong sampleNumber = 0;
|
||||
var numChannels = ConfigData.Modules.Sum(module => module.NumberOfChannels());
|
||||
|
||||
while (!(this as DTS.Common.Interface.DASFactory.ICommunication).IsCanceled() && !packet.StopEvent.WaitOne(0))
|
||||
{
|
||||
var curChannel = 0;
|
||||
//first array is channels, second array are samples
|
||||
var rtData = new short[numChannels][];
|
||||
|
||||
foreach (var module in DASInfo.Modules)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (module.TypeOfModule)
|
||||
{
|
||||
case DFConstantsAndEnums.ModuleType.EMPTYBANK:
|
||||
continue;
|
||||
case DFConstantsAndEnums.ModuleType.ProTOM:
|
||||
{
|
||||
curChannel += 16; //8squibs, 8 digitals
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var ss = new SampleAverage(this)
|
||||
{
|
||||
ModuleIndex = module.ModuleArrayIndex
|
||||
};
|
||||
ss.SyncExecute();
|
||||
if (module.TypeOfModule == DFConstantsAndEnums.ModuleType.ProDIM)
|
||||
{
|
||||
//apparently the DIM for SA just returns 1.0, 0
|
||||
for (int ch = 0; ch < numTDASDIMChannels; ch++)
|
||||
{
|
||||
rtData[curChannel++] = new short[]
|
||||
{
|
||||
0 == ss.ChannelValues[ch] ? short.MinValue : short.MaxValue
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ch = 0; ch < 8; ch++)
|
||||
{
|
||||
rtData[curChannel++] = new short[] { Convert.ToInt16(ss.ChannelValues[ch]) };
|
||||
}
|
||||
}
|
||||
|
||||
//if (IsG5() && i == 0)
|
||||
//{
|
||||
// int digitalbits = (ss.ChannelValues[9] << 16) | ss.ChannelValues[8];
|
||||
// BitVector32 bv = new BitVector32(digitalbits);
|
||||
// for (int digCh = 0; digCh < 16; digCh++)
|
||||
// {
|
||||
// if (bv[(1 << digCh)])
|
||||
// {
|
||||
// rtData[32 + digCh] = new short[] {short.MinValue};
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// rtData[32 + digCh] = new short[] {short.MaxValue};
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
packet.info.NewData(new List<short[][]>() { rtData }, new List<ulong>(new ulong[] { sampleNumber }), new List<ulong>(new ulong[] { ulong.MinValue }), new List<ulong>(new ulong[] { ulong.MinValue }));
|
||||
Thread.Sleep(50);
|
||||
sampleNumber++;
|
||||
//if (DateTime.Now.Subtract(lastUpdate).TotalMilliseconds >= MIN_CALLBACK_UPDATE_TIME)
|
||||
//{
|
||||
// lastUpdate = DateTime.Now;
|
||||
// packet.info.NewData(data, sampleNumbers);
|
||||
// sampleNumbers.Clear();
|
||||
// data.Clear();
|
||||
//}
|
||||
}
|
||||
packet.info.Success();
|
||||
}
|
||||
/// <summary>
|
||||
/// indicates whether the DAS supports streaming
|
||||
/// 10572 implement SW side for single command streaming realtime
|
||||
/// </summary>
|
||||
public bool SupportsIndividualChannelRealtimeStreaming => false;
|
||||
|
||||
/// <summary>
|
||||
/// this is used to space out the samples in a multiple sample packet of g5 realtime
|
||||
/// I based it on the max SPS, which is what we always send to the g5 (1k SPS)
|
||||
/// through empirical testing with the sig-gen, I changed to 1/978 for U5
|
||||
/// </summary>
|
||||
private const double _g5RealtimeInterval = 1 / 978D;
|
||||
//private DateTime _lastRTLogTime = DateTime.MinValue;
|
||||
//private int _samplesProcessed = 0;
|
||||
/// <summary>
|
||||
/// The worker for realtime service.
|
||||
/// </summary>
|
||||
/// <param name="asyncInfo">A RealTimeAsyncPacket for responses</param>
|
||||
private void AsyncRealTime(object asyncInfo)
|
||||
{
|
||||
var packet = asyncInfo as RealTimeAsyncPacket;
|
||||
_packet = packet;
|
||||
|
||||
//tdas devices for realtime have both a sampling rate and a reporting rate
|
||||
//ultimately the reporting rate will drive what we see in realtime
|
||||
//the user has requested a specific realtime rate, however right now
|
||||
//we just force the rate on TDAS equipment, this means we have to go and
|
||||
//adjust our sample numbers as if we were running at the requested rate.
|
||||
double expectedSampleRate = packet.samplesPerSecond;
|
||||
bool bG5 = IsG5();
|
||||
try
|
||||
{
|
||||
if (!SupportsRealtime()) { packet.info.Success(); return; }
|
||||
|
||||
FlushTimeoutMilliSec = 0;
|
||||
var sampleNumbers = new List<ulong>();
|
||||
var timeStamps = new List<ulong>();
|
||||
var sequenceNumbers = new List<ulong>();
|
||||
var data = new List<short[][]>();
|
||||
var dtSTart = DateTime.Now;
|
||||
var sampleNumberCarryover = 0;
|
||||
|
||||
if (bG5)
|
||||
{
|
||||
var mdx = new G5MonitorData(this);
|
||||
mdx.SyncExecute();
|
||||
}
|
||||
else
|
||||
{
|
||||
Command.TDAS.ProMonitorData md = new Command.TDAS.ProMonitorData(this, DASInfo.Modules[packet.ModuleIndex].TypeOfModule == DFConstantsAndEnums.ModuleType.ProSIM);
|
||||
md.ModuleIndex = packet.ModuleIndex;
|
||||
md.SyncExecute();
|
||||
}
|
||||
|
||||
|
||||
// Then consume the constant responses. Be sure to turn off logging for performance.
|
||||
Command.TDAS.MonitorDataNextSampleBase.MonitorType mt;
|
||||
if (IsG5())
|
||||
{
|
||||
mt = Command.TDAS.MonitorDataNextSampleBase.MonitorType.G5;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DASInfo.Modules[packet.ModuleIndex].TypeOfModule == DFConstantsAndEnums.ModuleType.ProDIM)
|
||||
{
|
||||
mt = MonitorDataNextSampleBase.MonitorType.DIM;
|
||||
}
|
||||
else
|
||||
{
|
||||
mt = MonitorDataNextSampleBase.MonitorType.Pro;
|
||||
}
|
||||
}
|
||||
|
||||
Command.TDAS.MonitorDataNextSampleBase next = new Command.TDAS.MonitorDataNextSampleBase(this, mt);
|
||||
|
||||
next.LogCommands = false;
|
||||
while (true && !(this as DTS.Common.Interface.DASFactory.ICommunication).IsCanceled() && !packet.StopEvent.WaitOne(1))
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
sampleNumbers.Clear();
|
||||
timeStamps.Clear();
|
||||
data.Clear();
|
||||
|
||||
// get the next response(s)
|
||||
next.SyncExecute();
|
||||
|
||||
var moreData = next.RTData;
|
||||
var timeSamples = next.Times;
|
||||
// Maybe we're ahead of the das.
|
||||
if (0 == moreData.Count())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bG5)
|
||||
{
|
||||
for (int currentSample = 0; currentSample < moreData.Count; currentSample++)
|
||||
{
|
||||
short digitalBits = moreData[currentSample][32];
|
||||
short[] newData = new short[48];
|
||||
Array.Copy(moreData[currentSample], newData, 32);
|
||||
|
||||
System.Collections.Specialized.BitVector32 bv = new System.Collections.Specialized.BitVector32(Convert.ToInt32(digitalBits));
|
||||
|
||||
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] = short.MinValue; }
|
||||
else { newData[32 + iChannelIdx] = short.MaxValue; }
|
||||
}
|
||||
moreData[currentSample] = newData;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//the service is expecting a DAS full of realtime sample data,
|
||||
//however with realtime on a rack, we're only going to have one module responding with data, so we need to fake data from the other modules
|
||||
//for now since the first SIM module is the only module we're accepting data from I can spoof data from all other channels
|
||||
bool bFound = false;
|
||||
List<List<short>> largerDataArray = new List<List<short>>();
|
||||
|
||||
for (int sample = 0; sample < moreData.Count; sample++)
|
||||
{
|
||||
bFound = false;
|
||||
for (int iModule = 0; iModule < DASInfo.Modules.Length; iModule++)
|
||||
{
|
||||
if (largerDataArray.Count <= sample) { largerDataArray.Add(new List<short>()); }
|
||||
switch (DASInfo.Modules[iModule].TypeOfModule)
|
||||
{
|
||||
case DFConstantsAndEnums.ModuleType.EMPTYBANK://ignore
|
||||
break;
|
||||
case DFConstantsAndEnums.ModuleType.ProDIM:
|
||||
if (!bFound && iModule == packet.ModuleIndex)
|
||||
{
|
||||
bFound = true;
|
||||
foreach (var d in moreData[sample])
|
||||
{
|
||||
System.Collections.Specialized.BitVector32 bv = new System.Collections.Specialized.BitVector32(d);
|
||||
short[] array = new short[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (bv[1 << i])
|
||||
{
|
||||
if (!IsG5())
|
||||
{
|
||||
array[i] = short.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
array[i] = short.MaxValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsG5())
|
||||
{
|
||||
array[i] = short.MinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
array[i] = short.MinValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
largerDataArray[sample].AddRange(array);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
largerDataArray[sample].AddRange(new short[]
|
||||
{
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue
|
||||
});
|
||||
}
|
||||
break;
|
||||
case DFConstantsAndEnums.ModuleType.ProSIM:
|
||||
if (!bFound && iModule == packet.ModuleIndex)
|
||||
{
|
||||
bFound = true;
|
||||
largerDataArray[sample].AddRange(moreData[sample]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//add 8 channels of short.minvalue
|
||||
largerDataArray[sample].AddRange(new short[]
|
||||
{
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue,
|
||||
short.MinValue
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (int i = 0; i < DASInfo.Modules[iModule].NumberOfChannels; i++)
|
||||
{
|
||||
largerDataArray[sample].Add(short.MinValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
moreData = new List<short[]>(largerDataArray.Count);
|
||||
for (int sample = 0; sample < largerDataArray.Count; sample++)
|
||||
{
|
||||
moreData.Add(largerDataArray[sample].ToArray());
|
||||
}
|
||||
|
||||
}
|
||||
// Need to transpose the data to comply with the service interface.
|
||||
int maxSample = moreData.Count();
|
||||
if (!packet.CareAboutSampleNumber)
|
||||
{
|
||||
maxSample = 1;//just do one sample back, we are in meter table mode and don't need the update speed...
|
||||
}
|
||||
for (int currentSample = 0; currentSample < maxSample; currentSample++)
|
||||
{
|
||||
short[][] transposedData = new short[moreData[0].Count()][];
|
||||
for (int currentChannel = 0; currentChannel < transposedData.Length; currentChannel++)
|
||||
{
|
||||
transposedData[currentChannel] = new short[1];
|
||||
transposedData[currentChannel][0] = moreData[currentSample][currentChannel];
|
||||
}
|
||||
data.Add(transposedData.ToArray());
|
||||
if (packet.CareAboutSampleNumber)
|
||||
{
|
||||
if (IsG5())
|
||||
{
|
||||
//compute sample numbers by starting at 0 and then just incrementing
|
||||
//finally, convert from that number to what the requested rate is. ideally the request rate is faster to prevent sample
|
||||
//number overlap, but it's more important the time scale is correct
|
||||
//this should just cause aliasing if the sample numbers overlap
|
||||
sampleNumbers.Add(
|
||||
Convert.ToUInt64(Convert.ToDouble(sampleNumberCarryover * _g5RealtimeInterval) *
|
||||
expectedSampleRate));
|
||||
timeStamps.Add(ulong.MinValue);
|
||||
if (sampleNumberCarryover == Int32.MaxValue)
|
||||
{
|
||||
sampleNumberCarryover = 0;
|
||||
}
|
||||
sampleNumberCarryover++;
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleNumbers.Add(Convert.ToUInt64(timeSamples[currentSample] * expectedSampleRate));
|
||||
timeStamps.Add(ulong.MinValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sampleNumberCarryover == Int32.MaxValue)
|
||||
{
|
||||
sampleNumberCarryover = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleNumberCarryover++;
|
||||
}
|
||||
sampleNumbers.Add(Convert.ToUInt64(sampleNumberCarryover));
|
||||
timeStamps.Add(ulong.MinValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Send the data to the caller.
|
||||
packet.info.NewData(data, sampleNumbers, timeStamps, sequenceNumbers);
|
||||
}
|
||||
if ((this as DTS.Common.Interface.DASFactory.ICommunication).IsCanceled())
|
||||
{
|
||||
packet.info.Cancel();
|
||||
}
|
||||
StopRealtime();
|
||||
packet.info.Success();
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
// We land here when the user cancels real time.
|
||||
packet.info.Cancel();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
packet.info.Error(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this service to terminate real time streaming.
|
||||
/// </summary>
|
||||
/// <param name="callback">User provided callback</param>
|
||||
/// <param name="userData">User provided data object</param>
|
||||
void IRealTimeActions.ExitRealTimeMode(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TDASServiceAsyncInfo(callback, userData);
|
||||
|
||||
LaunchAsyncWorker("TDAS.ExitRealTimeMode", new WaitCallback(AsyncExitRealTimeMode), info);
|
||||
}
|
||||
|
||||
private void StopRealtime()
|
||||
{
|
||||
if (!SupportsRealtime()) { return; }
|
||||
else
|
||||
{
|
||||
|
||||
if (IsG5())
|
||||
{
|
||||
QuitG5Monitoring qm = new QuitG5Monitoring(this);
|
||||
qm.SyncExecute();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
QuerySerialNumber qs = new QuerySerialNumber(this, 2000);
|
||||
qs.SyncExecute();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void AsyncExitRealTimeMode(object asyncInfo)
|
||||
{
|
||||
var info = asyncInfo as TDASServiceAsyncInfo;
|
||||
|
||||
try
|
||||
{
|
||||
StopRealtime();
|
||||
if (null != DASArmStatus) DASArmStatus.IsInRealtime = false;// FB15550: Update IsInRealtime flag if we exit RT so DataPRO is aware
|
||||
info.Success();
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
info.Cancel();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
info.Error(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
272
DataPRO/IService/Classes/TDAS Service/TDAS Service.cs
Normal file
272
DataPRO/IService/Classes/TDAS Service/TDAS Service.cs
Normal file
@@ -0,0 +1,272 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
//using DTS.DASLib.Command.SLICE;
|
||||
using DTS.Common.DASResource;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Classes.Connection;
|
||||
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()
|
||||
{
|
||||
public bool IsEthernetDistributor() { return false; }
|
||||
public bool IsSlice6Distributor() { return false; }
|
||||
public bool IsBattery() { return false; }
|
||||
public bool IsTSRAIR() { return false; }
|
||||
public bool IsSlice6Air() { return false; }
|
||||
public bool IsSlice6AirTc() { return false; }
|
||||
public bool IsScheduleEventCountSupported() { return false; }
|
||||
public class TDASDownloadServiceAsyncInfo
|
||||
{
|
||||
public TDASServiceAsyncInfo info { get; set; }
|
||||
public TDASServiceSetupInfo setupInfo { get; set; }
|
||||
|
||||
public TDASDownloadServiceAsyncInfo(TDASServiceAsyncInfo _info, object _setupInfo)
|
||||
{
|
||||
info = _info;
|
||||
if (_setupInfo != null)
|
||||
{
|
||||
setupInfo = _setupInfo as TDASServiceSetupInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TDASServiceQueryConfigAsyncInfo : TDASServiceAsyncInfo
|
||||
{
|
||||
public bool ReadIds { get; set; } = true;
|
||||
|
||||
public TDASServiceQueryConfigAsyncInfo(bool bReadIds, ServiceCallback callback, object userData)
|
||||
: base(callback, userData)
|
||||
{
|
||||
ReadIds = bReadIds;
|
||||
}
|
||||
}
|
||||
public class TDASServiceAsyncInfo
|
||||
{
|
||||
public ServiceCallback callback { get; set; }
|
||||
public object userData { get; set; }
|
||||
public object functionData { get; set; }
|
||||
|
||||
public TDASServiceAsyncInfo(ServiceCallback _callback, object _userData)
|
||||
{
|
||||
callback = _callback;
|
||||
userData = _userData;
|
||||
}
|
||||
|
||||
public void Error(string msg, Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cbData = new ServiceCallbackData();
|
||||
cbData.Status = ServiceCallbackData.CallbackStatus.Failure;
|
||||
cbData.ErrorMessage = msg;
|
||||
cbData.ErrorException = ex;
|
||||
cbData.UserData = userData;
|
||||
callback(cbData);
|
||||
}
|
||||
catch (Exception eex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoError, eex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Error(string msg)
|
||||
{
|
||||
Error(msg, null);
|
||||
}
|
||||
|
||||
public void Progress(int value)
|
||||
{
|
||||
try
|
||||
{
|
||||
var progressData = new ServiceCallbackData();
|
||||
progressData.Status = ServiceCallbackData.CallbackStatus.ProgressReport;
|
||||
progressData.ProgressValue = value;
|
||||
progressData.UserData = userData;
|
||||
callback(progressData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoProgressError, ex);
|
||||
}
|
||||
}
|
||||
public void NewData(object obj)
|
||||
{
|
||||
if (obj is ServiceCallbackData.DiagnosticNewData)
|
||||
{
|
||||
var progressData = new ServiceCallbackData();
|
||||
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
|
||||
progressData.ProgressValue = 0;
|
||||
progressData.UserData = userData;
|
||||
progressData.SetNewDiagnosticData((obj as ServiceCallbackData.DiagnosticNewData));
|
||||
callback(progressData);
|
||||
}
|
||||
else
|
||||
{
|
||||
var newdatadata = obj as NewDataData;
|
||||
var datas = newdatadata.datas;
|
||||
var samplenumbers = newdatadata.SampleNumbers;
|
||||
var timeStamps = newdatadata.TimeStamps;
|
||||
var sequenceNumbers = newdatadata.SequenceNumbers;
|
||||
try
|
||||
{
|
||||
var progressData = new ServiceCallbackData();
|
||||
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
|
||||
progressData.ProgressValue = 0;
|
||||
progressData.UserData = userData;
|
||||
for (var i = 0; i < datas.Length && i < samplenumbers.Length; i++)
|
||||
{
|
||||
progressData.AddSampleData(datas[i], samplenumbers[i], timeStamps[i], sequenceNumbers[i]);
|
||||
}
|
||||
callback(progressData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.SLICEAsyncInfoNewDataError, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void NewData(IList<short[][]> datas, IList<ulong> samplenumbers, IList<ulong> timeStamps, IList<ulong> sequenceNumbers)
|
||||
{
|
||||
try
|
||||
{
|
||||
var progressData = new ServiceCallbackData();
|
||||
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
|
||||
progressData.ProgressValue = 0;
|
||||
progressData.UserData = userData;
|
||||
for (var i = 0; i < datas.Count && i < samplenumbers.Count; i++)
|
||||
{
|
||||
progressData.AddSampleData(datas[i], samplenumbers[i], timeStamps[i], 0);
|
||||
}
|
||||
callback(progressData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoNewDataError, ex);
|
||||
}
|
||||
}
|
||||
public void NewData(short[][] data, ulong samplenumber, ulong timeStamp, ulong sequenceNumber)
|
||||
{
|
||||
try
|
||||
{
|
||||
var progressData = new ServiceCallbackData();
|
||||
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
|
||||
progressData.ProgressValue = 0;
|
||||
progressData.UserData = userData;
|
||||
progressData.AddSampleData(data, samplenumber, timeStamp, sequenceNumber);
|
||||
callback(progressData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoNewDataError, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Success()
|
||||
{
|
||||
try
|
||||
{
|
||||
var success = new ServiceCallbackData();
|
||||
success.Status = ServiceCallbackData.CallbackStatus.Success;
|
||||
success.UserData = userData;
|
||||
callback(success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoSuccessError, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cancelReport = new ServiceCallbackData();
|
||||
cancelReport.Status = ServiceCallbackData.CallbackStatus.Canceled;
|
||||
cancelReport.ProgressValue = 0;
|
||||
cancelReport.UserData = userData;
|
||||
callback(cancelReport);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoCancelError, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LaunchAsyncWorker(string Invoker, WaitCallback cb, object asyncInfo)
|
||||
{
|
||||
if (!Connected)
|
||||
{
|
||||
// "{0}: Not currently connected"
|
||||
throw new NotConnectedException(string.Format(Strings.Slice_LaunchAsyncWorker_Err1, Invoker));
|
||||
}
|
||||
|
||||
if (!ThreadPool.QueueUserWorkItem(cb, asyncInfo))
|
||||
{
|
||||
// "{0}: Unable to enqueue function"
|
||||
throw new Exception(string.Format(Strings.Slice_LaunchAsyncWorker_Err2, Invoker));
|
||||
}
|
||||
}
|
||||
|
||||
private void CallSyncMethod(string Invoker, WaitCallback cb, object info)
|
||||
{
|
||||
if (!Connected)
|
||||
{
|
||||
// "{0}: Not currently connected"
|
||||
throw new NotConnectedException(string.Format(Strings.Slice_LaunchAsyncWorker_Err1, Invoker));
|
||||
}
|
||||
cb(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// compare to an object to determine equality
|
||||
/// </summary>
|
||||
/// <param name="right"></param>
|
||||
/// <returns></returns>
|
||||
public override bool Equals(object right)
|
||||
{
|
||||
|
||||
if (right == null)
|
||||
return false;
|
||||
|
||||
if (ReferenceEquals(this, right))
|
||||
return true;
|
||||
|
||||
if (!(right is TDAS<T> rightSlice))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(SerialNumber))
|
||||
{
|
||||
return string.IsNullOrEmpty(rightSlice.SerialNumber);
|
||||
}
|
||||
if (string.IsNullOrEmpty(rightSlice.SerialNumber))
|
||||
return false;
|
||||
return SerialNumber == rightSlice.SerialNumber;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns identical index for any two 'equal' slice
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (string.IsNullOrEmpty(SerialNumber))
|
||||
return 0;
|
||||
return SerialNumber.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
326
DataPRO/IService/Classes/TDAS Service/TriggerCheck.cs
Normal file
326
DataPRO/IService/Classes/TDAS Service/TriggerCheck.cs
Normal file
@@ -0,0 +1,326 @@
|
||||
using System.Threading;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.ICommunication;
|
||||
using System;
|
||||
using DTS.Common.Interface.Connection;
|
||||
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 Trigger check
|
||||
void ITriggerCheckActions.PreStartTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
void ITriggerCheckActions.PostStartTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
private class TriggerCheckPacket : TDASServiceAsyncInfo
|
||||
{
|
||||
public TriggerCheckPacket(ServiceCallback cb, object ud)
|
||||
: base(cb, ud)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void ITriggerCheckActions.StartTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
LaunchAsyncWorker("TDAS.StartTriggerCheck", AsyncStartTriggerCheck, info);
|
||||
}
|
||||
|
||||
private void AsyncStartTriggerCheck(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is TriggerCheckPacket info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (null == DASArmStatus)
|
||||
{
|
||||
SetDASArmStatus(new ArmStatus(), true);
|
||||
}
|
||||
var status = DASArmStatus;
|
||||
try
|
||||
{
|
||||
status.IsArmed = true;
|
||||
status.IsRecording = false;
|
||||
status.IsTriggered = false;
|
||||
foreach (var module in DASInfo.Modules)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (module.TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsG5())
|
||||
{
|
||||
var testTrigger = new Command.TDAS.TestTrigger(this)
|
||||
{
|
||||
ModuleIndex = module.ModuleArrayIndex,
|
||||
SubCommand = Command.TDAS.TestTrigger.SubCommandValues.ARM
|
||||
};
|
||||
testTrigger.SyncExecute();
|
||||
break;
|
||||
}
|
||||
|
||||
var qsn = new Command.TDAS.QuerySerialNumberBroadcast(this, module.ModuleArrayIndex);
|
||||
qsn.SyncExecute();
|
||||
|
||||
var ttb = new Command.TDAS.TestTriggerBroadcast(this, module.ModuleArrayIndex)
|
||||
{
|
||||
SubCommand = Command.TDAS.TestTrigger.SubCommandValues.ARM
|
||||
};
|
||||
ttb.SyncExecute();
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
SetDASArmStatus(status, true);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//assuming this is for logging purposes...unknown
|
||||
var ta = new Command.TDAS.TestAll(this) { Mode = Command.TDAS.TestAllCommandString.Modes.CURR };
|
||||
ta.SyncExecute();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
info.Success();
|
||||
}
|
||||
|
||||
void ITriggerCheckActions.DoTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
LaunchAsyncWorker("TDAS.DoTriggercheck", AsyncDoTriggerCheck, info);
|
||||
}
|
||||
void ITriggerCheckActions.DoStartCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
LaunchAsyncWorker("TDAS.DoStartcheck", AsyncDoStartCheck, info);
|
||||
}
|
||||
private void AsyncDoStartCheck(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is TriggerCheckPacket info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (null == DASArmStatus)
|
||||
{
|
||||
SetDASArmStatus(new ArmStatus(), false);
|
||||
}
|
||||
var status = DASArmStatus;
|
||||
try
|
||||
{
|
||||
var ta = new Command.TDAS.TestAll(this) { Mode = Command.TDAS.TestAllCommandString.Modes.PREV };
|
||||
try
|
||||
{
|
||||
ta.SyncExecute();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ta.StartedRecordingFlag == DFConstantsAndEnums.VoltageStatusColor.Yellow
|
||||
|| ta.StartedRecordingFlag == DFConstantsAndEnums.VoltageStatusColor.Red)
|
||||
{
|
||||
status.IsRecording = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
StartRecord = false;
|
||||
}
|
||||
|
||||
if (DASArmStatus.IsRecording)
|
||||
{
|
||||
status.IsArmed = false;
|
||||
}
|
||||
status.IsArmed = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
SetDASArmStatus(status, true);
|
||||
}
|
||||
|
||||
info.Success();
|
||||
}
|
||||
|
||||
void ITriggerCheckActions.DoTriggerCheckSync()
|
||||
{
|
||||
//this function was created as part of
|
||||
//5211 Add check to ECM event line during ArmChecklist
|
||||
//however to minimize impact since the issue doesn't affect TDAS
|
||||
//I'll not make the changes to TDAS trigger check/armchecklist checks
|
||||
//instead for now I'll leave it as is
|
||||
//since this function shouldn't be used (unless we make the changes above), I'll leave it
|
||||
//with an exception to warn anyone that hooks it up not realizing the issue
|
||||
throw new NotImplementedException("DoTriggerCheckSync is not implemented for TDAS");
|
||||
}
|
||||
private void AsyncDoTriggerCheck(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is TriggerCheckPacket info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var ta = new Command.TDAS.TestAll(this) { Mode = Command.TDAS.TestAllCommandString.Modes.PREV };
|
||||
ta.SyncExecute();
|
||||
|
||||
if (ta.TriggerFlag == DFConstantsAndEnums.VoltageStatusColor.Red
|
||||
|| ta.TriggerFlag == DFConstantsAndEnums.VoltageStatusColor.Yellow)
|
||||
{
|
||||
DASArmStatus.IsTriggered = true;
|
||||
SetDASArmStatus();
|
||||
try
|
||||
{
|
||||
var status = new ArmStatus();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var module in DASInfo.Modules)
|
||||
{
|
||||
if (IsG5() && 0 < module.ModuleArrayIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (module.TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var testTrigger = new Command.TDAS.TestTrigger(this, 5000);
|
||||
testTrigger.ModuleIndex = module.ModuleArrayIndex;
|
||||
testTrigger.SubCommand = Command.TDAS.TestTrigger.SubCommandValues.STATUS;
|
||||
try
|
||||
{
|
||||
testTrigger.SyncExecute();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Module probably timed out because it is still armed and never responded to the rack trigger/event line.
|
||||
status.IsArmed = true;
|
||||
status.IsTriggered = false;
|
||||
info.Error(module.SerialNumber + " did not trigger, but other modules did");
|
||||
return;
|
||||
}
|
||||
|
||||
if (testTrigger.TriggerStatus == Command.TDAS.TestTrigger.StatusValues.OFF)
|
||||
{
|
||||
status.IsTriggered = true;
|
||||
status.IsArmed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (status.IsTriggered)
|
||||
{
|
||||
info.Error(module.SerialNumber + " did not trigger, but other modules did");
|
||||
return;
|
||||
}
|
||||
|
||||
status.IsTriggered = false;
|
||||
status.IsArmed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally { SetDASArmStatus(status, true); }
|
||||
|
||||
info.Success();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info.Success();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
info.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
void ITriggerCheckActions.CancelTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
LaunchAsyncWorker("TDAS.CancelTriggerCheck", AsyncCancelTriggerCheck, info);
|
||||
}
|
||||
|
||||
private void AsyncCancelTriggerCheck(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is TriggerCheckPacket info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
foreach (var m in DASInfo.Modules)
|
||||
{
|
||||
if (m.SerialNumber == "EMPTY" || m.TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK) continue;
|
||||
if (IsG5())
|
||||
{
|
||||
var testTrigger = new Command.TDAS.TestTrigger(this);
|
||||
testTrigger.ModuleIndex = m.ModuleArrayIndex;
|
||||
testTrigger.SubCommand = Command.TDAS.TestTrigger.SubCommandValues.OFF;
|
||||
testTrigger.SyncExecute();
|
||||
|
||||
var qsn = new Command.TDAS.QuerySerialNumber(this);
|
||||
qsn.ModuleIndex = m.ModuleArrayIndex;
|
||||
qsn.SyncExecute();
|
||||
break;
|
||||
}
|
||||
var qsc = new Command.TDAS.QuerySerialNumberBroadcast(this, m.ModuleArrayIndex);
|
||||
qsc.SyncExecute();
|
||||
|
||||
var tbc = new Command.TDAS.TestTriggerBroadcast(this, m.ModuleArrayIndex);
|
||||
tbc.SubCommand = Command.TDAS.TestTrigger.SubCommandValues.OFF;
|
||||
tbc.SyncExecute();
|
||||
|
||||
var qsnb = new Command.TDAS.QuerySerialNumberBroadcast(this, m.ModuleArrayIndex);
|
||||
qsnb.SyncExecute();
|
||||
break;
|
||||
}
|
||||
info.Success();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
info.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user