init
This commit is contained in:
2076
DataPRO/IService/Classes/SLICEService/SLICE Service.Arming.cs
Normal file
2076
DataPRO/IService/Classes/SLICEService/SLICE Service.Arming.cs
Normal file
File diff suppressed because it is too large
Load Diff
3697
DataPRO/IService/Classes/SLICEService/SLICE Service.Calibration.cs
Normal file
3697
DataPRO/IService/Classes/SLICEService/SLICE Service.Calibration.cs
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2579
DataPRO/IService/Classes/SLICEService/SLICE Service.Configuration.cs
Normal file
2579
DataPRO/IService/Classes/SLICEService/SLICE Service.Configuration.cs
Normal file
File diff suppressed because it is too large
Load Diff
1344
DataPRO/IService/Classes/SLICEService/SLICE Service.Download.cs
Normal file
1344
DataPRO/IService/Classes/SLICEService/SLICE Service.Download.cs
Normal file
File diff suppressed because it is too large
Load Diff
807
DataPRO/IService/Classes/SLICEService/SLICE Service.Public.cs
Normal file
807
DataPRO/IService/Classes/SLICEService/SLICE Service.Public.cs
Normal 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
|
||||
}
|
||||
923
DataPRO/IService/Classes/SLICEService/SLICE Service.Realtime.cs
Normal file
923
DataPRO/IService/Classes/SLICEService/SLICE Service.Realtime.cs
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
480
DataPRO/IService/Classes/SLICEService/SLICE Service.cs
Normal file
480
DataPRO/IService/Classes/SLICEService/SLICE Service.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user