Files
DP44/DataPRO/IService/Classes/InfoResult.cs
2026-04-17 14:55:32 -04:00

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);
}
}
}
}