386 lines
16 KiB
C#
386 lines
16 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Xml.Serialization;
|
|
using DASFactoryDb;
|
|
using DASFactoryDb.Config;
|
|
using DTS.Common.DAS.Concepts;
|
|
using DTS.Common.Enums.DASFactory;
|
|
using DTS.Common.Interface.DASFactory;
|
|
using DTS.Common.Interface.DASFactory.Config;
|
|
using DTS.Common.Utilities.Logging;
|
|
|
|
namespace DTS.DASLib.Service
|
|
{
|
|
/// <summary>
|
|
/// An instance of InfoResult is populated and filled when a DASFactory object discovers a DAS.
|
|
/// It contains information about the DAS hardware as well as the coinciding modules and channels.
|
|
/// It also has some functions to help translate between different numbering systems used
|
|
/// during DAS communications, such as Module numbers, Channel numbers and DASChannel numbers.
|
|
/// </summary>
|
|
public class InfoResult : IInfoResult
|
|
{
|
|
public string MACAddress { get; set; }
|
|
/// <summary>
|
|
/// Describes one module in this DAS.
|
|
/// </summary>
|
|
public class Module : IInfoResultModule
|
|
{
|
|
/// <summary>
|
|
/// Serial number of this module
|
|
/// </summary>
|
|
public string SerialNumber { get; set; }
|
|
|
|
/// <summary>
|
|
/// Firmware version in this module
|
|
/// </summary>
|
|
public string FirmwareVersion { get; set; }
|
|
|
|
/// <summary>
|
|
/// who does this module belong to?
|
|
/// </summary>
|
|
public InfoResult OwningInfoResult { get; set; }
|
|
|
|
/// <summary>
|
|
/// The number of this Module as it would be indexed in an array of Modules.
|
|
/// </summary>
|
|
public int ModuleArrayIndex { get; set; }
|
|
|
|
/// <summary>
|
|
/// How many channels are connected to this Module.
|
|
/// </summary>
|
|
public uint NumberOfChannels { get; set; }
|
|
|
|
/// <summary>
|
|
/// What sample rates does it support (in samples per second).
|
|
/// </summary>
|
|
public uint[] SupportedSampleRates { get; set; }
|
|
|
|
/// <summary>
|
|
/// An associative list (Dictionary) of sample rates and corresponding
|
|
/// Anti-Aliasing filter frequencies.
|
|
/// </summary>
|
|
public Dictionary<uint, float> SampleRate2AAFrequency { get; set; }
|
|
|
|
/// <summary>
|
|
/// How many bytes of sample storage is available in this module? This is null
|
|
/// if it's specified per DAS instead.
|
|
/// </summary>
|
|
public UInt64? MaxEventStorageSpaceInBytes { get; set; }
|
|
|
|
/// <summary>
|
|
/// How many bytes are stored for all channels at each sample interval? This is
|
|
/// null if it's specified per DAS instead.
|
|
/// </summary>
|
|
public uint? NumberOfBytesPerSampleClock { get; set; }
|
|
|
|
/// <summary>
|
|
/// How many samples can you record in this module?
|
|
/// </summary>
|
|
public double MaxRecordingSamples { get; set; }
|
|
|
|
/// <summary>
|
|
/// The <see cref="System.DateTime"/> of this module's last calibration.
|
|
/// </summary>
|
|
public DateTime? CalibrationDate { get; set; }
|
|
|
|
/// <summary>
|
|
/// True if a TDAS rack is armed and doesn't respond to some queries.
|
|
/// </summary>
|
|
public bool RackIsUnreadable { get; set; }
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// What type of module is this?
|
|
/// </summary>
|
|
public DFConstantsAndEnums.ModuleType TypeOfModule { get; set; }
|
|
|
|
/// <summary>
|
|
/// What recording modes does this Module support.
|
|
/// </summary>
|
|
public DFConstantsAndEnums.RecordingMode[] SupportedModes { get; set; }
|
|
|
|
public bool IsProgrammable { get; set; } = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// An array of the modules in this DAS.
|
|
/// </summary>
|
|
public IInfoResultModule[] Modules { get; set; }
|
|
|
|
public List<Common.Classes.Hardware.ExternalTilt> ActiveExternalTilts { get; set; } = new List<Common.Classes.Hardware.ExternalTilt>();
|
|
|
|
[XmlIgnore]
|
|
public IDASCommunication OwningDAS { get; set; }
|
|
|
|
public uint MaxNumberOfModules { get; set; }
|
|
public InfoResult()
|
|
{
|
|
|
|
}
|
|
/// <summary>
|
|
/// How many bytes of sample storage is available in this DAS? This is null if
|
|
/// it's specified per module instead.
|
|
/// </summary>
|
|
public UInt64? MaxEventStorageSpaceInBytes { get; set; }
|
|
|
|
/// <summary>
|
|
/// How many bytes are stored for all channels at each sample interval? This is
|
|
/// null if it's specified per module instead.
|
|
/// </summary>
|
|
public uint? NumberOfBytesPerSampleClock { get; set; }
|
|
|
|
/// <summary>
|
|
/// FB15353 Is this device hardware configured for streaming only?
|
|
/// null if device doesn't support a streaming-only configuration
|
|
/// </summary>
|
|
public bool? DeviceStreamingOnly { get; set; }
|
|
|
|
// temporary constant
|
|
public int NumberOfBridgeChannels { get; set; } = 3;
|
|
|
|
/// <summary>
|
|
/// The ID of the battery.
|
|
/// </summary>
|
|
public IEID BatteryID { get; set; }
|
|
|
|
/// <summary>
|
|
/// TRUE if a battery is present in the hardware unit.
|
|
/// </summary>
|
|
public bool HasBattery
|
|
{
|
|
get
|
|
{
|
|
if (BatteryID == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (string.IsNullOrEmpty(BatteryID.ID))
|
|
{
|
|
return false;
|
|
}
|
|
if (EIDReader.IsBlankID(BatteryID.ID)) { return false; }
|
|
return true;
|
|
}
|
|
}
|
|
public byte MapDASChannelNumber2RealtimeChannelNumber(int channelNumber)
|
|
{
|
|
try
|
|
{
|
|
switch (Modules[0].TypeOfModule)
|
|
{
|
|
case DFConstantsAndEnums.ModuleType.G5Digital:
|
|
// This case is never hit because of the use of Modules.First(), but left for clarity.
|
|
return Convert.ToByte(32);
|
|
case DFConstantsAndEnums.ModuleType.G5Analog:
|
|
return (byte)channelNumber;
|
|
case DFConstantsAndEnums.ModuleType.ProDIM:
|
|
return Convert.ToByte(channelNumber);
|
|
//return MapDASChannelNumber2ModuleChannelNumber(channelNumber);
|
|
case DFConstantsAndEnums.ModuleType.ProSIM:
|
|
return Convert.ToByte(channelNumber);
|
|
//return MapDASChannelNumber2ModuleChannelNumber(channelNumber);
|
|
case DFConstantsAndEnums.ModuleType.SLICEPro_TOM:
|
|
return Convert.ToByte(channelNumber);
|
|
case DFConstantsAndEnums.ModuleType.ProTOM:
|
|
return Convert.ToByte(channelNumber);
|
|
//return MapDASChannelNumber2ModuleChannelNumber(channelNumber);
|
|
case DFConstantsAndEnums.ModuleType.RibeyeLED:
|
|
return Convert.ToByte(channelNumber);
|
|
case DFConstantsAndEnums.ModuleType.SliceARS:
|
|
return Convert.ToByte(channelNumber);
|
|
case DFConstantsAndEnums.ModuleType.SliceBridge:
|
|
return Convert.ToByte(channelNumber);
|
|
case DFConstantsAndEnums.ModuleType.SLICEIEPE:
|
|
return Convert.ToByte(channelNumber);
|
|
default:
|
|
return Convert.ToByte(channelNumber);
|
|
}
|
|
}
|
|
catch (System.Exception ex) { APILogger.Log("MapDASChannelNumber2RealtimeChannelNumber failed", ex); }
|
|
return Convert.ToByte(channelNumber);
|
|
}
|
|
/// <summary>
|
|
/// Convert a DASChannel number (0..29) to a module array index (0..9).
|
|
/// A DASChannel number is a channel's identifier global within this DAS.
|
|
/// A Module array index is a Module identifier as it would be indexed in an array.
|
|
/// </summary>
|
|
/// <param name="channelNumber">The DAS channel number to convert</param>
|
|
/// <returns>The module array index</returns>
|
|
public byte MapDASChannelNumber2ModuleArrayIndex(int channelNumber)
|
|
{
|
|
foreach (var module in Modules)
|
|
{
|
|
int numChannels = Convert.ToInt32(module.NumberOfChannels);
|
|
if (channelNumber >= numChannels) { channelNumber -= numChannels; }
|
|
else { return (byte)module.ModuleArrayIndex; }
|
|
}
|
|
return (byte)(Modules.Length - 1);
|
|
//return (byte)(channelNumber / NumberOfBridgeChannels);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a DAS channel number (0..29) to a module device id (1..10)
|
|
/// A DASChannel number is a channel's identifier global within this DAS.
|
|
/// A Module deviceID is an identifier for the corresponding channel that starts at 1 for the first Module.
|
|
/// </summary>
|
|
/// <param name="channelNumber">The DAS channel number to convert</param>
|
|
/// <returns>The module device id</returns>
|
|
public byte MapDASChannelNumber2ModuleDeviceID(int channelNumber)
|
|
{
|
|
return (byte)(channelNumber / NumberOfBridgeChannels + 1);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a DAS channel number (0..29) to a module channel number (0..2)
|
|
/// A DASChannel number is a channel's identifier global within this DAS.
|
|
/// A moduleChannel number is the channel's identifier relative only to it's parent Module.
|
|
/// </summary>
|
|
/// <param name="channelNumber">The DAS channel number to convert</param>
|
|
/// <returns>The channel number within the module</returns>
|
|
public byte MapDASChannelNumber2ModuleChannelNumber(int channelNumber)
|
|
{
|
|
if (OwningDAS is EthernetTDAS)
|
|
{
|
|
var ch = Convert.ToUInt32(channelNumber);
|
|
foreach (var m in Modules)
|
|
{
|
|
if (m.NumberOfChannels <= ch)
|
|
{
|
|
ch -= m.NumberOfChannels;
|
|
}
|
|
else
|
|
{
|
|
return (byte)ch;
|
|
}
|
|
}
|
|
}
|
|
return (byte)(channelNumber % NumberOfBridgeChannels);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a module array index (0..9) and a module channel number (0..2) to a DAS channel number (0..29)
|
|
/// A Module array index is a Module identifier as it would be indexed in an array.
|
|
/// A moduleChannel number is the channel's identifier relative only to it's parent Module.
|
|
/// A DASChannel number is a channel's identifier global within this DAS.
|
|
/// </summary>
|
|
/// <param name="moduleArrayIdx">The module array index (0..9)</param>
|
|
/// <param name="channelNumber">The module channel number (0..2)</param>
|
|
/// <returns>The DAS channel number within the DAS (0..29)</returns>
|
|
public byte MapModuleArrayIndexAndChannelNum2DASChannel(int moduleArrayIdx, int channelNumber)
|
|
{
|
|
uint channel = 0;
|
|
foreach (var module in Modules)
|
|
{
|
|
//30429 Invalidate/fail sooner than Arm step if DAS doesn't have streaming capability/channel (TSR AIR may or may not)
|
|
if (module == null) { break; }
|
|
if (module.ModuleArrayIndex < moduleArrayIdx) { channel += module.NumberOfChannels; }
|
|
else if (module.ModuleArrayIndex > moduleArrayIdx) { break; }
|
|
else
|
|
{
|
|
channel += Convert.ToUInt32(channelNumber);
|
|
break;
|
|
}
|
|
}
|
|
return (byte)(channel);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The <see cref="System.DateTime"/> returns the datetime of the DAS (or the oldest module's calibration)
|
|
/// returns 1970-01-01 is considering invalid/NA
|
|
/// </summary>
|
|
private DateTime? _calibrationDate;
|
|
public DateTime? CalibrationDate
|
|
{
|
|
get
|
|
{
|
|
var dCalDate = new DateTime(1970, 1, 1);
|
|
if (null != _calibrationDate)
|
|
{
|
|
dCalDate = (DateTime)_calibrationDate;
|
|
}
|
|
if (null != Modules)
|
|
{
|
|
foreach (var module in Modules)
|
|
{
|
|
//30429 Invalidate/fail sooner than Arm step if DAS doesn't have streaming capability/channel (TSR AIR may or may not)
|
|
if (module == null) { continue; }
|
|
if (module.SerialNumber.ToLower().Contains("empty")) { continue; }
|
|
if (null != module.CalibrationDate)
|
|
{
|
|
var mCalDate = (DateTime)module.CalibrationDate;
|
|
if (mCalDate < dCalDate || dCalDate.Year == 1970) { dCalDate = mCalDate; }
|
|
}
|
|
}
|
|
}
|
|
return dCalDate;
|
|
}
|
|
set => _calibrationDate = value;
|
|
}
|
|
|
|
public static void SetDASInfo(IDASCommunication das)
|
|
{
|
|
if (!DASFactoryDb.DbWrapper.Connected) { return; }
|
|
if (das.RecordId < 0) { return; }
|
|
|
|
try
|
|
{
|
|
Config.DASInfoClear(das.RecordId);
|
|
InsertDASInfo(das, das.DASInfo);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
}
|
|
}
|
|
public static void SetDASInfo(IDASCommunication das, IInfoResult dasInfo, bool bSetInDb = true)
|
|
{
|
|
das.DASInfo = dasInfo;
|
|
if (!bSetInDb || !DASFactoryDb.DbWrapper.Connected) { return; }
|
|
|
|
try
|
|
{
|
|
if (das.RecordId < 0)
|
|
{
|
|
das.RecordId = DASFactoryDb.DbWrapper.GetDeviceId(das.SerialNumber);
|
|
if (das.RecordId < 0)
|
|
{
|
|
var id = DASFactoryDb.DAS.DAS.InsertDASSimple(das.SerialNumber, das.FirmwareVersion,
|
|
((ICommunication)das).Transport.ConnectString);
|
|
das.RecordId = id;
|
|
}
|
|
}
|
|
|
|
Config.DASInfoClear(das.RecordId);
|
|
InsertDASInfo(das, dasInfo);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
}
|
|
}
|
|
|
|
private static void InsertDASInfo(IDASCommunication das, IInfoResult dasInfo)
|
|
{
|
|
if (!DbWrapper.Connected) { return; }
|
|
if (null != dasInfo && das.RecordId > 0)
|
|
{
|
|
var batteryId = string.Empty;
|
|
if (null != dasInfo.BatteryID)
|
|
{
|
|
batteryId = dasInfo.BatteryID.ID;
|
|
}
|
|
Config.DASInfoInsert(das.RecordId,
|
|
dasInfo.MACAddress,
|
|
das.RecordId,
|
|
dasInfo.MaxNumberOfModules,
|
|
dasInfo.MaxEventStorageSpaceInBytes,
|
|
dasInfo.NumberOfBytesPerSampleClock,
|
|
batteryId,
|
|
dasInfo.CalibrationDate);
|
|
}
|
|
}
|
|
}
|
|
}
|