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 { /// /// 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. /// public class InfoResult : IInfoResult { public string MACAddress { get; set; } /// /// Describes one module in this DAS. /// public class Module : IInfoResultModule { /// /// Serial number of this module /// public string SerialNumber { get; set; } /// /// Firmware version in this module /// public string FirmwareVersion { get; set; } /// /// who does this module belong to? /// public InfoResult OwningInfoResult { get; set; } /// /// The number of this Module as it would be indexed in an array of Modules. /// public int ModuleArrayIndex { get; set; } /// /// How many channels are connected to this Module. /// public uint NumberOfChannels { get; set; } /// /// What sample rates does it support (in samples per second). /// public uint[] SupportedSampleRates { get; set; } /// /// An associative list (Dictionary) of sample rates and corresponding /// Anti-Aliasing filter frequencies. /// public Dictionary SampleRate2AAFrequency { get; set; } /// /// How many bytes of sample storage is available in this module? This is null /// if it's specified per DAS instead. /// public UInt64? MaxEventStorageSpaceInBytes { get; set; } /// /// How many bytes are stored for all channels at each sample interval? This is /// null if it's specified per DAS instead. /// public uint? NumberOfBytesPerSampleClock { get; set; } /// /// How many samples can you record in this module? /// public double MaxRecordingSamples { get; set; } /// /// The of this module's last calibration. /// public DateTime? CalibrationDate { get; set; } /// /// True if a TDAS rack is armed and doesn't respond to some queries. /// public bool RackIsUnreadable { get; set; } /// /// What type of module is this? /// public DFConstantsAndEnums.ModuleType TypeOfModule { get; set; } /// /// What recording modes does this Module support. /// public DFConstantsAndEnums.RecordingMode[] SupportedModes { get; set; } public bool IsProgrammable { get; set; } = false; } /// /// An array of the modules in this DAS. /// public IInfoResultModule[] Modules { get; set; } public List ActiveExternalTilts { get; set; } = new List(); [XmlIgnore] public IDASCommunication OwningDAS { get; set; } public uint MaxNumberOfModules { get; set; } /// /// How many bytes of sample storage is available in this DAS? This is null if /// it's specified per module instead. /// public UInt64? MaxEventStorageSpaceInBytes { get; set; } /// /// How many bytes are stored for all channels at each sample interval? This is /// null if it's specified per module instead. /// public uint? NumberOfBytesPerSampleClock { get; set; } /// /// FB15353 Is this device hardware configured for streaming only? /// null if device doesn't support a streaming-only configuration /// public bool? DeviceStreamingOnly { get; set; } // temporary constant public int NumberOfBridgeChannels { get; set; } = 3; /// /// The ID of the battery. /// public IEID BatteryID { get; set; } /// /// TRUE if a battery is present in the hardware unit. /// 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); } /// /// 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. /// /// The DAS channel number to convert /// The module array index 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); } /// /// 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. /// /// The DAS channel number to convert /// The module device id public byte MapDASChannelNumber2ModuleDeviceID(int channelNumber) { return (byte)(channelNumber / NumberOfBridgeChannels + 1); } /// /// 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. /// /// The DAS channel number to convert /// The channel number within the module 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); } /// /// 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. /// /// The module array index (0..9) /// The module channel number (0..2) /// The DAS channel number within the DAS (0..29) 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); } /// /// The returns the datetime of the DAS (or the oldest module's calibration) /// returns 1970-01-01 is considering invalid/NA /// 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); } } } }