This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,807 @@
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<T> : Communication<T>,
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
/// <summary>
/// returns true if the device is using a stream mode (either S6A streaming or record and stream)
/// </summary>
/// <returns></returns>
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<int> RealtimeDASChannels { get; set; }
public List<double> 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;
}
/// <summary>
/// returns true if the unit is known to be streaming
/// does not query the hardware, just returns a flag if it has been set
/// </summary>
/// <returns>true if known to be streaming, false otherwise</returns>
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<InputClockSource, bool> 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
});
/// <summary>
/// the breakpoints for IEPE ranges possible on S6
/// FB15462 split off S6 IEPE gain selection from S6A
/// </summary>
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)
});
/// <summary>
/// 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
/// </summary>
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<ushort, object> SystemAttributes { get; set; }
public Dictionary<ushort, object> UserAttributes { get; set; }
public Dictionary<ushort, object> ArmAttributes { get; set; }
public Dictionary<ushort, object> 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<WINUSBConnection>
{
public WinUSBSlice()
{
_bSupportsMultipleSampleRealtime = true;
}
}
public class CDCUSBSlice : SLICE2<WINUSBConnection>
{
public CDCUSBSlice()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class WinUSBSlice1_5 : SLICE1_5<WINUSBConnection>
{
public WinUSBSlice1_5()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class WinUSBSlice6 : SLICE6<WINUSBConnection>
{
public WinUSBSlice6()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class WinUSBSlice6Air : SLICE6AIR<WINUSBConnection>
{
public WinUSBSlice6Air()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class WinUSBSlice6AirBridge : SLICE6AIRBR<WINUSBConnection>
{
public WinUSBSlice6AirBridge()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class WinUSBTsrAir : TSRAIR<WINUSBConnection>
{
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<WINUSBConnection>
{
public WinUSBSlice6AirThermocoupler()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class EthernetSlice : Slice<EthernetConnection>
{
public EthernetSlice()
{
_bSupportsMultipleSampleRealtime = true;
}
}
public class EthernetSlice2 : SLICE2<EthernetConnection>
{
public EthernetSlice2()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class EthernetSlice6 : SLICE6<EthernetConnection>
{
public override HardwareTypes GetHardwareType()
{
return HardwareTypes.SLICE6_Base;
}
public EthernetSlice6()
{
_bSupportsMultipleSampleRealtime = false;
((EthernetConnection)Transport).RequiresKeepAliveReset = true;
}
}
public class EthernetSlice6Air : SLICE6AIR<EthernetConnection>
{
public override HardwareTypes GetHardwareType()
{
return IsEthernetRecorder ? HardwareTypes.S6A_EthernetRecorder : HardwareTypes.SLICE6_AIR;
}
public EthernetSlice6Air()
{
_bSupportsMultipleSampleRealtime = false;
((EthernetConnection)Transport).RequiresKeepAliveReset = true;
}
}
public class EthernetSlice6AirBridge : SLICE6AIRBR<EthernetConnection>
{
public override HardwareTypes GetHardwareType()
{
return HardwareTypes.SLICE6_AIR_BR;
}
public EthernetSlice6AirBridge()
{
_bSupportsMultipleSampleRealtime = false;
((EthernetConnection)Transport).RequiresKeepAliveReset = true;
}
}
public class EthernetSlice6DB : SLICE6DB<EthernetConnection>
{
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<EthernetConnection>
{
public override HardwareTypes GetHardwareType()
{
return HardwareTypes.PowerPro;
}
public EthernetPowerPro()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class EthernetTsrAir : TSRAIR<EthernetConnection>
{
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<EthernetConnection>
{
public override HardwareTypes GetHardwareType()
{
return HardwareTypes.SLICE6DB3;
}
public EthernetSlice6DB3()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class EthernetSlicePRODB : SLICEPRODB<EthernetConnection>
{
public override HardwareTypes GetHardwareType()
{
return HardwareTypes.SLICE_Pro_Distributor;
}
public EthernetSlicePRODB()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class EthernetSlice1_5 : SLICE1_5<EthernetConnection>
{
public EthernetSlice1_5()
{
_bSupportsMultipleSampleRealtime = false;
}
}
public class EthernetSliceDB : SliceDB<EthernetConnection>
{
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<EthernetConnection>
{
public override HardwareTypes GetHardwareType()
{
return HardwareTypes.SLICE6_AIR_TC;
}
public EthernetSlice6AirThermocoupler()
{
_bSupportsMultipleSampleRealtime = false;
((EthernetConnection)Transport).RequiresKeepAliveReset = true;
}
}
#endregion
}

View File

@@ -0,0 +1,923 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using DTS.Common.ICommunication;
using DTS.DASLib.Command.SLICE;
using DTS.Common.Utilities.Logging;
using DTS.DASLib.Command;
using DTS.DASLib.Command.SLICE.RealtimeCommands;
using DTS.Common.Interface.Connection;
using DTS.Common.Enums.DASFactory;
using DTS.Common.Interface.DASFactory;
using System.Threading.Tasks;
using DTS.Common.Enums;
using DTS.Common.Classes.DASFactory;
namespace DTS.DASLib.Service
{
public partial class Slice<T> : Communication<T>,
IDASCommunication,
IConfigurationActions,
IDiagnosticsActions,
ITriggerCheckActions,
IRealTimeActions,
IArmActions,
IDownloadActions where T : IConnection, new()
{
#region Real time
public virtual bool ControlsDAQ() { return true; }
public virtual bool SupportsRealtime()
{
return !IsTOM();
}
public virtual bool SupportsMultipleEvents() { return IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents); }
public virtual bool SupportsMultipleConfigurations() { return IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MultipleConfigurations); }
public virtual bool SupportsAutoArm() { return IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.AutoArm); }
public virtual bool SupportsLevelTrigger() { return IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.LevelTrigger); }
public bool SupportsHardwareInputCheck() { return IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines); }
protected bool _bSupportsMultipleSampleRealtime = true;
public bool SupportsMultipleSampleRealtime() { return _bSupportsMultipleSampleRealtime; }
protected class RealTimeAsyncPacket
{
public SliceServiceAsyncInfo Info { get; set; }
public Timer Timer { get; set; }
public int SamplesPerSecond { get; set; }
public int MillisecBetweenSamples { get; set; }
public bool AllowMultipleSampleRealtime { get; set; }
public ManualResetEvent StopEvent { get; set; }
public byte[] Channels { get; set; }
public double AAF { get; set; }
public int minCallbackUpdateTimeMs { get; set; }
public bool UseUDPStreaming { get; set; } = false;
public int StreamPortOffset { get; set; }
public string HostIPAddress { get; set; } = IPAddress.Any.ToString();
}
protected class RealTimeTiltAsyncPacket
{
public SliceServiceAsyncInfo Info { get; set; }
public double[] TiltInDegrees { get; set; }
public ManualResetEvent StopEvent { get; set; }
}
// FB15313: Add UDP streaming options
protected class RealTimeUDPStreamProfileAsyncPacket
{
public SliceServiceAsyncInfo Info { get; set; }
public UDPStreamProfile Profile { get; set; }
public string UDPAddress { get; set; }
public ushort TimeDataChannelId { get; set; }
public uint[] TMNSConfig { get; set; }
public ushort DataChannelId { get; set; }
public ushort IRIGTimeDataPacketIntervalMs { get; set; }
}
void IRealTimeActions.RealTime(int samplesPerSecond,
int millisecBetweenSamples,
ServiceCallback callback,
object userData,
bool allowMultipleSampleRealtime,
int moduleIndex,
ManualResetEvent stopEvent,
byte[] channels,
double aaf,
int minCallbackUpdateTimeMs,
bool UseUDPStreaming,
string hostIPAddress)
{
var packet = new RealTimeAsyncPacket();
packet.StopEvent = stopEvent;
packet.Info = new SliceServiceAsyncInfo(callback, userData);
packet.MillisecBetweenSamples = millisecBetweenSamples;
packet.SamplesPerSecond = samplesPerSecond;
packet.AllowMultipleSampleRealtime = allowMultipleSampleRealtime;
packet.Channels = channels;
packet.AAF = aaf;
packet.minCallbackUpdateTimeMs = minCallbackUpdateTimeMs;
packet.UseUDPStreaming = UseUDPStreaming;
packet.StreamPortOffset = moduleIndex; // FB15388: udp ports must be unique, start index-0 unit at the default and iterate offset from there
packet.HostIPAddress = hostIPAddress;
LaunchAsyncWorker("Slice.RealTime", AsyncRealTime, packet);
}
void IRealTimeActions.RealTimePolling(ServiceCallback callback,
object userData,
ManualResetEvent stopEvent,
byte[] channels)
{
var packet = new RealTimeAsyncPacket
{
StopEvent = stopEvent,
Info = new SliceServiceAsyncInfo(callback, userData),
Channels = channels
};
LaunchAsyncWorker("Slice.RealtimePolling", AsyncRealTimePolling, packet);
}
/// <summary>
/// returns an object implementing IGetRealtimeSamples capable of returning realtime samples
/// </summary>
/// <param name="iCommunication"></param>
/// <param name="bPolling">whether realtime is polling or not</param>
/// <returns></returns>
protected virtual IGetRealtimeSamples GetRealtimeSamplesClass(DTS.Common.Interface.DASFactory.ICommunication iCommunication, bool bPolling = false)
{
return new GetRealtimeSamples(iCommunication, 2000, bPolling);
}
/// <summary>
/// indicates whether the DAS supports streaming
/// 10572 implement SW side for single command streaming realtime
/// </summary>
public virtual bool SupportsIndividualChannelRealtimeStreaming => false;
/// <summary>
/// indicates whether the das supports udp streaming
/// 15160 Port UDP Realtime Stream from FWTU
/// </summary>
public virtual bool SupportsUDPRealtimeStreaming => false;
/// <summary>
/// depending on firmware, some devices will send back all channels even if you request less while others will send back what's requested.
/// DataPRO is always expecting all channels to be returned. fix for these models is to always request all
/// 31829 Datapro s6air br shows noise in realtime view chart that is not real noise and does not show up in fwtu realtime or recorded
/// </summary>
/// <param name="packet"></param>
/// <returns></returns>
protected virtual byte[] GetRTChannelIndices(RealTimeAsyncPacket packet)
{
return packet.Channels;
}
/// <summary>
/// this is the minimum of time between data callbacks for realtime
/// this should be moved to the settings file, but it is fine here
/// for now since there is the ms between samples setting and
/// only the g8 and older firmware need to request samples at a fast rate
/// </summary>
//protected const int MIN_CALLBACK_UPDATE_TIME = 20;
private void AsyncRealTime(object asyncInfo)
{
var packet = asyncInfo as RealTimeAsyncPacket;
try
{
var ssaPolarity = new SetSystemAttribute(this, AbstractCommandBase.Default_IO_Timeout);
ssaPolarity.SetValue(AttributeTypes.SystemAttributes.TriggerPolarity, (byte)(InvertTrigger ? 1 : 0), true);
ssaPolarity.SyncExecute();
ssaPolarity = new SetSystemAttribute(this, AbstractCommandBase.Default_IO_Timeout);
ssaPolarity.SetValue(AttributeTypes.SystemAttributes.StartRecordPolarity, (byte)(InvertStart ? 1 : 0), true);
ssaPolarity.SyncExecute();
// Set sample rate and adjustable anti-alias filter frequency in the
// hardware based on the milliseconds between samples parameter that
// was passed in via the RealTimeAsyncPacket object. Keep the filter
// -3dB point at 1/5 the frequency of the sample rate.
// number of samples per second
var rtSampleRate = Convert.ToUInt32(packet.SamplesPerSecond);
var uiMillisecondsBetweenSamples = packet.MillisecBetweenSamples;
var setSampleRate = new SetRealtimeSampleRate(this);
setSampleRate.SetValue(rtSampleRate);
setSampleRate.SyncExecute();
var lastUpdate = DateTime.MinValue;
StreamReaderUDP streamReader = null;
if (SupportsIndividualChannelRealtimeStreaming)
{
try
{
var saa = new SetArmAttribute(this);
saa.SetValue(AttributeTypes.ArmAndEventAttributes.RealtimeAAFilterFrequencyHz,
Convert.ToSingle(packet.AAF), true);
saa.SyncExecute();
if (packet.UseUDPStreaming && SupportsUDPRealtimeStreaming)
{
//FB 18152 find the host ip
string dasIp;
string hostIpAddress = "";
if (Common.Utils.NetworkUtils.TryParseConnectionString(ConnectString, out dasIp))
{
hostIpAddress = Common.Utils.PingUtils.DasToHost[dasIp].HostIpAddress;
}
else
{ // We should not get here since SupportsUDPRealtimeStreaming is false for USB devices but just in case have a guard
APILogger.Log("Streaming realtime with UDP is not supported for USB devices.");
return;
}
var udpAddress = new UriBuilder(DFConstantsAndEnums.RealtimeUDPAddress);
udpAddress.Port += packet.StreamPortOffset;
streamReader = new StreamReaderUDP(udpAddress.Uri.AbsoluteUri, hostIpAddress, UDPStreamProfile.DTS_UDP, packet.Channels);
var startTimeStampRealtime = new StartTimeStampStreamMode(this);
startTimeStampRealtime.ParamsToSend = streamReader.cmdline.ToArray();
startTimeStampRealtime.SyncExecute();
}
else
{
var startRT = new StartRealtimeStreamingMode(this, GetRTChannelIndices(packet));
startRT.SyncExecute();
}
}
catch (Exception ex)
{
APILogger.Log(ex);
}
}
else
{
var startRT = new StartRealtimeMode(this);
startRT.SupportsMultipleSampleRealtime =
packet.AllowMultipleSampleRealtime && SupportsMultipleSampleRealtime();
startRT.SyncExecute();
}
var sampleNumbers = new List<ulong>(100);
var timeStamps = new List<ulong>(100);
var sequenceNumbers = new List<ulong>(100);
var data = new List<short[][]>(100);
// start calling for RT data
var getRTdata = GetRealtimeSamplesClass(this);
getRTdata.LogCommands = false;
var numChannels = 0;
foreach (var mod in DASInfo.Modules)
{
switch (mod.TypeOfModule)
{
case DFConstantsAndEnums.ModuleType.EmbeddedMicrophone:
case DFConstantsAndEnums.ModuleType.EmbeddedMagnetometer:
case DFConstantsAndEnums.ModuleType.EmbeddedMagnetInput:
case DFConstantsAndEnums.ModuleType.UART:
case DFConstantsAndEnums.ModuleType.StreamOut:
case DFConstantsAndEnums.ModuleType.StreamIn:
continue;
default:
numChannels += (int)mod.NumberOfChannels;
break;
}
}
getRTdata.Channels = (ushort)numChannels;
if (SerialNumber.StartsWith("SPD") || SerialNumber.StartsWith("SLD"))
{
if (getRTdata is RealtimeStreamingNextSamples cmd)
{
cmd.DigitalInput = true;
var transitions = new List<bool>();
foreach (var mod in ConfigData.Modules)
{
foreach (var channel in mod.Channels)
{
var aic = (AnalogInputDASChannel)channel;
switch (aic.DigitalMode)
{
case DigitalInputModes.CCNC:
case DigitalInputModes.CCNO:
transitions.Add(false);
break;
case DigitalInputModes.THL:
case DigitalInputModes.TLH:
transitions.Add(true);
break;
}
}
}
cmd.TransitionMode = transitions.ToArray();
}
}
while (!packet.StopEvent.WaitOne(0, false))
{
if (null != streamReader)
{
try
{
var udpPacket = streamReader.Read();
if (null != udpPacket)
{
data.Add(udpPacket.ChannelData);
sampleNumbers.Add(udpPacket.SampleNumber);
timeStamps.Add( /*Convert.ToUInt64(udpPacket.TimeStamp)*/0);
sequenceNumbers.Add(udpPacket.SequenceNumber);
var newData = new NewDataData(data.ToArray(), sampleNumbers.ToArray(),
timeStamps.ToArray(),
sequenceNumbers.ToArray());
Task.Run(() => { packet.Info.NewData(newData); });
sampleNumbers.Clear();
timeStamps.Clear();
sequenceNumbers.Clear();
data.Clear();
}
}
catch (SocketException sox) //FB15531: Don't silently consume realtime errors
{
//if it's a timeout it could just be that there's no data yet,
//give the device a chance to send data
if (sox.SocketErrorCode != SocketError.TimedOut)
{
throw sox;
}
}
catch (CommandException ce)
{
if (ce.Error == CommandErrorReason.ReceiveFailed ||
ce.Error == CommandErrorReason.SendFailed)
{
packet.Info.Error(ce.Message, new Common.Classes.Connection.NotConnectedException(ce.Message));
return;
}
//15909 Crash in Realtime when connection is lost
//in the case of a communication error in start realtime, notify consumer
packet.Info.Error(ce.Message, ce);
return;
}
catch (Common.Classes.Connection.NotConnectedException nce)
{
//15909 Crash in Realtime when connection is lost
//in the case of a communication error in start realtime, notify consumer
packet.Info.Error(nce.Message, nce);
return;
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
}
else
{
// call HW to get RT samples
try
{
getRTdata.SyncExecute();
}
catch (CommandException ce)
{
if (ce.Error == CommandErrorReason.ReceiveFailed ||
ce.Error == CommandErrorReason.SendFailed)
{
packet.Info.Error(ce.Message, new Common.Classes.Connection.NotConnectedException(ce.Message));
return;
}
//15909 Crash in Realtime when connection is lost
//in the case of a communication error in start realtime, notify consumer
packet.Info.Error(ce.Message, ce);
return;
}
catch (Common.Classes.Connection.NotConnectedException nce)
{
//15909 Crash in Realtime when connection is lost
//in the case of a communication error in start realtime, notify consumer
packet.Info.Error(nce.Message, nce);
return;
}
catch (Exception ex)
{
APILogger.Log(ex);
}
if (getRTdata.SamplesReturned > 0)
{
var rtData = new short[getRTdata.Channels][];
for (int idx = 0; idx < getRTdata.Channels; idx++)
{
rtData[idx] = getRTdata.GetChannelData(idx);
}
sampleNumbers.Add(getRTdata.SampleNumber);
timeStamps.Add(getRTdata.TimeStamp);
sequenceNumbers.Add(getRTdata.SequenceNumber);
data.Add(rtData);
}
if (DateTime.Now.Subtract(lastUpdate).TotalMilliseconds >= packet.minCallbackUpdateTimeMs)
{
lastUpdate = DateTime.Now;
if (!IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.StartRealtimeStream))
{
var ihl =
new InitializeHardwareLines(this, AbstractCommandBase.Default_IO_Timeout);
ihl.LogCommands = false;
try
{
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands
.InitHardwareInputLines) &&
!packet.StopEvent.WaitOne(0, false))
{
ihl.SyncExecute();
}
}
catch (Exception)
{
} //TODO: Where is an Exception?
var d1 = new short[1][];
d1[0] = new short[2];
d1[0][0] = (short)(ihl.StartRecordShorted ? 1 : 0);
d1[0][1] = (short)(ihl.TriggerInputShorted ? 1 : 0);
data.Add(d1);
sampleNumbers.Add(ulong.MaxValue);
timeStamps.Add(ulong.MinValue);
sequenceNumbers.Add(ulong.MinValue);
}
else
{
//Thread.Sleep(50);
}
ThreadPool.QueueUserWorkItem(packet.Info.NewData,
new NewDataData(data.ToArray(), sampleNumbers.ToArray(), timeStamps.ToArray(),
sequenceNumbers.ToArray()));
sampleNumbers.Clear();
timeStamps.Clear();
sequenceNumbers.Clear();
data.Clear();
}
}
Thread.Sleep(uiMillisecondsBetweenSamples);
}
var endRealtime = new EndRealtimeMode(this);
endRealtime.SyncExecute();
packet.Info.Success();
}
catch (CanceledException)
{
packet.Info.Cancel();
}
catch (Exception ex)
{
packet.Info.Error(ex.Message, ex);
}
}
private void AsyncRealTimePolling(object asyncInfo)
{
var packet = asyncInfo as RealTimeAsyncPacket;
try
{
var ssaPolarity = new SetSystemAttribute(this, AbstractCommandBase.Default_IO_Timeout);
ssaPolarity.SetValue(AttributeTypes.SystemAttributes.TriggerPolarity, (byte)(InvertTrigger ? 1 : 0), true);
ssaPolarity.SyncExecute();
ssaPolarity = new SetSystemAttribute(this, AbstractCommandBase.Default_IO_Timeout);
ssaPolarity.SetValue(AttributeTypes.SystemAttributes.StartRecordPolarity, (byte)(InvertStart ? 1 : 0), true);
ssaPolarity.SyncExecute();
// Set sample rate and adjustable anti-alias filter frequency in the
// hardware based on the milliseconds between samples parameter that
// was passed in via the RealTimeAsyncPacket object. Keep the filter
// -3dB point at 1/5 the frequency of the sample rate.
// number of samples per second
var rtSampleRate = Convert.ToUInt32(50);
const int uiMillisecondsBetweenSamples = 200;
var setSampleRate = new SetRealtimeSampleRate(this);
setSampleRate.SetValue(rtSampleRate);
setSampleRate.SyncExecute();
DateTime lastUpdate = DateTime.MinValue;
// set RT mode in HW
var startRT = new StartRealtimeMode(this);
startRT.SupportsMultipleSampleRealtime = true;
startRT.SyncExecute();
var sampleNumbers = new List<ulong>(100);
var timeStamps = new List<ulong>(100);
var sequenceNumbers = new List<ulong>(100);
var data = new List<short[][]>(100);
// start calling for RT data
var getRTdata = GetRealtimeSamplesClass(this, true);
getRTdata.LogCommands = false;
getRTdata.Channels = (ushort)DASInfo.Modules.Sum(m => m.NumberOfChannels);
while (!packet.StopEvent.WaitOne(0, false))
{
// call HW to get RT samples
try
{
getRTdata.SyncExecute();
}
catch (Exception ex) { APILogger.Log(ex); }
if (getRTdata.SamplesReturned > 0)
{
var rtData = new short[getRTdata.Channels][];
for (var idx = 0; idx < getRTdata.Channels; idx++)
{
rtData[idx] = getRTdata.GetChannelData(idx);
}
sampleNumbers.Add(getRTdata.SampleNumber);
timeStamps.Add(getRTdata.TimeStamp);
sequenceNumbers.Add(getRTdata.SequenceNumber);
data.Add(rtData);
}
if (DateTime.Now.Subtract(lastUpdate).TotalMilliseconds >= packet.minCallbackUpdateTimeMs)
{
lastUpdate = DateTime.Now;
var ihl = new InitializeHardwareLines(this, AbstractCommandBase.Default_IO_Timeout);
ihl.LogCommands = false;
try
{
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines) && !packet.StopEvent.WaitOne(0, false))
{
ihl.SyncExecute();
}
}
catch (Exception ex) { APILogger.Log(ex); }
if (Common.Constants.CheckStatusLinesInRealtime)
{
var d1 = new short[1][];
d1[0] = new short[2];
d1[0][0] = (short)(ihl.StartRecordShorted ? 1 : 0);
d1[0][1] = (short)(ihl.TriggerInputShorted ? 1 : 0);
data.Add(d1);
sampleNumbers.Add(ulong.MaxValue);
}
//15244 Cannot run meter mode in realtime
timeStamps.Add(ulong.MinValue);
ThreadPool.QueueUserWorkItem(packet.Info.NewData, new NewDataData(data.ToArray(), sampleNumbers.ToArray(), timeStamps.ToArray(), sequenceNumbers.ToArray()));
sampleNumbers.Clear();
timeStamps.Clear();
sequenceNumbers.Clear();
data.Clear();
}
Thread.Sleep(uiMillisecondsBetweenSamples);
}
var exitRT = new EndRealtimeMode(this);
exitRT.SyncExecute();
packet.Info.Success();
}
catch (CanceledException)
{
packet.Info.Cancel();
}
catch (Exception ex)
{
packet.Info.Error(ex.Message, ex);
}
}
void IRealTimeActions.ExitRealTimeMode(ServiceCallback callback, object userData)
{
var info = new SliceServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Slice.ExitRealTimeMode", new WaitCallback(AsyncExitRealTimeMode), info);
}
private void AsyncExitRealTimeMode(object asyncInfo)
{
var info = asyncInfo as SliceServiceAsyncInfo;
if (!SupportsRealtime())
{
if (null != DASArmStatus) DASArmStatus.IsInRealtime = false;// FB15550: Update IsInRealtime flag if we exit RT so DataPRO is aware
info.Success();
return;
}
try
{
var exitRT = new EndRealtimeMode(this);
exitRT.SyncExecute();
if (null != DASArmStatus && RecordingModeExtensions.IsAStreamMode((DFConstantsAndEnums.RecordingMode)DASArmStatus.RecordingMode))
{
//for safety unset the auto arm flag in case the user reboots ...
DisAutoArm();
}
if (null != DASArmStatus) DASArmStatus.IsInRealtime = false; // FB15550: Update IsInRealtime flag if we exit RT so DataPRO is aware
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
void IRealTimeActions.RealTimeTiltPolling(ServiceCallback callback,
object userData,
ManualResetEvent stopEvent)
{
var packet = new RealTimeTiltAsyncPacket();
packet.StopEvent = stopEvent;
packet.Info = new SliceServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Slice.RealTimeTiltPolling", AsyncRealTimeTiltPolling, packet);
}
private void AsyncRealTimeTiltPolling(object asyncInfo)
{
var packet = asyncInfo as RealTimeTiltAsyncPacket;
try
{
while (!packet.StopEvent.WaitOne(0, false))
{
var axisADCData = new short[3] { 0, 0, 0 };
var calFactor = new double[3] { 1, 1, 1 };
var zeroData = new double[3] { 0, 0, 0 };
// Get raw tilt ADC
var qtsd = new QueryTiltSensorData(this);
qtsd.DeviceID = 1;
qtsd.SyncExecute();
axisADCData[0] = qtsd.Channel1ValueAdc;
axisADCData[1] = qtsd.Channel2ValueAdc;
axisADCData[2] = qtsd.Channel3ValueAdc;
//Get tilt sensor scale factors
var scaleFactorGPerADC = new float[3] { 1, 1, 1 };
if (RunTestVariables.InRunTest && RunTestVariables.TiltSensorScaleFactor > 0)
{
scaleFactorGPerADC = new[]
{
RunTestVariables.TiltSensorScaleFactor, RunTestVariables.TiltSensorScaleFactor,
RunTestVariables.TiltSensorScaleFactor
};
}
else
{
try
{
var scaleFactorQuery = new QueryArmAttribute(this)
{
Key = AttributeTypes.ArmAndEventAttributes.InSliceTiltSensorScaleFactorGPerADC
};
scaleFactorQuery.SyncExecute();
scaleFactorGPerADC = scaleFactorQuery.Value as float[];
}
catch (Exception)
{
}
}
int dominantAxis = (axisADCData.Max() < Math.Abs(axisADCData.Min())) ?
Array.IndexOf(axisADCData, axisADCData.Min()) : Array.IndexOf(axisADCData, axisADCData.Max());
var query = new QuerySystemAttribute_BridgeSlice6(this);
query.DeviceID = 1;
try
{
query.Key = AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_1;
query.SyncExecute();
calFactor[0] = Convert.ToDouble(query.Value) == 0D ? 1D : Convert.ToDouble(query.Value);
query.Key = AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_7;
query.SyncExecute();
calFactor[1] = Convert.ToDouble(query.Value) == 0D ? 1D : Convert.ToDouble(query.Value);
query.Key = AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_13;
query.SyncExecute();
calFactor[2] = Convert.ToDouble(query.Value) == 0D ? 1D : Convert.ToDouble(query.Value);
}
catch { }
// Calculate Accel Data
var accelData = new double[3];
for (int i = 0; i < accelData.Length; i++)
{
var channel_2G = (axisADCData[i] / calFactor[i]) * scaleFactorGPerADC[i];
if (channel_2G > 1)
{
channel_2G = 1;
}
else if (channel_2G < -1)
{
channel_2G = -1;
}
accelData[i] = channel_2G;
}
bool positivePolarity = (axisADCData[dominantAxis] > 0);
switch (dominantAxis)
{
case 0:
query.Key = AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_2;
break;
case 1:
query.Key = AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_8;
break;
case 2:
query.Key = AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_14;
break;
default:
query.Key = AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_2;
break;
}
try
{
query.SyncExecute();
zeroData[dominantAxis] = Convert.ToDouble(query.Value);
}
catch { }
var query2 = new QuerySystemAttribute_BridgeSlice6(this);
query2.DeviceID = 1;
switch (dominantAxis)
{
case 0:
query.Key = positivePolarity ? AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_9 : AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_10;
query2.Key = positivePolarity ? AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_15 : AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_16;
break;
case 1:
query.Key = positivePolarity ? AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_3 : AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_4;
query2.Key = positivePolarity ? AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_17 : AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_18;
break;
case 2:
query.Key = positivePolarity ? AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_5 : AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_6;
query2.Key = positivePolarity ? AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_11 : AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_12;
break;
default:
query.Key = positivePolarity ? AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_9 : AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_10;
query2.Key = positivePolarity ? AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_15 : AttributeTypes.SystemAttributes_BridgeSlice6.TILTSENSOR_CAL_16;
break;
}
try
{
query.SyncExecute();
query2.SyncExecute();
switch (dominantAxis)
{
case 0:
zeroData[1] = Convert.ToDouble(query.Value);
zeroData[2] = Convert.ToDouble(query2.Value);
break;
case 1:
zeroData[0] = Convert.ToDouble(query.Value);
zeroData[2] = Convert.ToDouble(query2.Value);
break;
case 2:
zeroData[0] = Convert.ToDouble(query.Value);
zeroData[1] = Convert.ToDouble(query2.Value);
break;
}
}
catch { }
// Calculate Tilt Data
var Sx = (axisADCData[0] - zeroData[0]) / calFactor[0];
var Sy = (axisADCData[1] - zeroData[1]) / calFactor[1];
var Sz = (axisADCData[2] - zeroData[2]) / calFactor[2];
var SG = Math.Sqrt(Math.Pow(Sx, 2) + Math.Pow(Sy, 2) + Math.Pow(Sz, 2));
var tiltInDegrees = new double[3];
tiltInDegrees[0] = (180.0 / Math.PI) * Math.Asin(Sx / SG);
tiltInDegrees[1] = (180.0 / Math.PI) * Math.Asin(Sy / SG);
tiltInDegrees[2] = (180.0 / Math.PI) * Math.Asin(Sz / SG);
TiltAxisData = tiltInDegrees.ToList();
ThreadPool.QueueUserWorkItem(packet.Info.NewData, new ServiceCallbackData.TiltNewData()
{
TiltData = tiltInDegrees,
AccelData = accelData,
});
}
packet.Info.Success();
}
catch (CanceledException)
{
packet.Info.Cancel();
}
catch (Exception ex)
{
packet.Info.Error(ex.Message, ex);
}
}
public string UDPStreamAddress
{
get;
private set;
}
// FB15313: Add UDP Streaming options
void IRealTimeActions.SetUDPStreamProfile(ServiceCallback callback, object userData,
UDPStreamProfile streamProfile, string udpAddress, ushort timeChannelId, ushort dataChannelId,
uint[] tmnsConfig, ushort irigTimeDataPacketIntervalMs)
{
var packet = new RealTimeUDPStreamProfileAsyncPacket()
{
Info = new SliceServiceAsyncInfo(callback, userData),
Profile = streamProfile,
UDPAddress = udpAddress,
TimeDataChannelId = timeChannelId,
DataChannelId = dataChannelId,
TMNSConfig = tmnsConfig,
IRIGTimeDataPacketIntervalMs = irigTimeDataPacketIntervalMs
};
LaunchAsyncWorker("Slice.SetUDPStreamProfile", AsyncSetUDPStreamProfile, packet);
}
private void AsyncSetUDPStreamProfile(object asyncInfo)
{
var packet = asyncInfo as RealTimeUDPStreamProfileAsyncPacket;
try
{
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.UDPRealtimeStream))
{
var rtUDPAddress = packet.UDPAddress;
var profile = (byte)packet.Profile;
var timeChannelId = packet.TimeDataChannelId;
var dataChannelId = packet.DataChannelId;
var tmnsConfig = new TMNSConfig(packet.TMNSConfig);
var udpAddress = new UriBuilder(rtUDPAddress);
byte[] tmp = Encoding.ASCII.GetBytes(udpAddress.Uri.AbsoluteUri.TrimEnd('/'));
byte[] ipport = new byte[28];
for (int i = 0; i < tmp.Length; i++)
{
ipport[i] = tmp[i];
}
var ssaUDPStreamProfile = new StreamConfigUDPSet(this, AbstractCommandBase.Default_IO_Timeout)
{
Stream_Profile_Number = profile,
Irig106Config0 = timeChannelId,
Irig106Config1 = dataChannelId,
TMNS_PCMSubFrameId = tmnsConfig.TMNS_PCMSubFrameId,
TMNS_MsgId = tmnsConfig.TMNS_MsgId,
TMNS_PCMMinorPerMajor = tmnsConfig.TMNS_PCMMinorPerMajor,
TMNS_TMATSPortNumber = tmnsConfig.TMNS_TMATSPortNumber,
IENAUDP_PortNumber = tmnsConfig.IENAUDP_PortNumber,
TMNS5 = tmnsConfig.TMNS5,
TMNS6 = tmnsConfig.TMNS6,
TMNS7 = tmnsConfig.TMNS7,
UdpIpPort = ipport
};
ssaUDPStreamProfile.SyncExecute();
UDPStreamAddress = udpAddress.Uri.AbsoluteUri.TrimEnd('/');
// FB15354: Enforce IRIG Time Data Packet Interval in order to read streaming data in NetView, etc.
var ssaIRIGTimeData = new SetSystemAttributeSLICE2(this, AbstractCommandBase.Default_IO_Timeout);
ssaIRIGTimeData.SetValue(AttributeTypes.SystemAttributesSLICE2.S6A_IrigTimeDataPacketIntervalMsec, packet.IRIGTimeDataPacketIntervalMs.ToString(), true);
ssaIRIGTimeData.SyncExecute();
}
packet.Info.Success();
}
catch (CanceledException)
{
packet.Info.Cancel();
}
catch (Exception ex)
{
packet.Info.Error(ex.Message, ex);
}
}
void IRealTimeActions.GetUDPStreamProfile(ServiceCallback callback, object userData)
{
var info = new SliceServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Slice.GetUDPStreamProfile", AsyncGetUDPStreamProfile, info);
}
private void AsyncGetUDPStreamProfile(object asyncInfo)
{
var info = asyncInfo as SliceServiceAsyncInfo;
try
{
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.UDPRealtimeStream))
{
var qsaUDPStreamProfile = new StreamConfigUDPGet(this, AbstractCommandBase.Default_IO_Timeout);
qsaUDPStreamProfile.SyncExecute();
var len = Array.IndexOf(qsaUDPStreamProfile.UdpIpPort, (byte)0x00);
UDPStreamAddress = Encoding.ASCII.GetString(qsaUDPStreamProfile.UdpIpPort, 0, len < 0 ? qsaUDPStreamProfile.UdpIpPort.Length : len);
}
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
#endregion
}
}

View File

@@ -0,0 +1,237 @@
using System;
using DTS.DASLib.Command.SLICE;
using DTS.Common.ICommunication;
using DTS.Common.Utilities.Logging;
using DTS.Common.Interface.Connection;
using DTS.Common.Enums.DASFactory;
using DTS.Common.Interface.DASFactory;
namespace DTS.DASLib.Service
{
public partial class Slice<T> : Communication<T>,
IDASCommunication,
IConfigurationActions,
IDiagnosticsActions,
ITriggerCheckActions,
IRealTimeActions,
IArmActions,
IDownloadActions where T : IConnection, new()
{
#region Trigger check
void ITriggerCheckActions.PreStartTriggerCheck(ServiceCallback callback, object userData)
{
var info = new SliceServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Slice.PreStartTriggerCheck", AsyncPreStartTriggerCheck, info);
}
/// <summary>
/// complete any prep work before starting trigger check that needs to be done
/// </summary>
protected virtual void AsyncPreStartTriggerCheck(object asyncInfo)
{
if (!(asyncInfo is SliceServiceAsyncInfo info)) { return; }
try
{
if (SupportsStartInversion())
{
var ssaPolarity = new SetSystemAttribute(this);
ssaPolarity.SetValue(AttributeTypes.SystemAttributes.StartRecordPolarity, (byte)(InvertStart ? 1 : 0), true);
ssaPolarity.SyncExecute();
}
if (SupportsTriggerInversion())
{
var ssaPolarity = new SetSystemAttribute(this);
ssaPolarity.SetValue(AttributeTypes.SystemAttributes.TriggerPolarity, (byte)(InvertTrigger ? 1 : 0), true);
ssaPolarity.SyncExecute();
}
}
catch (Exception ex)
{
APILogger.Log($"AsyncPreStartTriggerCheck failed, {ex.Message}");
}
info.Success();
}
void ITriggerCheckActions.PostStartTriggerCheck(ServiceCallback callback, object userData)
{
var info = new SliceServiceAsyncInfo(callback, userData);
info.Success();
}
void ITriggerCheckActions.StartTriggerCheck(ServiceCallback callback, object userData)
{
var info = new SliceServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Slice.StartTriggerCheck", AsyncStartTriggerCheck, info);
}
protected virtual void AsyncStartTriggerCheck(object asyncInfo)
{
if (!(asyncInfo is SliceServiceAsyncInfo info)) { return; }
try
{
try
{
var ihl = new InitializeHardwareLines(this) { LogCommands = true };
try
{
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines))
{
ihl.SyncExecute();
}
}
catch (Exception ex)
{
InitializeHardwareLines.Log(ex, ihl);
}
if (ihl.TriggerInputShorted)
{
info.Error("TriggerInputShorted");
return;
}
if (ihl.StartRecordShorted)
{
info.Error("StartInputShorted");
return;
}
}
catch (CanceledException)
{
info.Cancel();
return;
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
return;
}
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
void ITriggerCheckActions.DoStartCheck(ServiceCallback callback, object userData)
{
var info = new SliceServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Slice.DoStartCheck", AsyncDoStartCheck, info);
}
void ITriggerCheckActions.DoTriggerCheck(ServiceCallback callback, object userData)
{
SliceServiceAsyncInfo info = null;
if (null != callback)
{
info = new SliceServiceAsyncInfo(callback, userData);
}
LaunchAsyncWorker("Slice.DoTriggerCheck", AsyncDoTriggerCheck, info);
}
void ITriggerCheckActions.DoTriggerCheckSync()
{
var ihl = new InitializeHardwareLines(this) { LogCommands = false };
try
{
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines))
{
ihl.SyncExecute();
}
}
catch (Exception ex)
{
InitializeHardwareLines.Log(ex, ihl);
}
var status = new ArmStatus
{
IsTriggered = ihl.TriggerInputShorted,
IsArmed = !ihl.TriggerInputShorted,
IsTriggerShorted = ihl.TriggerInputShorted,
IsStartShorted = ihl.StartRecordShorted
};
SetDASArmStatus(status, true);
}
private void AsyncDoTriggerCheck(object asyncInfo)
{
SliceServiceAsyncInfo info = null;
if (asyncInfo is SliceServiceAsyncInfo)
{
info = (SliceServiceAsyncInfo)asyncInfo;
}
try
{
((ITriggerCheckActions)this).DoTriggerCheckSync();
info?.Success();
}
catch (CanceledException)
{
info?.Cancel();
}
catch (Exception ex)
{
info?.Error(ex.Message, ex);
}
}
private void AsyncDoStartCheck(object asyncInfo)
{
if (!(asyncInfo is SliceServiceAsyncInfo info)) { return; }
try
{
var ihl = new InitializeHardwareLines(this) { LogCommands = false };
try
{
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines))
{
ihl.SyncExecute();
}
}
catch (Exception ex) { InitializeHardwareLines.Log(ex, ihl); }
var status = new ArmStatus
{
IsArmed = !ihl.TriggerInputShorted,
IsRecording = ihl.StartRecordShorted
};
SetDASArmStatus(status, true);
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
void ITriggerCheckActions.CancelTriggerCheck(ServiceCallback callback, object userData)
{
var info = new SliceServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Slice.CancelTriggerCheck", AsyncCancelTriggerCheck, info);
}
private void AsyncCancelTriggerCheck(object asyncInfo)
{
if (!(asyncInfo is SliceServiceAsyncInfo info)) { return; }
try
{
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
#endregion
}
}

View File

@@ -0,0 +1,480 @@
using System;
using System.Threading;
using DTS.Common.DASResource;
using DTS.Common.ICommunication;
using DTS.DASLib.Command.SLICE;
using DTS.Common.Utilities.Logging;
using DTS.Common.Interface.Connection;
using DTS.Common.Classes.Connection;
using DTS.Common.Interface.DASFactory;
using DTS.Common.Enums.DASFactory;
using static DTS.Common.Enums.DASFactory.DFConstantsAndEnums;
using DTS.Common.Events;
using DTS.Common.Enums;
using System.Collections.Generic;
using DTS.Common.Enums.Sensors;
namespace DTS.DASLib.Service
{
public partial class Slice<T> : Communication<T>,
IDASCommunication,
IConfigurationActions,
IDiagnosticsActions,
ITriggerCheckActions,
IRealTimeActions,
IArmActions,
IDownloadActions where T : IConnection, new()
{
/// <summary>
/// returns the requested range for an analog channel, making adjustment for nonlinear if needed
/// </summary>
protected static double GetRequestedRange(AnalogInputDASChannel analog, double MvPerEU)
{
if (null != analog.LinearizationFormula && analog.LinearizationFormula.IsValid())
{
switch (analog.LinearizationFormula.NonLinearStyle)
{
case NonLinearStyles.Polynomial:
//polynomial can scale and should bypass this?
break;
default:
if (MvPerEU.Equals(1))
{
APILogger.DebugLog($"GetRequestRange HC={analog?.HardwareChannelName ?? "NULL"}, mVPerEu={MvPerEU} - {InputRangeMV}");
return InputRangeMV;
}
break;
}
}
APILogger.DebugLog($"GetRequestRange HC={analog?.HardwareChannelName ?? "NULL"}, mVPerEu={MvPerEU} DesiredRange={analog.DesiredRangeWithHeadroomEU}");
return analog.DesiredRangeWithHeadroomEU * MvPerEU;
}
public virtual bool SupportsRemoveLeapSeconds { get => false; }
protected void SetRemoveSeconds()
{
//http://manuscript.dts.local/f/cases/31747/Add-support-for-GPS-Time-leap-seconds
if (IsCommandSupported(ProtocolLimitedCommands.RemoveLeapSeconds))
{
try
{
var set = new SetSystemAttributeSLICE6AIR(this);
set.SetValue(AttributeTypes.SystemAttributesSLICE6AIR.RemoveLeapSeconds, RunTestVariables.RemoveLeapSeconds ? (byte)1 : (byte)0, true);
set.SyncExecute();
}
catch (Exception ex)
{
APILogger.Log(ex);
}
}
}
protected virtual QATSExtendedFault[] GetExtendedFaultFlags()
{
var list = new List<QATSExtendedFault>();
try
{
if (!IsCommandSupported(ProtocolLimitedCommands.ExtendedFaultIds)) { return list.ToArray(); }
var qee = new QueryArmAttribute(this) { Key = AttributeTypes.ArmAndEventAttributes.ExtFaultFlags, DeviceID = 0 };
qee.SyncExecute();
if (qee.Value is uint[] uints)
{
var first = uints[0];
for (var i = 0; i < 32; i++)
{
if (0 != (first & (1 << i)))
{
list.Add((QATSExtendedFault)(1 << i));
}
}
}
}
catch (Exception ex)
{
APILogger.Log(ex);
}
return list.ToArray();
}
public virtual bool SupportsADCSamplesPerPacket { get => false; }
protected void SetADCSamplesPerPacket(int adcPerPacket)
{
//http://manuscript.dts.local/f/cases/31754/
if (IsCommandSupported(ProtocolLimitedCommands.ADCSamplesPerPacket))
{
try
{
var get = new QuerySystemAttribute(this) { Key = AttributeTypes.SystemAttributes.S6A_IrigStreamBufferConfig };
get.SyncExecute();
var getParams = (ushort[])get.Value;
getParams[1] = (ushort)adcPerPacket;
var set = new SetSystemAttribute(this);
set.SetValue(AttributeTypes.SystemAttributes.S6A_IrigStreamBufferConfig, getParams, true);
set.SyncExecute();
}
catch (Exception ex)
{
APILogger.Log(ex);
}
}
else
{
APILogger.Log($"ADC samples per second not supported by firmware on {SerialNumber}");
}
}
protected virtual uint[] GetExtendedFaultFlags(int eventIndex)
{
try
{
var qee = new QueryEventAttribute(this) { Key = AttributeTypes.ArmAndEventAttributes.ExtFaultFlags, DeviceID = 0, EventNumber = Convert.ToUInt16(eventIndex) };
qee.SyncExecute();
return (uint[])qee.Value;
}
catch (Exception ex)
{
APILogger.Log(ex);
}
return new uint[] { 0, 0, 0, 0 };
}
/// <summary>
/// surfaces an error to the application, if applicable
/// http://manuscript.dts.local/f/cases/28312/Surface-Read-does-not-match-write-to-user
/// </summary>
/// <param name="msg"></param>
protected static void SurfaceApplicationError(string msg)
{
PageErrorEvent.SurfaceApplicationError(msg);
}
public ExcitationStatus ExcitationStatus { get; set; } = ExcitationStatus.Unknown;
public virtual void SetIsStreamingSupported(bool supported = false)
{
IsStreamingSupported = false;
}
public virtual void ReadFirstUseDate()
{
IsFirstUseDateSupported = false;
FirstUseDate = null;
}
/// <summary>
/// indicates date of first use
/// null indicates the hardware has not been used since calibration
/// only valid when IsFirstUseDateSupported is true
/// 15524 DAS "First Use Date"
/// </summary>
public DateTime? FirstUseDate { get; set; } = null;
/// <summary>
/// returns whether the hardware supports first use or not
/// for hardware to support first use the hardware must support
/// storage for user attributes in firmware and also have been
/// calibrated by software support hardware first use
/// 15524 DAS "First Use Date"
/// </summary>
public bool IsFirstUseDateSupported { get; set; } = false;
/// <summary>
/// indicates whether or not streaming is supported
/// 30429 TSR AIRs can enable/disable streaming via the DISABLE_STREAMING_FEATURE system attribute
/// </summary>
public bool IsStreamingSupported { get; set; } = false;
public int RecordId { get; set; } = Common.Enums.Hardware.HardwareConstants.INVALID_IDASCOMMUNICATION_RECORD_ID;
/// <summary>
/// returns the total number of channels in the event
/// </summary>
/// <param name="eventNum"></param>
/// <returns></returns>
protected virtual uint GetEventTotalChannels(int eventNum)
{
var eventTC = new QueryEventAttribute(this);
eventTC.EventNumber = (ushort)eventNum;
eventTC.Key = AttributeTypes.ArmAndEventAttributes.TotalChannels;
eventTC.SyncExecute();
return (byte)eventTC.Value;
}
public string MACAddress { get; set; }
public string[] DownstreamMACAddresses { get; set; }
public virtual bool IsEthernetDistributor() { return false; }
public virtual bool IsSlice6Distributor() { return false; }
public virtual bool IsBattery() { return false; }
public virtual bool IsTSRAIR() { return false; }
public virtual bool IsSlice6Air() { return false; }
public virtual bool IsSlice6AirTc() { return false; }
public virtual bool IsScheduleEventCountSupported() { return false; }
public class SliceServiceQueryConfigAsyncInfo : SliceServiceAsyncInfo
{
public uint CRC { get; set; } = 0;
public string ConfigString { get; set; } = string.Empty;
public bool ReadIds { get; set; } = true;
public bool DeviceScaleFactors { get; set; } = true;
public SliceServiceQueryConfigAsyncInfo(ServiceCallback _callback, object _userData, uint crc,
string strConfig, bool bReadIds, bool bDeviceScaleFactors, bool differentModuleCountsAreOK) : base(_callback, _userData)
{
CRC = crc;
ConfigString = strConfig;
ReadIds = bReadIds;
DeviceScaleFactors = bDeviceScaleFactors;
DifferentModuleCountsAreOK = differentModuleCountsAreOK;
}
public bool DifferentModuleCountsAreOK { get; set; } = false;
}
public class SliceServiceQueryTestSetupAsyncInfo : SliceServiceAsyncInfo
{
public string TestSetupGuid { get; set; }
public SliceServiceQueryTestSetupAsyncInfo(ServiceCallback _callback, object _userData, string testSetupGuid) : base(_callback, _userData)
{
TestSetupGuid = testSetupGuid;
}
}
public class SliceServiceSetTestSetupAsyncInfo : SliceServiceAsyncInfo
{
public string TestSetupXML { get; set; }
public SliceServiceSetTestSetupAsyncInfo(ServiceCallback _callback, object _userData, string testSetupXML) : base(_callback, _userData)
{
TestSetupXML = testSetupXML;
}
}
public class AutoDetectServiceAsyncInfo : SliceServiceAsyncInfo
{
public bool QueryConfiguration { get; set; } = true;
public AutoDetectServiceAsyncInfo(bool queryConfiguration, ServiceCallback callback, object userData)
: base(callback, userData)
{
QueryConfiguration = queryConfiguration;
}
}
public class SliceServiceAsyncInfo
{
public ServiceCallback callback { get; set; }
public object userData { get; set; }
public object functionData { get; set; }
public PrePostResults PreOrPost { get; set; }
public int? MaxTimeout { get; set; }
public SliceServiceAsyncInfo(ServiceCallback _callback, object _userData)
{
callback = _callback;
userData = _userData;
}
public void Error(string msg, Exception ex)
{
try
{
var cbData = new ServiceCallbackData();
cbData.Status = ServiceCallbackData.CallbackStatus.Failure;
cbData.ErrorMessage = msg;
cbData.ErrorException = ex;
cbData.UserData = userData;
callback(cbData);
}
catch (Exception eex)
{
APILogger.Log("MessageBox", Strings.SLICEAsyncInfoError, eex);
}
}
public void Error(string msg)
{
Error(msg, null);
}
public void Progress(int value)
{
try
{
var progressData = new ServiceCallbackData();
progressData.Status = ServiceCallbackData.CallbackStatus.ProgressReport;
progressData.ProgressValue = value;
progressData.UserData = userData;
callback(progressData);
}
catch (Exception ex)
{
APILogger.Log("MessageBox", Strings.SLICEAsyncInfoProgressError, ex);
}
}
//public void NewData(IList<short[][]> datas, IList<UInt64> SampleNumbers)
public void NewData(object obj)
{
if (obj is ServiceCallbackData.DiagnosticNewData)
{
var progressData = new ServiceCallbackData();
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
progressData.ProgressValue = 0;
progressData.UserData = userData;
progressData.SetNewDiagnosticData((obj as ServiceCallbackData.DiagnosticNewData));
callback(progressData);
}
else if (obj is ServiceCallbackData.TiltNewData)
{
var progressData = new ServiceCallbackData();
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
progressData.ProgressValue = 0;
progressData.UserData = userData;
progressData.SetNewTiltData((obj as ServiceCallbackData.TiltNewData));
callback(progressData);
}
else if (obj is ServiceCallbackData.UARTNewData)
{
var progressData = new ServiceCallbackData();
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
progressData.ProgressValue = 0;
progressData.UserData = userData;
progressData.SetNewUARTData(obj as ServiceCallbackData.UARTNewData);
callback(progressData);
}
else if (obj is byte[])
{
var progressData = new ServiceCallbackData();
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
progressData.ProgressValue = 0;
progressData.SetNewByteData((byte[])obj);
progressData.UserData = userData;
callback(progressData);
}
else if (obj is DFConstantsAndEnums.T0CorrectionStatus status)
{
var progressData = new ServiceCallbackData();
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
progressData.ProgressValue = 0;
var i = (int)status;
progressData.SetNewByteData(BitConverter.GetBytes(i));
progressData.UserData = userData;
callback(progressData);
}
else
{
var newdatadata = obj as NewDataData;
var datas = newdatadata.datas;
var samplenumbers = newdatadata.SampleNumbers;
var timeStamps = newdatadata.TimeStamps;
var sequenceNumbers = newdatadata.SequenceNumbers;
try
{
var progressData = new ServiceCallbackData();
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
progressData.ProgressValue = 0;
progressData.UserData = userData;
var sequenceNumber = 0UL;
for (int i = 0; i < datas.Length && i < samplenumbers.Length; i++)
{
//polling apparently doesn't always populate sequence number
//to prevent an indexing error just use the last one
//18009 DataPRO becomes unusable when trying to put realtime in meter mode
if (i < sequenceNumbers.Length) { sequenceNumber = sequenceNumbers[i]; }
progressData.AddSampleData(datas[i], samplenumbers[i], timeStamps[i], sequenceNumber);
}
callback(progressData);
}
catch (Exception ex)
{
APILogger.Log("MessageBox", Strings.SLICEAsyncInfoNewDataError, ex);
}
}
}
public void NewData(short[][] data, UInt64 samplenumber, ulong timeStamp, ulong sequenceNumber)
{
try
{
var progressData = new ServiceCallbackData();
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
progressData.ProgressValue = 0;
progressData.UserData = userData;
progressData.AddSampleData(data, samplenumber, timeStamp, sequenceNumber);
callback(progressData);
}
catch (Exception ex)
{
APILogger.Log("MessageBox", Strings.SLICEAsyncInfoNewDataError, ex);
}
}
public void Success()
{
try
{
var success = new ServiceCallbackData();
success.Status = ServiceCallbackData.CallbackStatus.Success;
success.UserData = userData;
callback(success);
}
catch (Exception ex)
{
APILogger.Log("MessageBox", Strings.SLICEAsyncInfoSuccessError, ex);
}
}
public void Cancel()
{
try
{
var cancelReport = new ServiceCallbackData();
cancelReport.Status = ServiceCallbackData.CallbackStatus.Canceled;
cancelReport.ProgressValue = 0;
cancelReport.UserData = userData;
callback(cancelReport);
}
catch (Exception ex)
{
APILogger.Log("MessageBox", Strings.SLICEAsyncInfoCancelError, ex);
}
}
}
public void LaunchAsyncWorker(string Invoker, WaitCallback cb, object asyncInfo)
{
if (!Connected)
{
// "{0}: Not currently connected"
throw new NotConnectedException(string.Format(Strings.Slice_LaunchAsyncWorker_Err1, Invoker));
}
if (!ThreadPool.QueueUserWorkItem(cb, asyncInfo))
{
// "{0}: Unable to enqueue function"
throw new Exception(string.Format(Strings.Slice_LaunchAsyncWorker_Err2, Invoker));
}
}
/// <summary>
/// compare to an object to determine equality
/// </summary>
/// <param name="right"></param>
/// <returns></returns>
public override bool Equals(object right)
{
if (right == null)
return false;
if (ReferenceEquals(this, right))
return true;
var rightSlice = right as Slice<T>;
if (rightSlice == null)
return false;
if (string.IsNullOrEmpty(SerialNumber))
{
return string.IsNullOrEmpty(rightSlice.SerialNumber);
}
if (string.IsNullOrEmpty(rightSlice.SerialNumber))
return false;
return SerialNumber == rightSlice.SerialNumber;
}
/// <summary>
/// returns identical index for any two 'equal' slice
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
if (string.IsNullOrEmpty(SerialNumber))
return 0;
return SerialNumber.GetHashCode();
}
}
}