using DTS.Common.Constant.DASSpecific; using DTS.Common.Enums.DASFactory; using DTS.Common.Enums.Sensors; using DTS.Common.ICommunication; using DTS.Common.Interface.Connection; using DTS.Common.Interface.DASFactory.Config; using DTS.Common.Utilities.Logging; using DTS.DASLib.Command.SLICE; using System; using System.Collections.Generic; using System.Linq; namespace DTS.DASLib.Service { public class SLICE6AIRBR : SLICE6_Base, IAlignUDPToPPSAware where T : IConnection, new() { public bool AlignUDPToPPS { get; set; } public override bool SupportsRemoveLeapSeconds => true; public override bool SupportsADCSamplesPerPacket => true; protected override bool RequiresNon0QualificationSamples => true; protected override byte[] GetRTChannelIndices(RealTimeAsyncPacket packet) { return new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; } public override void SetIsStreamingSupported(bool supported) { IsStreamingSupported = true; } /// /// the order of this DAS among multiple das /// public int DASIndex { get; set; } = -1; public override void InitMinProto() { // SLICE 6.0 Protocol Limitations SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArm] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmRepeatEnable] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDefaultMIF] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackSensors] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.TestCommunication] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackLowPowerMode] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetRealtimeSampleRate] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.LevelTrigger] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AttributeStoreBlocks] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MaxEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmDiagnosticDelay] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackChannelAutoArmDiagLevel] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FlashClear] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleSamplesRealtime] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.DiangosShuntDAC] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageInsertion] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPTimestamp] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRecDelayInSecond] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryTiltSensorData] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InSliceTiltSensorADCPre] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRealtimeStream] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.UDPRealtimeStream] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.GenerateEvent] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPSyncStatus] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetClockSyncConfig] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDSPFilterSettings] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPDomainID] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ActiveRAM] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.RecordAndStreamSubSample] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.RemoveLeapSeconds] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.RecordOnBoot] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.UDPAlignOnPPS] = SLICE6AIRBR.UDPALIGNONPPS_PROTOCOL; SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ADCSamplesPerPacket] = SLICE6AIRBR.ADC_SAMPLES_PER_PACKET_VER; MinimumProtocols = SLICE6AIR_BR_MinimumProtocols; } #region protocol settings/overrides private readonly Dictionary SLICE6AIR_BR_MinimumProtocols = new Dictionary(); protected override int MIN_PROTOCOL_TMATS_INTERVAL => SLICE6AIRBR.MIN_PROTOCOL_VER; private uint maxSampleRateHz = 0; protected override uint MaxSampleRateHz { get { if (0 == maxSampleRateHz) { try { var qsa = new QuerySystemAttributeSLICE6(this) { Key = AttributeTypes.SystemAttributesSLICE6.MaximumSampleRate }; qsa.SyncExecute(); maxSampleRateHz = (uint)qsa.Value; } catch (Exception ex) { APILogger.Log("Error getting S6A-BR max sample rate, returning 50K"); APILogger.LogException(ex); return 50000; } } return maxSampleRateHz; } } #endregion protected override DASModule MakeConfigModuleFromInfoModule(InfoResult.Module infoModule) { //per LP: can stream, no IEPE var configModule = new DASModule(infoModule.ModuleArrayIndex, this); configModule.Channels = new DASChannel[infoModule.NumberOfChannels]; for (var i = 0; i < infoModule.NumberOfChannels; i++) { if (DFConstantsAndEnums.ModuleType.StreamOut == configModule.ModuleType()) { var streamOutChannel = new StreamOutputDASChannel(configModule, i); configModule.Channels[i] = streamOutChannel; } else { var channel = new AnalogInputDASChannel(configModule, i); channel.SupportedBridges = new SensorConstants.BridgeType[] { SensorConstants.BridgeType.FullBridge, SensorConstants.BridgeType.HalfBridge, }; configModule.Channels[i] = channel; } } return configModule; } /// /// we can probably simplify and take common items (slice6+slice1) out of this function, but for now /// it's mostly a copy of SLICE1.AsyncConfigure /// /// protected override void AsyncConfigure(object configAsyncInfo) { var info = configAsyncInfo as SliceConfigServiceAsyncInfo; SetUDPAlignOnPPS(); SetRemoveSeconds(); if ((info.StreamADCPerPacket != null) && info.StreamADCPerPacket.ContainsKey(this)) { SetADCSamplesPerPacket(info.StreamADCPerPacket[this]); } //12638 DAS does not record data in recorder mode during calibration ~ 40% of time. //for SLICE6 we call reseteventlist here, prior to configuring and NOT before arming ResetEventListPriorToConfigure(); int progressValue = 0; bool bReleased = true; if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.ProgramStackChannels)) { ReconfigureAccordingToConfig(); } PresetSampleRate(); SetVoltageRequirements(); SetPolarity(); SetArmDisableShortCheck(); try { Lock(); bReleased = false; // loop thru the modules (slices) and configure the non-UART channels var numChannels = DASInfo.Modules.Sum(mod => mod.NumberOfChannels); var numStreamingChannels = DASInfo.Modules.Sum(mod => DFConstantsAndEnums.ModuleType.StreamOut == mod.TypeOfModule ? mod.NumberOfChannels : 0); var rangeArray = new float[numChannels]; //var IsHalfBridgeArray = new bool[numChannels]; var bridgeModeArray = new byte[numChannels]; var BridgeResistanceArray = new ushort[numChannels]; var IsACCoupledArray = new bool[numChannels]; //18294 Implement Bridge AC / DC coupling(fw update dependent) var bridgeACCouplingArray = new bool[numChannels]; // level trigger values var enableLowerLevelTriggerThreshold = new bool[numChannels]; var enableUpperLevelTriggerThreshold = new bool[numChannels]; var lowerLevelTriggerThreshold = new float[numChannels]; var upperLevelTriggerThreshold = new float[numChannels]; var qualificationSamples = new int[numChannels]; var diagnosticChannels = new List(); var bModified = false; CommonConfigureWork(diagnosticChannels, qualificationSamples, ref bReleased, info, bridgeModeArray, IsACCoupledArray, BridgeResistanceArray, ref bModified, rangeArray, enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold, enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold, bridgeACCouplingArray); if (bReleased) { return; } // report progress progressValue = 5; info.Progress(progressValue); StoreConfigAttributes(info, rangeArray, ref bReleased, ref progressValue, bridgeModeArray, IsACCoupledArray, BridgeResistanceArray, enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold, enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold, qualificationSamples, numChannels, out var config, bridgeACCouplingArray, 0, numStreamingChannels); progressValue = 20; info.Progress(progressValue); RemainingConfigWork(ref progressValue, info, diagnosticChannels, config, ref bReleased, null, null, null); } catch (CanceledException) { if (!bReleased) { bReleased = true; Release(); } info.Cancel(); } catch (Exception ex) { if (!bReleased) { bReleased = true; Release(); } info.Error(ex.Message, ex); } finally { if (!bReleased) { bReleased = true; Release(); } } info.Progress(100); info.Success(); } /// /// returns true if the device is known to be streaming /// does not query device, just returns a flag if it has been set /// public override bool GetIsStreaming() { if (null == DASArmStatus) { return false; } //18852 Cannot use Stop streaming / (Dis)Auto Arm button if one or more DAS is idle //can't rely on just having received invalid mode, QATS will still have a status of realtime //when streaming, so we'll use either for now. return DASArmStatus.ReceivedInvalidModeDuringSetup || DASArmStatus.IsInRealtime; } } }