using System; using System.Collections.Generic; using DTS.Common; using DTS.DASLib.Command.SLICE; using DTS.DASLib.Command; using DTS.Common.ICommunication; using DTS.Common.WINUSBConnection; using DTS.Common.Interface.Connection; using DTS.Common.Interface.DASFactory.Diagnostics; using DTS.DASLib.Service.Classes.Diagnostics; using DTS.Common.Interface.DASFactory.ARM; using DTS.Common.Interface.DASFactory.Download; using DTS.Common.Interface.DASFactory.Config; using DTS.Common.Enums.DASFactory; using DTS.Common.Interface.DASFactory; using DTS.Common.Enums.Hardware; using DTS.Common.Utilities.Logging; using DTS.DASLib.Command.SLICE.RealtimeCommands; using System.Linq; namespace DTS.DASLib.Service { public partial class Slice : Communication, IDASCommunication, IConfigurationActions, IDiagnosticsActions, ITriggerCheckActions, IRealTimeActions, IArmActions, IDownloadActions where T : IConnection, new() { public virtual HardwareTypes GetHardwareType() { if (SerialNumber.Contains("BA5")) { return HardwareTypes.SLICE_NANO_Base; } if (SerialNumber.Contains("BA0")) { return HardwareTypes.SLICE_Micro_Base; } if (SerialNumber.StartsWith("SG5")) { return HardwareTypes.SLICE1_G5Stack; } return HardwareTypes.SLICE_Base; } public virtual int[] GetStackChannelConfigTypes() { return new int[] { 0 }; } public float InputLowVoltage { get; set; } = 7; public float InputMediumVoltage { get; set; } = 11; public float InputHighVoltage { get; set; } = 15; public float BatteryLowVoltage { get; set; } = 8; public float BatteryMediumVoltage { get; set; } = 8.5F; public float BatteryHighVoltage { get; set; } = 9; public double MinimumValidInputVoltage { get; set; } = 4; public virtual double MaximumValidInputVoltage { get; set; } = 19; public double MinimumValidBatteryVoltage { get; set; } = 4; public double MaximumValidBatteryVoltage { get; set; } = 9; #region Configuration // our public configure member public IConfigurationData ConfigData { get; set; } //FB 25526 moved from SLICE6AIR class so can be used by subtypes /// /// returns true if the device is using a stream mode (either S6A streaming or record and stream) /// /// public bool ShouldWriteStreamInfo() { if (Array.Exists(ConfigData.Modules, m => RecordingModeExtensions.IsAStreamMode(m.RecordingMode))) { return true; } return false; } #endregion #region Diagnostics // our public diagnostics member public IDiagnosticActions[] ChannelDiagnostics { get; set; } public void SetChannelDiagnosticActions(IDiagnosticActions[] actions, bool setInDb = true) { DiagnosticsActions.SetChannelDiagnosticActions(this, actions, setInDb); } public IDiagnosticResult[] ChannelDiagnosticsResults { get; set; } public void ClearChannelDiagnosticsResults(bool bClearDb = true) { DiagnosticsResultActions.ClearChannelDiagnosticsResults(this, bClearDb); } public void SetChannelDiagnosticsResults(IDiagnosticResult[] results, bool setInDb) { DiagnosticsResultActions.SetChannelDiagnosticsResults(this, results, setInDb); } public IModuleDiagnosticsResult[] ModuleDiagnosticsResults { get; set; } public IBaseInputValues BaseInput { get; set; } public IArmCheckActions ArmCheckActions { get; set; } public IArmCheckResults ArmCheckResults { get; set; } public IOptimizationValues OptimizationValues { get; set; } #endregion #region Trigger check // our public trigger check member public ITriggerCheckResult TriggerResult { get; set; } #endregion #region Real time // our public real time member public List RealtimeDASChannels { get; set; } public List TiltAxisData { get; set; } #endregion #region FlashErase public FlashEraseStatus DASFlashEraseStatus { get; set; } #endregion #region Arming public bool GetIsInArm() { if (null == DASArmStatus) { return false; } return DASArmStatus.IsArmed; } public bool GetIsInRealtime() { if (null == DASArmStatus) { return false; } return DASArmStatus.IsInRealtime; } /// /// returns true if the unit is known to be streaming /// does not query the hardware, just returns a flag if it has been set /// /// true if known to be streaming, false otherwise public virtual bool GetIsStreaming() { return false; } public void SetInArm(bool WriteToDb) { if (null == DASArmStatus) { var armStatus = new ArmStatus() { IsArmed = true }; ArmStatus.SetArmStatus(this, armStatus, WriteToDb); } else { DASArmStatus.IsArmed = true; if (WriteToDb) { SetDASArmStatus(); } } } public void SetInRealtime(bool WriteToDb, bool ExitRealtimeIfPossible) { //before we mark it as realtime, check for qats, if we have //qats it's armed, not realtime try { var qats = new QueryArmAndTriggerStatus(this); qats.SyncExecute(); if (qats.IsArmed) { SetInArm(WriteToDb); return; } } catch (Exception) { //don't bother logging. } if (ExitRealtimeIfPossible) { try { var exitRT = new EndRealtimeMode(this); exitRT.SyncExecute(); //presumably we succeeded? //should we turn off power too? I'm not sure, uncomment the following lines to turn off power... //var info = new SliceServiceAsyncInfo((ServiceCallbackData data) => { }, this); //AsyncEnterLowPowerMode(info); return; } catch (Exception ex) { APILogger.Log(ex); } } if (null == DASArmStatus) { var armStatus = new ArmStatus() { IsInRealtime = true }; ArmStatus.SetArmStatus(this, armStatus, WriteToDb); } else { DASArmStatus.IsInRealtime = true; if (WriteToDb) { SetDASArmStatus(); } } } public IArmStatusData DASArmStatus { get; set; } public void SetDASArmStatus(IArmStatusData status, bool bSetInDb) { ArmStatus.SetArmStatus(this, status, bSetInDb); } public void SetDASArmStatus() { //FB 26817 if (DASArmStatus.IsArmed) { DASArmStatus.MaxEventsPossible = GetTSRAIRMaxEventsPossible(); } ArmStatus.SetArmStatus(this, DASArmStatus, true); } //FB 26817 Only for TSR AIR Query MaxEventsPossible after Arm to get the supported max events private ushort? GetTSRAIRMaxEventsPossible() { if (this is WinUSBTsrAir || this is EthernetTsrAir) { try { //per WIKI before querying we should set to 0 first to calculate? var setMaxEventsPossible = new SetSystemAttribute(this); setMaxEventsPossible.DeviceID = 0; setMaxEventsPossible.SetValue(AttributeTypes.SystemAttributes.MaxEventsPossible, new[] { (ushort)0, (ushort)0 }, true); setMaxEventsPossible.SyncExecute(); var getMaxEventsPossible = new QuerySystemAttribute(this); getMaxEventsPossible.DeviceID = 0; getMaxEventsPossible.Key = AttributeTypes.SystemAttributes.MaxEventsPossible; getMaxEventsPossible.SyncExecute(); ushort maxEventPossible = ((ushort[])getMaxEventsPossible.Value)[1]; return maxEventPossible; } catch (Exception ex) { APILogger.Log(ex); } } return null; } public DFConstantsAndEnums.CommandStatus AutoArmStatus { get; set; } = DFConstantsAndEnums.CommandStatus.StatusNoError; #endregion #region Clock Sync public IDictionary DASClockSyncStatus { get; set; } = null; public bool ClockSyncInUTC { get; set; } = false; public ClockSyncProfile DASClockSyncProfile { get; set; } public byte PTPDomainID { get; set; } #endregion #region Downloading public virtual IDownloadRequest WhatToDownload { get; set; } public void SetWhatToDownload(IDownloadRequest request, bool bSetInDb = true) { DownloadRequest.SetWhatToDownload(this, request, bSetInDb); } public IDownloadReport EventInfo { get; set; } public void SetEventInfo(IDownloadReport eventInfo, bool bSetInDb = true) { DownloadReport.SetEventInfo(this, eventInfo, bSetInDb); } public bool[] EventDownloadedStatus { get; set; } public void SetEventDownloadStatus(bool[] status, bool storeInDb = true) { DownloadReport.SetEventDownloadStatus(this, status, storeInDb); } public Guid[] EventGuids { get; set; } public void SetEventGuids(Guid[] guids, bool storeInDb = true) { DownloadReport.SetEventGuids(this, guids, storeInDb); } public ushort[] FaultFlags { get; set; } public void SetEventFaultFlags(ushort[] flags, bool storeInDb = true) { DownloadReport.SetEventFaultFlags(this, flags, storeInDb); } uint[] IDownload.ExtendedFaultFlags1 { get; set; } uint[] IDownload.ExtendedFaultFlags2 { get; set; } uint[] IDownload.ExtendedFaultFlags3 { get; set; } uint[] IDownload.ExtendedFaultFlags4 { get; set; } void IDownload.SetExtendedFaultFlags(uint[][] flags) { DownloadExtendedFaultFunctions.SetExtendedFaultFlags(flags, this); } public byte[] ArmAttempts { get; set; } public void SetEventArmAttemps(byte[] armAttempts, bool storeInDb = true) { DownloadReport.SetEventArmAttempts(this, armAttempts, storeInDb); } #endregion #region Information public virtual bool SupportsTriggerInversion() { return true; } public virtual bool SupportsStartInversion() { return true; } public bool InvertTrigger { get; set; } public bool InvertStart { get; set; } public bool IgnoreShortedStart { get; set; } public bool IgnoreShortedTrigger { get; set; } public new IInfoResult DASInfo { get; set; } public void SetDASInfo(IInfoResult dasInfo, bool bSetInDb = true) { InfoResult.SetDASInfo(this, dasInfo, bSetInDb); } public void SetDASInfo() { InfoResult.SetDASInfo(this); } public static StaticInformation StaticDASBridgeInfo = new StaticInformation(new double[] {//1,2,4,8,10,16,20,32,40,64,80,128,160,320,640,1280 2400D/1.0, 2400D/2.0, 2400D/4.0, 2400D/8.0, 2400D/10.0, 2400D/16.0, 2400D/20.0, 2400D/32.0, 2400D/40.0, 2400D/64.0, 2400D/80.0, 2400D/128.0, 2400D/160.0, 2400D/320.0, 2400D/640.0, 2400D/1280.0 }); /// /// the breakpoints for IEPE ranges possible on S6 /// FB15462 split off S6 IEPE gain selection from S6A /// public static StaticInformation StaticDASS6EIEPEInfo = new StaticInformation(new double[] {//1,2,4,8,10,16,20,32,40,64,80,128,160,320,640,1280 2400D/(1.0/6), 2400D/(2.0/6), 2400D/(4.0/6), 2400D/(8.0/6), 2400D/(10.0/6), 2400D/(16.0/6), 2400D/(20.0/6), 2400D/(32.0/6), 2400D/(40.0/6), 2400D/(64.0/6), 2400D/(80.0/6), 2400D/(128.0/6), 2400D/(160.0/6), 2400D/(320.0/6), 2400D/(640.0/6), 2400D/(1280.0/6) }); /// /// the breakpoints for IEPE ranges possible on S6A /// 14558 IEPE gain selection limited to gain 1 and 10 in DataPRO for SLICE6 AIR /// 15462 Limit SLICE 6 AIR gains as they are not functional with IEPE accel /// public static StaticInformation StaticDASS6AEIEPEInfo = new StaticInformation(new double[] {//1,2,4,8,10,16,20,32,40,64,80,128,160,320,640,1280 2400D/(1.0/6), //G1 2400D/(2.0/6), //G2 2400D/(4.0/6), //G3 2400D/(8.0/6), //G4 2400D/(10.0/6),//G5 - 1440 2400D/(16.0/6),//G6 - 900 2400D/(20.0/6),//G7 - 720 2400D/(32.0/6),//G8 - 450 2400D/(40.0/6),//G9 - 360 2400D/(64.0/6),//G10 - 225 2400D/(80.0/6),//G11 - 180 2400D/(128.0/6),//G12 - 112.5 2400D/(160.0/6),//G13 - 90 2400D/(320.0/6),//G14 - 45 2400D/(640.0/6),//G15 - 22.5 2400D/(1280.0/6)//G16 - 11.25 }); public enum GainCodesSLICE6IEPE //Used by Slice PRO Gen3 { [MaxInputRange(14400D)] [MinInputRange(7200D)] [FirmwareInputRange(10800D)] G1, [MaxInputRange(7200D)] [MinInputRange(3600D)] [FirmwareInputRange(5400D)] G2, [MaxInputRange(3600D)] [MinInputRange(1800D)] [FirmwareInputRange(2700)] G3, [MaxInputRange(1800D)] [MinInputRange(1440)] [FirmwareInputRange(1620)] G4, [MaxInputRange(1440D)] [MinInputRange(900D)] [FirmwareInputRange(1170D)] G5, [MaxInputRange(900D)] [MinInputRange(720D)] [FirmwareInputRange(810D)] G6, [MaxInputRange(720D)] [MinInputRange(450D)] [FirmwareInputRange(585)] G7, [GainDisabled(true)] [MaxInputRange(450D)] [MinInputRange(360D)] [FirmwareInputRange(405)] G8, [MaxInputRange(360D)] [MinInputRange(225D)] [FirmwareInputRange(292.5)] G9, [GainDisabled(true)] [MaxInputRange(225D)] [MinInputRange(180D)] [FirmwareInputRange(202.5)] G10, [MaxInputRange(180)] [MinInputRange(112.5)] [FirmwareInputRange(146.25)] G11, [GainDisabled(true)] [MaxInputRange(112.5)] [MinInputRange(90)] [FirmwareInputRange(101.25)] G12, [MaxInputRange(90)] [MinInputRange(45)] [FirmwareInputRange(67.5)] G13, [MaxInputRange(45)] [MinInputRange(22.5)] [FirmwareInputRange(33.75)] G14, [GainDisabled(true)] [MaxInputRange(22.5)] [MinInputRange(11.25)] [FirmwareInputRange(16.875)] G15, [GainDisabled(true)] [MaxInputRange(11.25)] [MinInputRange(0)] [FirmwareInputRange(5.625)] G16 }; //0.2040816327F, 2.0408163265F public static StaticInformation StaticDASIEPEInfo = new StaticInformation(new double[] { 2400D/.2040816327D, 2400D/2.0408163265D }); #endregion #region Firmware Utility public string FWUtilSerialNumber { get; set; } public Dictionary SystemAttributes { get; set; } public Dictionary UserAttributes { get; set; } public Dictionary ArmAttributes { get; set; } public Dictionary EventAttributes { get; set; } public ushort EventAttributeEventNumber { get; set; } #endregion //I'm guessing hiding was not intended, this member hides an inherited member (from ICommunication) //public string SerialNumber { get; set; } public override string ToString() { var sn = SerialNumber; if (!string.IsNullOrEmpty(sn)) return sn; return "Unknown DAS"; } public virtual int NumberOfConfiguredChannels() { if (ConfigData == null) return 0; return ConfigData.NumberOfConfiguredChannels(); } public virtual int NumberOfChannels() { if (ConfigData == null) return 0; return ConfigData.NumberOfChannels(); } public virtual int NumberOfDownloadChannels() { if (ConfigData == null) return 0; return ConfigData.NumberOfDownloadChannels(); } public int CompareTo(IDASCommunication das) { if (das == null || string.IsNullOrEmpty(das.SerialNumber) || string.IsNullOrEmpty(SerialNumber)) return 0; return SerialNumber.CompareTo(das.SerialNumber); } public virtual bool DiagnosticsHasBeenRun { get; set; } private bool _configureHasBeenRun = false; public virtual bool ConfigureHasBeenRun { get => _configureHasBeenRun; set { if (!value && null != ConfigData) { ConfigData.ClearSetup = true; } _configureHasBeenRun = value; } } } #region Sub classes used for identification public class WinUSBSlice : Slice { public WinUSBSlice() { _bSupportsMultipleSampleRealtime = true; } } public class CDCUSBSlice : SLICE2 { public CDCUSBSlice() { _bSupportsMultipleSampleRealtime = false; } } public class WinUSBSlice1_5 : SLICE1_5 { public WinUSBSlice1_5() { _bSupportsMultipleSampleRealtime = false; } } public class WinUSBSlice6 : SLICE6 { public WinUSBSlice6() { _bSupportsMultipleSampleRealtime = false; } } public class WinUSBSlice6Air : SLICE6AIR { public WinUSBSlice6Air() { _bSupportsMultipleSampleRealtime = false; } } public class WinUSBSlice6AirBridge : SLICE6AIRBR { public WinUSBSlice6AirBridge() { _bSupportsMultipleSampleRealtime = false; } } public class WinUSBTsrAir : TSRAIR { public override HardwareTypes GetHardwareType() { if (UNKNOWN_REVISION == _hardwareRevision) QueryHardwareRevision(); switch (_hardwareRevision) { case (int)TSR_AIR_HW_REVISION.DIR: return HardwareTypes.DIR; case (int)TSR_AIR_HW_REVISION.DKR: return HardwareTypes.DKR; default: return HardwareTypes.UNDEFINED; } } public WinUSBTsrAir() { _bSupportsMultipleSampleRealtime = false; // no network time sync TSRAIR_MinimumProtocols.Remove(DFConstantsAndEnums.ProtocolLimitedCommands.PTPSyncStatus); TSRAIR_MinimumProtocols.Remove(DFConstantsAndEnums.ProtocolLimitedCommands.PTPTimestamp); _haveInited = true; } } public class WinUSBSlice6AirThermocoupler : SLICE6AIRTC { public WinUSBSlice6AirThermocoupler() { _bSupportsMultipleSampleRealtime = false; } } public class EthernetSlice : Slice { public EthernetSlice() { _bSupportsMultipleSampleRealtime = true; } } public class EthernetSlice2 : SLICE2 { public EthernetSlice2() { _bSupportsMultipleSampleRealtime = false; } } public class EthernetSlice6 : SLICE6 { public override HardwareTypes GetHardwareType() { return HardwareTypes.SLICE6_Base; } public EthernetSlice6() { _bSupportsMultipleSampleRealtime = false; ((EthernetConnection)Transport).RequiresKeepAliveReset = true; } } public class EthernetSlice6Air : SLICE6AIR { public override HardwareTypes GetHardwareType() { return IsEthernetRecorder ? HardwareTypes.S6A_EthernetRecorder : HardwareTypes.SLICE6_AIR; } public EthernetSlice6Air() { _bSupportsMultipleSampleRealtime = false; ((EthernetConnection)Transport).RequiresKeepAliveReset = true; } } public class EthernetSlice6AirBridge : SLICE6AIRBR { public override HardwareTypes GetHardwareType() { return HardwareTypes.SLICE6_AIR_BR; } public EthernetSlice6AirBridge() { _bSupportsMultipleSampleRealtime = false; ((EthernetConnection)Transport).RequiresKeepAliveReset = true; } } public class EthernetSlice6DB : SLICE6DB { public override HardwareTypes GetHardwareType() { switch (S6DBMode) { case S6DBModes.INDUMMY: return HardwareTypes.SLICE6DB_InDummy; //case S6DBModes.AIR: // return HardwareTypes.SLICE6DB_AIR; default: return HardwareTypes.SLICE6DB; } } public EthernetSlice6DB() { _bSupportsMultipleSampleRealtime = false; } } public class EthernetPowerPro : PowerPro { public override HardwareTypes GetHardwareType() { return HardwareTypes.PowerPro; } public EthernetPowerPro() { _bSupportsMultipleSampleRealtime = false; } } public class EthernetTsrAir : TSRAIR { public override HardwareTypes GetHardwareType() { if (UNKNOWN_REVISION == _hardwareRevision) QueryHardwareRevision(); switch (_hardwareRevision) { case (int)TSR_AIR_HW_REVISION.REV_A: return HardwareTypes.TSR_AIR; case (int)TSR_AIR_HW_REVISION.REV_B: return HardwareTypes.TSR_AIR_RevB; default: return HardwareTypes.UNDEFINED; } } public EthernetTsrAir() { _bSupportsMultipleSampleRealtime = false; ((EthernetConnection)Transport).RequiresKeepAliveReset = true; } } public class EthernetSlice6DB3 : SLICE6DB { public override HardwareTypes GetHardwareType() { return HardwareTypes.SLICE6DB3; } public EthernetSlice6DB3() { _bSupportsMultipleSampleRealtime = false; } } public class EthernetSlicePRODB : SLICEPRODB { public override HardwareTypes GetHardwareType() { return HardwareTypes.SLICE_Pro_Distributor; } public EthernetSlicePRODB() { _bSupportsMultipleSampleRealtime = false; } } public class EthernetSlice1_5 : SLICE1_5 { public EthernetSlice1_5() { _bSupportsMultipleSampleRealtime = false; } } public class EthernetSliceDB : SliceDB { public bool SupportsDiagnostics => IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics); public EthernetSliceDB() { } public override string ToString() { if (!string.IsNullOrEmpty(SerialNumber)) { return SerialNumber; } else return base.ToString(); } } public class EthernetSlice6AirThermocoupler : SLICE6AIRTC { public override HardwareTypes GetHardwareType() { return HardwareTypes.SLICE6_AIR_TC; } public EthernetSlice6AirThermocoupler() { _bSupportsMultipleSampleRealtime = false; ((EthernetConnection)Transport).RequiresKeepAliveReset = true; } } #endregion }