815 lines
34 KiB
C#
815 lines
34 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Xml;
|
|||
|
|
using System.Xml.Schema;
|
|||
|
|
using System.Xml.Serialization;
|
|||
|
|
using DTS.Common.DAS.Concepts;
|
|||
|
|
using DTS.Common.Enums;
|
|||
|
|
using DTS.Common.Enums.DASFactory;
|
|||
|
|
using DTS.Common.Interface.DASFactory;
|
|||
|
|
using DTS.Common.Interface.DASFactory.Config;
|
|||
|
|
using DTS.Common.Utils;
|
|||
|
|
|
|||
|
|
namespace DTS.DASLib.Service
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// This represents one Module on a DAS unit. A DAS unit can have numerous Modules and a Module can have
|
|||
|
|
/// numerous channels. The channels that are connected to this module are in the <see cref="DASModule.Channels" />
|
|||
|
|
/// array property. See <see cref="DASChannel" />. Another property, <see cref="DASModule.ModuleArrayIndex" />
|
|||
|
|
/// is the index of this object in any array of Modules in the corresponding <see cref="IDASCommunication" />
|
|||
|
|
/// however it may also be addressed by it's Device ID. The first module in a DAS will have a ModuleArrayIndex
|
|||
|
|
/// of 0 but a DeviceID of 1. See <see cref="DTS.DASLib.Service.InfoResult" />.MapDASChannelNumber2ModuleDeviceID and
|
|||
|
|
/// <see cref="DTS.DASLib.Service.InfoResult" />.MapModuleDeviceIDAndChannelNum2DASChannel
|
|||
|
|
/// </summary>
|
|||
|
|
[Serializable]
|
|||
|
|
public class DASModule : IDASModule, IXmlSerializable
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// An array of <see cref="DASChannel" /> objects representing the channels attatched to this
|
|||
|
|
/// module, indexable by ModuleChannelNumber of the Channel.
|
|||
|
|
/// </summary>
|
|||
|
|
public IDASChannel[] Channels { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// EID's for the module corresponding to the sensors on each of the channels.
|
|||
|
|
/// </summary>
|
|||
|
|
[XmlIgnore]
|
|||
|
|
public IEID[] IDs { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Index of this Module in any array of Modules. The first module in a DAS unit will have a
|
|||
|
|
/// ModuleArrayIndex of 0.
|
|||
|
|
/// </summary>
|
|||
|
|
public int ModuleArrayIndex { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// For use only with Circular-Buffer mode.
|
|||
|
|
/// See <see cref="DASModule.RecordingMode" />.
|
|||
|
|
/// The number of requested seconds for this Module to sample data before a 'Trigger' event; the number of
|
|||
|
|
/// seconds to sample BEFORE time-zero.
|
|||
|
|
/// </summary>
|
|||
|
|
public double RequestedPreTriggerSeconds { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// For use with all recording modes.
|
|||
|
|
/// See <see cref="DASModule.RecordingMode" />.
|
|||
|
|
/// The number of requested seconds to sample data from sensors after time-zero, that is after
|
|||
|
|
/// a trigger or start event.
|
|||
|
|
/// </summary>
|
|||
|
|
public double RequestedPostTriggerSeconds { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// For use only with Circular-Buffer mode.
|
|||
|
|
/// See <see cref="DASModule.RecordingMode" />.
|
|||
|
|
/// The number of seconds for this Module to sample data before a 'Trigger' event; the number of
|
|||
|
|
/// seconds to sampel BEFORE time-zero.
|
|||
|
|
/// </summary>
|
|||
|
|
public double PreTriggerSeconds { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// For use with all recording modes.
|
|||
|
|
/// See <see cref="DASModule.RecordingMode" />.
|
|||
|
|
/// The number of seconds to sample data from sensors after time-zero, that is after
|
|||
|
|
/// a trigger or start event.
|
|||
|
|
/// </summary>
|
|||
|
|
public double PostTriggerSeconds { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// The number of events to collect before disarming.
|
|||
|
|
/// </summary>
|
|||
|
|
public int NumberOfEvents { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// The number of seconds of inactivity before going back to sleep.
|
|||
|
|
/// </summary>
|
|||
|
|
public int WakeUpMotionTimeout { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// The version of the firmware on a module.
|
|||
|
|
/// </summary>
|
|||
|
|
public string FirmwareVersion { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// A string that describes the module, for example, to know if it was created for the
|
|||
|
|
/// purposes of adding it to the .dts file during download of Slice6 Distributor attributes.
|
|||
|
|
/// </summary>
|
|||
|
|
public string Description { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// The maximum storage space for a module.
|
|||
|
|
/// </summary>
|
|||
|
|
public UInt64? MaxEventStorageSpaceInBytes { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// This is set after a recording session and is the total number of samples this Module
|
|||
|
|
/// captured during the last data acquisition run.
|
|||
|
|
/// </summary>
|
|||
|
|
public UInt64 NumberOfSamples { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// An array of sample numbers where a trigger was activated.
|
|||
|
|
/// </summary>
|
|||
|
|
[XmlIgnore]
|
|||
|
|
public UInt64[] TriggerSampleNumbers { get; set; }
|
|||
|
|
|
|||
|
|
public int GetLevelTriggerT0AdjustmentSamplesAutoApplied()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
//temporary hack/workaround to correct leveltriggert0adjustmentsamples
|
|||
|
|
if (OwningDAS is IDASReconfigure)
|
|||
|
|
{
|
|||
|
|
//we do qualifications +1 at request of Loc/Tim, see them for details
|
|||
|
|
var channelsWithAdjustments = Channels.Where(c => c.LevelTriggerSeen);
|
|||
|
|
return channelsWithAdjustments.Count() > 0 ? channelsWithAdjustments.First().QualificationSamples : 0;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//
|
|||
|
|
// Figure out what the number of samples that would have been auto-applied to
|
|||
|
|
// this module is.
|
|||
|
|
//
|
|||
|
|
var channelsWithAdjustments = Channels.Where(c => null != c.LevelTriggerT0AdjustmentSamples);
|
|||
|
|
var channelsWithMaxAdjustment = channelsWithAdjustments.Max(c => c.LevelTriggerT0AdjustmentSamples);
|
|||
|
|
return channelsWithAdjustments.Count() > 0 ? (int)(channelsWithAdjustments.First().LevelTriggerT0AdjustmentSamples) : 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
catch (System.Exception ex)
|
|||
|
|
{
|
|||
|
|
throw new ApplicationException(
|
|||
|
|
"encountered problem getting number of level trigger T0 adjustment samples already applied to module "
|
|||
|
|
+ (null != OwningDAS && null != OwningDAS.SerialNumber ? "\"" + OwningDAS.SerialNumber + "\"" : "<NULL>")
|
|||
|
|
+ ", module "
|
|||
|
|
+ ModuleArrayIndex.ToString(),
|
|||
|
|
ex);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// The sample number where recording started.
|
|||
|
|
/// </summary>
|
|||
|
|
public ulong StartRecordSampleNumber { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public uint StartRecordTimestampSec { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public uint TriggerTimestampSec { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public uint StartRecordTimestampNanoSec { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public uint TriggerTimestampNanoSec { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public bool PTPMasterSync { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public double TiltSensorAxisXDegreesPre { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public double TiltSensorAxisYDegreesPre { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public double TiltSensorAxisZDegreesPre { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public double TiltSensorAxisXDegreesPost { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public double TiltSensorAxisYDegreesPost { get; set; }
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public double TiltSensorAxisZDegreesPost { get; set; }
|
|||
|
|
public float TemperatureLocation1Pre { get; set; } = float.NaN;
|
|||
|
|
|
|||
|
|
public float TemperatureLocation2Pre { get; set; } = float.NaN;
|
|||
|
|
public float TemperatureLocation3Pre { get; set; } = float.NaN;
|
|||
|
|
public float TemperatureLocation4Pre { get; set; } = float.NaN;
|
|||
|
|
public float TemperatureLocation1Post { get; set; } = float.NaN;
|
|||
|
|
public float TemperatureLocation2Post { get; set; } = float.NaN;
|
|||
|
|
public float TemperatureLocation3Post { get; set; } = float.NaN;
|
|||
|
|
public float TemperatureLocation4Post { get; set; } = float.NaN;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// The sample rate in Hz at which the Module will sample sensor data.
|
|||
|
|
/// </summary>
|
|||
|
|
public uint SampleRateHz { get; set; }
|
|||
|
|
|
|||
|
|
//FB 25558
|
|||
|
|
/// <summary>
|
|||
|
|
/// The actual sample rate in Hz currently used in realtime for TSR AIR
|
|||
|
|
/// </summary>
|
|||
|
|
public uint ActualSampleRateHz { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// The sample rate in Hz at which any Embedded Modules will sample sensor data.
|
|||
|
|
/// </summary>
|
|||
|
|
public uint[] EmbeddedSampleRateHz { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// xml string tag for AAFilterRateHz
|
|||
|
|
/// </summary>
|
|||
|
|
public const string AAFilterRateHzTag = "AAFilterRateHz";
|
|||
|
|
/// <summary>
|
|||
|
|
/// Hardware anti-alias filter rate.
|
|||
|
|
/// </summary>
|
|||
|
|
public float AAFilterRateHz { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// What type of recording mode is this Module in?
|
|||
|
|
/// See <see cref="Test.Module.RecordingMode.RecorderMode" />.
|
|||
|
|
/// </summary>
|
|||
|
|
public DFConstantsAndEnums.RecordingMode RecordingMode { get; set; }
|
|||
|
|
public DateTime ScheduledStartTime { get; set; }
|
|||
|
|
public int RecordingInterval { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// FB15388: The UDP streaming profile set (for supporting DAS).
|
|||
|
|
/// </summary>
|
|||
|
|
[XmlIgnore]
|
|||
|
|
public UDPStreamProfile StreamProfile { get; set; }
|
|||
|
|
|
|||
|
|
#region Slice 6 Tilt Feature
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Defines which 2 axis will be used for the bubble level feature for Slice 6.
|
|||
|
|
/// </summary>
|
|||
|
|
public DFConstantsAndEnums.TiltAxes TiltAxes { get; set; }
|
|||
|
|
|
|||
|
|
public double TargetAxisOne { get; set; }
|
|||
|
|
|
|||
|
|
public double TargetAxisTwo { get; set; }
|
|||
|
|
|
|||
|
|
public float TargetAngleAxisX { get; set; }
|
|||
|
|
public float TargetAngleAxisY { get; set; }
|
|||
|
|
public float TargetAngleAxisZ { get; set; }
|
|||
|
|
|
|||
|
|
public double MountOffsetAxisOne { get; set; }
|
|||
|
|
|
|||
|
|
public double MountOffsetAxisTwo { get; set; }
|
|||
|
|
|
|||
|
|
public string SystemLocation { get; set; }
|
|||
|
|
|
|||
|
|
public string SystemID { get; set; }
|
|||
|
|
|
|||
|
|
public int AxisIgnored { get; set; }
|
|||
|
|
|
|||
|
|
public byte TiltID { get; set; }
|
|||
|
|
|
|||
|
|
public string TiltSerialNumber { get; set; }
|
|||
|
|
|
|||
|
|
public double LevelTolerance { get; set; }
|
|||
|
|
|
|||
|
|
public bool UseForTiltCalculation { get; set; }
|
|||
|
|
public double InputVoltage { get; set; }
|
|||
|
|
public double BatteryVoltage { get; set; }
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
[XmlIgnore]
|
|||
|
|
public IDASCommunication OwningDAS { get; set; }
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Count how many channels are configured in this Module.
|
|||
|
|
/// See <see cref="AnalogInputDASChannel.IsConfigured" />.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>Number of configured channels</returns>
|
|||
|
|
public int NumberOfConfiguredChannels()
|
|||
|
|
{
|
|||
|
|
if (Channels == null || Channels.Length == 0)
|
|||
|
|
return 0;
|
|||
|
|
var configuredChannels = from ch in Channels.AsParallel() where ch.IsConfigured() select ch;
|
|||
|
|
if (configuredChannels.Count() > 0)
|
|||
|
|
{
|
|||
|
|
var channels = configuredChannels.ToArray();
|
|||
|
|
}
|
|||
|
|
return configuredChannels.Count();
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// Count how many TOM channels are configured in this module
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>Number of configured TOM channels</returns>
|
|||
|
|
public int NumberOfConfiguredTOMChannels()
|
|||
|
|
{
|
|||
|
|
if (Channels == null || Channels.Length == 0)
|
|||
|
|
{
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
var configuredTOMChannels = from ch in Channels.AsParallel() where (ch.IsConfigured() && ch is OutputSquibChannel) select ch;
|
|||
|
|
return configuredTOMChannels.Count();
|
|||
|
|
}
|
|||
|
|
public bool IsDummyArmed()
|
|||
|
|
{
|
|||
|
|
int numConfiguredChannels = NumberOfConfiguredChannels();
|
|||
|
|
return numConfiguredChannels < 1;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// Count how many channels this module has (regardless if they are configured
|
|||
|
|
/// or not).
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>Total number of channels</returns>
|
|||
|
|
public int NumberOfChannels()
|
|||
|
|
{
|
|||
|
|
if (Channels == null || Channels.Length == 0)
|
|||
|
|
return 0;
|
|||
|
|
return Channels.Length;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Retrieve the serial number from DASInfo
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>The serial number of this module</returns>
|
|||
|
|
public string SerialNumber()
|
|||
|
|
{
|
|||
|
|
if (OwningDAS == null)
|
|||
|
|
{
|
|||
|
|
throw new NullReferenceException("DASModule: Trying to get serialnumber but OwningDAS is null");
|
|||
|
|
}
|
|||
|
|
if (OwningDAS.DASInfo == null)
|
|||
|
|
{
|
|||
|
|
throw new NullReferenceException("DASModule: Trying to get serialnumber but OwningDAS.DASInfo is null");
|
|||
|
|
}
|
|||
|
|
if (OwningDAS.DASInfo.Modules == null)
|
|||
|
|
{
|
|||
|
|
throw new NullReferenceException("DASModule: Trying to get serialnumber but OwningDAS.DASInfo.Modules is null");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < OwningDAS.DASInfo.Modules.Length; i++)
|
|||
|
|
{
|
|||
|
|
if (OwningDAS.DASInfo.Modules[i]?.ModuleArrayIndex == ModuleArrayIndex)
|
|||
|
|
{
|
|||
|
|
var sn = OwningDAS.DASInfo.Modules[i].SerialNumber;
|
|||
|
|
if (string.IsNullOrEmpty(sn))
|
|||
|
|
{
|
|||
|
|
throw new NullReferenceException("DASModule: Trying to get serialnumber but it's null or empty");
|
|||
|
|
}
|
|||
|
|
else { return sn; }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
throw new NullReferenceException("DASModule: Trying to get serialnumber but ModuleArrayIndex is invalid");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Retrieve the module type from DASInfo
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>The type of this module</returns>
|
|||
|
|
public DFConstantsAndEnums.ModuleType ModuleType()
|
|||
|
|
{
|
|||
|
|
if (OwningDAS == null)
|
|||
|
|
{
|
|||
|
|
throw new NullReferenceException("DASModule: Trying to get module type but OwningDAS is null");
|
|||
|
|
}
|
|||
|
|
if (OwningDAS.DASInfo == null)
|
|||
|
|
{
|
|||
|
|
throw new NullReferenceException("DASModule: Trying to get module type but OwningDAS.DASInfo is null");
|
|||
|
|
}
|
|||
|
|
if (OwningDAS.DASInfo.Modules == null)
|
|||
|
|
{
|
|||
|
|
throw new NullReferenceException("DASModule: Trying to get module type but OwningDAS.DASInfo.Modules is null");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
foreach (InfoResult.Module module in OwningDAS.DASInfo.Modules)
|
|||
|
|
{
|
|||
|
|
if (module.ModuleArrayIndex != ModuleArrayIndex) continue;
|
|||
|
|
var dasType = module.TypeOfModule;
|
|||
|
|
return dasType;
|
|||
|
|
}
|
|||
|
|
throw new NullReferenceException("DASModule: Trying to get module type but ModuleArrayIndex is invalid");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Retrieve the module type from DASInfo and return whether or not it's a clock type
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>Whether the type of this module is a clock</returns>
|
|||
|
|
public bool IsClock()
|
|||
|
|
{
|
|||
|
|
DFConstantsAndEnums.ModuleType moduleType = ModuleType();
|
|||
|
|
return moduleType == DFConstantsAndEnums.ModuleType.EmbeddedClockNanosAndPad ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedClockSecondsAndMarker;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Retrieve the module type from DASInfo and return whether or not it's a uart type
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>Whether the type of this module is a uart</returns>
|
|||
|
|
public bool IsUart()
|
|||
|
|
{
|
|||
|
|
DFConstantsAndEnums.ModuleType moduleType = ModuleType();
|
|||
|
|
return moduleType == DFConstantsAndEnums.ModuleType.UART;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Retrieve the module type from DASInfo and return whether or not it's a stream output type
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>Whether the type of this module is a stream output</returns>
|
|||
|
|
public bool IsStreamOut()
|
|||
|
|
{
|
|||
|
|
DFConstantsAndEnums.ModuleType moduleType = ModuleType();
|
|||
|
|
return moduleType == DFConstantsAndEnums.ModuleType.StreamOut;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Retrieve the module type from DASInfo and return whether or not it's a stream input type
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>Whether the type of this module is a stream output</returns>
|
|||
|
|
public bool IsStreamIn()
|
|||
|
|
{
|
|||
|
|
DFConstantsAndEnums.ModuleType moduleType = ModuleType();
|
|||
|
|
return moduleType == DFConstantsAndEnums.ModuleType.StreamIn;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Retrieve the module type from DASInfo and return whether or not it's an embedded type
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>Whether the type of this module is embedded</returns>
|
|||
|
|
public bool IsEmbedded()
|
|||
|
|
{
|
|||
|
|
DFConstantsAndEnums.ModuleType moduleType = ModuleType();
|
|||
|
|
return moduleType == DFConstantsAndEnums.ModuleType.EmbeddedLinearAccelLowG ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedLinearAccelHighG ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedAngularRate ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedAngularAccel ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedAtmospheric ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedMagnetInput ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedMagnetometer ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedMicrophone ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedOptical ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedClockNanosAndPad ||
|
|||
|
|
moduleType == DFConstantsAndEnums.ModuleType.EmbeddedClockSecondsAndMarker;
|
|||
|
|
}
|
|||
|
|
public bool IsThermocoupler()
|
|||
|
|
{
|
|||
|
|
DFConstantsAndEnums.ModuleType moduleType = ModuleType();
|
|||
|
|
return moduleType == DFConstantsAndEnums.ModuleType.Thermocoupler;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// Constructor for a DASModule that initializes the object with a
|
|||
|
|
/// ModuleArrayIndex and a parent DAS as an IDASCommunication.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="moduleArrayIdx"></param>
|
|||
|
|
/// <param name="_OwningDAS"></param>
|
|||
|
|
public DASModule(int moduleArrayIdx, IDASCommunication _OwningDAS)
|
|||
|
|
{
|
|||
|
|
Channels = null;
|
|||
|
|
IDs = null;
|
|||
|
|
ModuleArrayIndex = moduleArrayIdx;
|
|||
|
|
PreTriggerSeconds = 0;
|
|||
|
|
PostTriggerSeconds = 0;
|
|||
|
|
NumberOfSamples = 0;
|
|||
|
|
TriggerSampleNumbers = null;
|
|||
|
|
|
|||
|
|
StartRecordSampleNumber = 0;
|
|||
|
|
SampleRateHz = 10000;
|
|||
|
|
AAFilterRateHz = 0;
|
|||
|
|
RecordingMode = DFConstantsAndEnums.RecordingMode.RecorderMode;
|
|||
|
|
OwningDAS = _OwningDAS;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Default constructor for serialization methods compliance.
|
|||
|
|
/// </summary>
|
|||
|
|
public DASModule()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
public virtual void WriteXmlCRC32(XmlWriter writer)
|
|||
|
|
{
|
|||
|
|
writer.WriteStartElement("DASModule");
|
|||
|
|
|
|||
|
|
// Channels
|
|||
|
|
writer.WriteStartElement("Channels");
|
|||
|
|
if (Channels != null)
|
|||
|
|
{
|
|||
|
|
foreach (var channel in Channels)
|
|||
|
|
{
|
|||
|
|
channel.WriteElementStart(writer);
|
|||
|
|
channel.WriteXmlCRC32(writer);
|
|||
|
|
channel.WriteElementEnd(writer);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
writer.WriteEndElement();
|
|||
|
|
|
|||
|
|
// ModuleArrayIndex
|
|||
|
|
XMLHelper.PutInt(writer, "ModuleArrayIndex", ModuleArrayIndex);
|
|||
|
|
|
|||
|
|
// PreTriggerSeconds
|
|||
|
|
//XMLHelper.PutDouble(writer, "PreTriggerSeconds", PreTriggerSeconds);
|
|||
|
|
|
|||
|
|
// PostTriggerSeconds
|
|||
|
|
//XMLHelper.PutDouble(writer, "PostTriggerSeconds", PostTriggerSeconds);
|
|||
|
|
|
|||
|
|
// NumberOfSamples
|
|||
|
|
//XMLHelper.PutUInt64(writer, "NumberOfSamples", NumberOfSamples);
|
|||
|
|
|
|||
|
|
// StartRecordSampleNumber
|
|||
|
|
//XMLHelper.PutUInt64(writer, "StartRecordSampleNumber", StartRecordSampleNumber);
|
|||
|
|
|
|||
|
|
// SampleRateHz
|
|||
|
|
//XMLHelper.PutUInt(writer, "SampleRateHz", SampleRateHz);
|
|||
|
|
|
|||
|
|
// AAFilterRateHz, we write this one as a double
|
|||
|
|
//XMLHelper.PutDouble(writer, AAFilterRateHzTag, (double)AAFilterRateHz);
|
|||
|
|
|
|||
|
|
// RecordingMode
|
|||
|
|
//XMLHelper.PutString(writer, "RecordingMode", RecordingMode.ToString());
|
|||
|
|
|
|||
|
|
writer.WriteEndElement();
|
|||
|
|
}
|
|||
|
|
public virtual void WriteXml(XmlWriter writer)
|
|||
|
|
{
|
|||
|
|
writer.WriteStartElement("DASModule");
|
|||
|
|
|
|||
|
|
// Channels
|
|||
|
|
writer.WriteStartElement("Channels");
|
|||
|
|
if (Channels != null)
|
|||
|
|
{
|
|||
|
|
foreach (var channel in Channels)
|
|||
|
|
{
|
|||
|
|
channel.WriteElementStart(writer);
|
|||
|
|
channel.WriteXml(writer);
|
|||
|
|
channel.WriteElementEnd(writer);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
writer.WriteEndElement();
|
|||
|
|
|
|||
|
|
// ModuleArrayIndex
|
|||
|
|
XMLHelper.PutInt(writer, "ModuleArrayIndex", ModuleArrayIndex);
|
|||
|
|
|
|||
|
|
// PreTriggerSeconds
|
|||
|
|
XMLHelper.PutDouble(writer, "PreTriggerSeconds", PreTriggerSeconds);
|
|||
|
|
|
|||
|
|
// PostTriggerSeconds
|
|||
|
|
XMLHelper.PutDouble(writer, "PostTriggerSeconds", PostTriggerSeconds);
|
|||
|
|
|
|||
|
|
// NumberOfSamples
|
|||
|
|
XMLHelper.PutUInt64(writer, "NumberOfSamples", NumberOfSamples);
|
|||
|
|
|
|||
|
|
// StartRecordSampleNumber
|
|||
|
|
XMLHelper.PutUInt64(writer, "StartRecordSampleNumber", StartRecordSampleNumber);
|
|||
|
|
|
|||
|
|
// SampleRateHz
|
|||
|
|
XMLHelper.PutUInt(writer, "SampleRateHz", SampleRateHz);
|
|||
|
|
|
|||
|
|
// AAFilterRateHz, we write this one as a double
|
|||
|
|
XMLHelper.PutDouble(writer, AAFilterRateHzTag, AAFilterRateHz);
|
|||
|
|
|
|||
|
|
// RecordingMode
|
|||
|
|
XMLHelper.PutString(writer, "RecordingMode", RecordingMode.ToString());
|
|||
|
|
|
|||
|
|
// ScheduledStartTime
|
|||
|
|
XMLHelper.PutString(writer, "ScheduledStartTime", ScheduledStartTime.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
|||
|
|
|
|||
|
|
// RecordingInterval
|
|||
|
|
XMLHelper.PutString(writer, "RecordingInterval", RecordingInterval.ToString());
|
|||
|
|
|
|||
|
|
// Slice 6 Tilt variables
|
|||
|
|
XMLHelper.PutString(writer, "TiltAxes", TiltAxes.ToString());
|
|||
|
|
XMLHelper.PutString(writer, "SystemID", SystemID);
|
|||
|
|
XMLHelper.PutString(writer, "SystemLocation", SystemLocation);
|
|||
|
|
XMLHelper.PutDouble(writer, "TargetAxisOne", TargetAxisOne);
|
|||
|
|
XMLHelper.PutDouble(writer, "TargetAxisTwo", TargetAxisTwo);
|
|||
|
|
XMLHelper.PutDouble(writer, "MountOffsetAxisOne", MountOffsetAxisOne);
|
|||
|
|
XMLHelper.PutDouble(writer, "MountOffsetAxisTwo", MountOffsetAxisTwo);
|
|||
|
|
XMLHelper.PutDouble(writer, "LevelTolerance", LevelTolerance);
|
|||
|
|
XMLHelper.PutInt(writer, "AxisIgnored", AxisIgnored);
|
|||
|
|
XMLHelper.PutBool(writer, "UseForTiltCalculation", UseForTiltCalculation);
|
|||
|
|
XMLHelper.PutDouble(writer, "InputVoltage", InputVoltage);
|
|||
|
|
XMLHelper.PutDouble(writer, "BatteryVoltage", BatteryVoltage);
|
|||
|
|
|
|||
|
|
// FB 26980 Write NumberOfEvents to XML
|
|||
|
|
XMLHelper.PutInt(writer, "NumberOfEvents", NumberOfEvents);
|
|||
|
|
XMLHelper.PutInt(writer, "WakeUpMotionTimeout", WakeUpMotionTimeout);
|
|||
|
|
|
|||
|
|
writer.WriteEndElement();
|
|||
|
|
}
|
|||
|
|
private void ReadChannels(XmlReader reader)
|
|||
|
|
{
|
|||
|
|
var myChannels = new List<DASChannel>();
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
if (reader.NodeType == XmlNodeType.Element && reader.Name == "DASChannel")
|
|||
|
|
{
|
|||
|
|
var chanType = "DTS.DASLib.Service." + reader.GetAttribute("xsi:type");
|
|||
|
|
var channelClassType = Type.GetType(chanType);
|
|||
|
|
var deserializedChannel = Activator.CreateInstance(channelClassType) as DASChannel;
|
|||
|
|
deserializedChannel.ReadXml(reader);
|
|||
|
|
myChannels.Add(deserializedChannel);
|
|||
|
|
}
|
|||
|
|
//if we are at </channels> break out now, don't want to do a read()
|
|||
|
|
if (reader.Name == "Channels" && (reader.NodeType == XmlNodeType.EndElement || reader.IsEmptyElement))
|
|||
|
|
{
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
//if we are at <DASChannel> we don't want to do a read, otherwise we do
|
|||
|
|
if (!(reader.NodeType == XmlNodeType.Element && reader.Name == "DASChannel"))
|
|||
|
|
{
|
|||
|
|
if (!reader.Read()) { break; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} while (!(reader.Name == "Channels" && reader.NodeType == XmlNodeType.EndElement));
|
|||
|
|
|
|||
|
|
Channels = myChannels.ToArray();
|
|||
|
|
}
|
|||
|
|
private const string CHANNELS_TAG = "Channels";
|
|||
|
|
private const string MODULEARRAYINDEX_TAG = "ModuleArrayIndex";
|
|||
|
|
private const string PRETRIGGERSECONDS_TAG = "PreTriggerSeconds";
|
|||
|
|
private const string POSTTRIGGERSECONDS_TAG = "PostTriggerSeconds";
|
|||
|
|
private const string NUMBEROFSECONDS_TAG = "NumberOfSamples";
|
|||
|
|
private const string TRIGGERSAMPLENUMBERS_TAG = "TriggerSampleNumbers";
|
|||
|
|
private const string STARTRECORDSAMPLENUMBER_TAG = "StartRecordSampleNumber";
|
|||
|
|
private const string SAMPLERATEHZ_TAG = "SampleRateHz";
|
|||
|
|
private const string AAFILTERRATEHZ_TAG = "AAFilterRateHz";
|
|||
|
|
private const string RECORDINGMODE_TAG = "RecordingMode";
|
|||
|
|
private const string SCHEDULEDSTARTTIME_TAG = "ScheduledStartTime";
|
|||
|
|
private const string RECORDINGINTERVAL_TAG = "RecordingInterval";
|
|||
|
|
private const string TILT_AXES_TAG = "TiltAxes";
|
|||
|
|
private const string SYSTEMID_TAG = "SystemID";
|
|||
|
|
private const string SYSTEMLOCATION_TAG = "SystemLocation";
|
|||
|
|
private const string MOUNTOFFSETAXISONE_TAG = "MountOffsetAxisOne";
|
|||
|
|
private const string MOUNTOFFSETAXISTWO_TAG = "MountOffsetAxisTwo";
|
|||
|
|
private const string TARGETAXISONE_TAG = "TargetAxisOne";
|
|||
|
|
private const string TARGETAXISTWO_TAG = "TargetAxisTwo";
|
|||
|
|
private const string LEVELTOLERANCE_TAG = "LevelTolerance";
|
|||
|
|
private const string AXISIGNORED_TAG = "AxisIgnored";
|
|||
|
|
private const string USEFORTILTCALCULATION_TAG = "UseForTiltCalculation";
|
|||
|
|
private const string INPUTVOLTAGE_TAG = "InputVoltage";
|
|||
|
|
private const string BATTERYVOLTAGE_TAG = "BatteryVoltage";
|
|||
|
|
private const string NUMBEROFEVENTS_TAG = "NumberOfEvents";
|
|||
|
|
private const string WAKEUPTIMEOUT_TAG = "WakeUpTimeout";
|
|||
|
|
|
|||
|
|
protected virtual void HandleElement(XmlReader reader)
|
|||
|
|
{
|
|||
|
|
switch (reader.Name)
|
|||
|
|
{
|
|||
|
|
case CHANNELS_TAG:
|
|||
|
|
ReadChannels(reader);
|
|||
|
|
break;
|
|||
|
|
case MODULEARRAYINDEX_TAG:
|
|||
|
|
ModuleArrayIndex = XMLHelper.GetInt(reader);
|
|||
|
|
break;
|
|||
|
|
case PRETRIGGERSECONDS_TAG:
|
|||
|
|
PreTriggerSeconds = XMLHelper.GetDouble(reader);
|
|||
|
|
break;
|
|||
|
|
case POSTTRIGGERSECONDS_TAG:
|
|||
|
|
PostTriggerSeconds = XMLHelper.GetDouble(reader);
|
|||
|
|
break;
|
|||
|
|
case NUMBEROFSECONDS_TAG:
|
|||
|
|
NumberOfSamples = XMLHelper.GetUInt64(reader);
|
|||
|
|
break;
|
|||
|
|
case TRIGGERSAMPLENUMBERS_TAG: // UInt64[]
|
|||
|
|
throw new XmlException("DASModule.ReadXml: Unexpected TriggerSampleNumbers tag in data");
|
|||
|
|
case STARTRECORDSAMPLENUMBER_TAG:
|
|||
|
|
StartRecordSampleNumber = XMLHelper.GetUInt64(reader);
|
|||
|
|
break;
|
|||
|
|
case SAMPLERATEHZ_TAG:
|
|||
|
|
SampleRateHz = XMLHelper.GetUInt(reader);
|
|||
|
|
break;
|
|||
|
|
case AAFilterRateHzTag:
|
|||
|
|
AAFilterRateHz = XMLHelper.GetFloat(reader);
|
|||
|
|
break;
|
|||
|
|
case RECORDINGMODE_TAG:
|
|||
|
|
var value = XMLHelper.GetString(reader);
|
|||
|
|
if (!Enum.TryParse(value, out DFConstantsAndEnums.RecordingMode mode))
|
|||
|
|
{
|
|||
|
|
if (value.Equals("ActiveMode"))
|
|||
|
|
{
|
|||
|
|
RecordingMode = DFConstantsAndEnums.RecordingMode.Aerospace;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else { RecordingMode = mode; }
|
|||
|
|
break;
|
|||
|
|
case SCHEDULEDSTARTTIME_TAG:
|
|||
|
|
var scheduledStartTime = XMLHelper.GetString(reader);
|
|||
|
|
ScheduledStartTime = DateTime.Parse(scheduledStartTime, System.Globalization.CultureInfo.InvariantCulture);
|
|||
|
|
break;
|
|||
|
|
case RECORDINGINTERVAL_TAG:
|
|||
|
|
RecordingInterval = XMLHelper.GetInt(reader);
|
|||
|
|
break;
|
|||
|
|
case TILT_AXES_TAG:
|
|||
|
|
var ta = XMLHelper.GetString(reader);
|
|||
|
|
TiltAxes = (DFConstantsAndEnums.TiltAxes)Enum.Parse(typeof(DFConstantsAndEnums.TiltAxes), ta);
|
|||
|
|
break;
|
|||
|
|
case SYSTEMID_TAG:
|
|||
|
|
SystemID = XMLHelper.GetString(reader);
|
|||
|
|
break;
|
|||
|
|
case SYSTEMLOCATION_TAG:
|
|||
|
|
SystemLocation = XMLHelper.GetString(reader);
|
|||
|
|
break;
|
|||
|
|
case MOUNTOFFSETAXISONE_TAG:
|
|||
|
|
MountOffsetAxisOne = XMLHelper.GetDouble(reader);
|
|||
|
|
break;
|
|||
|
|
case MOUNTOFFSETAXISTWO_TAG:
|
|||
|
|
MountOffsetAxisTwo = XMLHelper.GetDouble(reader);
|
|||
|
|
break;
|
|||
|
|
case TARGETAXISONE_TAG:
|
|||
|
|
TargetAxisOne = XMLHelper.GetDouble(reader);
|
|||
|
|
break;
|
|||
|
|
case TARGETAXISTWO_TAG:
|
|||
|
|
TargetAxisTwo = XMLHelper.GetDouble(reader);
|
|||
|
|
break;
|
|||
|
|
case LEVELTOLERANCE_TAG:
|
|||
|
|
LevelTolerance = XMLHelper.GetDouble(reader);
|
|||
|
|
break;
|
|||
|
|
case AXISIGNORED_TAG:
|
|||
|
|
AxisIgnored = XMLHelper.GetInt(reader);
|
|||
|
|
break;
|
|||
|
|
case USEFORTILTCALCULATION_TAG:
|
|||
|
|
UseForTiltCalculation = XMLHelper.GetBool(reader);
|
|||
|
|
break;
|
|||
|
|
case INPUTVOLTAGE_TAG:
|
|||
|
|
InputVoltage = XMLHelper.GetDouble(reader);
|
|||
|
|
break;
|
|||
|
|
case BATTERYVOLTAGE_TAG:
|
|||
|
|
BatteryVoltage = XMLHelper.GetDouble(reader);
|
|||
|
|
break;
|
|||
|
|
//FB 26980
|
|||
|
|
case NUMBEROFEVENTS_TAG:
|
|||
|
|
NumberOfEvents = XMLHelper.GetInt(reader);
|
|||
|
|
break;
|
|||
|
|
case WAKEUPTIMEOUT_TAG:
|
|||
|
|
WakeUpMotionTimeout = XMLHelper.GetInt(reader);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
// let child handle it
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public virtual void ReadXml(XmlReader reader)
|
|||
|
|
{
|
|||
|
|
// it must be an Element
|
|||
|
|
if (reader.NodeType != XmlNodeType.Element)
|
|||
|
|
{
|
|||
|
|
throw new XmlException("DASModule.ReadXml: Unknown input: " + reader.NodeType.ToString());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// remove our start tag
|
|||
|
|
if (reader.Name == "DASModule")
|
|||
|
|
{
|
|||
|
|
reader.Read();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
if (reader.NodeType != XmlNodeType.EndElement)
|
|||
|
|
{
|
|||
|
|
HandleElement(reader);
|
|||
|
|
}
|
|||
|
|
if (!reader.Read()) { break; }
|
|||
|
|
} while (!(reader.Name.Equals("DASModule") && reader.NodeType == XmlNodeType.EndElement));
|
|||
|
|
|
|||
|
|
|
|||
|
|
// we're going to end with an EndElement, so clean up
|
|||
|
|
if (reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("DASModule"))
|
|||
|
|
{
|
|||
|
|
reader.Read();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public XmlSchema GetSchema()
|
|||
|
|
{
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public virtual ushort GetCRC32()
|
|||
|
|
{
|
|||
|
|
var sb = new StringBuilder();
|
|||
|
|
|
|||
|
|
using (var writer = XmlWriter.Create(sb))
|
|||
|
|
{
|
|||
|
|
WriteXmlCRC32(writer);
|
|||
|
|
writer.Flush();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var lData = new List<byte>(Encoding.UTF8.GetBytes(sb.ToString()));
|
|||
|
|
|
|||
|
|
if (0 != lData.Count % 2) { lData.Add(0x00); }
|
|||
|
|
byte[] data = lData.ToArray();
|
|||
|
|
|
|||
|
|
ushort crc = 0xFFFF;
|
|||
|
|
for (int i = 0; i < data.Length; i += 2)
|
|||
|
|
{
|
|||
|
|
crc = Utils.Math_DoCRC16Step(BitConverter.ToUInt16(data, i), crc);
|
|||
|
|
}
|
|||
|
|
return crc;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|