init
This commit is contained in:
22
DataPRO/IService/Classes/SLICE/DASConfigurationEventArg.cs
Normal file
22
DataPRO/IService/Classes/SLICE/DASConfigurationEventArg.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// this class handles the data passed to consumers during a DASConfigurationEvent
|
||||
/// 17872 Use DASConfig XMLs on disk when performing an emergency download with DAS that have blank filestore(s)
|
||||
/// </summary>
|
||||
public class DASConfigurationArg : IDASConfigurationArg
|
||||
{
|
||||
public IDASCommunication DAS { get; private set; }
|
||||
public bool BlankConfigurationRead { get; private set; }
|
||||
public bool ConfigurationFailedValidation { get; private set; }
|
||||
|
||||
public DASConfigurationArg(IDASCommunication das, bool blankRead, bool failedValidation)
|
||||
{
|
||||
DAS = das;
|
||||
BlankConfigurationRead = blankRead;
|
||||
ConfigurationFailedValidation = failedValidation;
|
||||
}
|
||||
}
|
||||
}
|
||||
898
DataPRO/IService/Classes/SLICE/PowerPRO.cs
Normal file
898
DataPRO/IService/Classes/SLICE/PowerPRO.cs
Normal file
@@ -0,0 +1,898 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using DTS.Common.DASResource;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using Arm = DTS.DASLib.Command.SLICE.Arm;
|
||||
using Disarm = DTS.DASLib.Command.SLICE.Disarm;
|
||||
using EnableFaultChecking = DTS.DASLib.Command.SLICE.EnableFaultChecking;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System.Text;
|
||||
using DTS.DASLib.Service.Classes.SLICE;
|
||||
using System.Net.NetworkInformation;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Communication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.StatusAndProgressBar;
|
||||
using DTS.Common.Utilities;
|
||||
using DTS.DASLib.Command.SLICE.DownloadCommands;
|
||||
using DTS.DASLib.Command.SLICEDB;
|
||||
using DTS.Common.Constant.DASSpecific;
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using DisableFaultChecking = DTS.DASLib.Command.SLICE.DisableFaultChecking;
|
||||
using DTS.Common;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class PowerPro<T> : PowerPro_Base<T>, //IDASReconfigure,
|
||||
IDASCommunication,
|
||||
IConfigurationActions,
|
||||
IDiagnosticsActions,
|
||||
ITriggerCheckActions,
|
||||
IRealTimeActions,
|
||||
IArmActions,
|
||||
IDownloadActions
|
||||
where T : IConnection, new()
|
||||
{
|
||||
protected override void AsyncConfigure(object configAsyncInfo)
|
||||
{
|
||||
var info = (SliceConfigServiceAsyncInfo)configAsyncInfo;
|
||||
|
||||
if (ConfigData != null && ConfigData.Modules.Any())
|
||||
{
|
||||
try
|
||||
{
|
||||
var saa = new SetArmAttribute(this);
|
||||
saa.SetValue(AttributeTypes.ArmAndEventAttributes.SampleRate, ConfigData.Modules[0].SampleRateHz, true);
|
||||
saa.SyncExecute();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("failed to configure", SerialNumber, ex);
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
base.AsyncConfigure(configAsyncInfo);
|
||||
}
|
||||
public override string ConvertInputVoltage2BatteryCharging(double inputVoltage)
|
||||
{
|
||||
bool isCharging;
|
||||
var SwitchQuery = new QuerySwitchImmediate(this)
|
||||
{
|
||||
DeviceID = 0,
|
||||
Switch = (byte)Switches.PowerProSwitches.ChargePower
|
||||
};
|
||||
try
|
||||
{
|
||||
SwitchQuery.SyncExecute();
|
||||
if (1 == SwitchQuery.Setting)
|
||||
{
|
||||
isCharging = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isCharging = false;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
isCharging = false;
|
||||
}
|
||||
|
||||
// If we are charging
|
||||
if (isCharging)
|
||||
{
|
||||
return Resources.Charging;
|
||||
}
|
||||
// If we aren't charging and input is valid
|
||||
else if (inputVoltage > MinimumValidInputVoltage && inputVoltage < MaximumValidInputVoltage)
|
||||
{
|
||||
return Resources.NotCharging;
|
||||
}
|
||||
// If we're off input voltage and not charging
|
||||
else
|
||||
{
|
||||
return Resources.Discharging;
|
||||
}
|
||||
}
|
||||
public override bool? ChargingEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void IDASCommunication.SetIsStreamingSupported(bool supported)
|
||||
{
|
||||
IsStreamingSupported = false;
|
||||
}
|
||||
void IDASCommunication.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>
|
||||
/// returns true if the devices is an ethernet distributor
|
||||
/// for now that is SLICEDb, SLICE ECM, SLICE6DB
|
||||
/// these are devices that we talk through, but not to for device communication
|
||||
/// a rack we communicate with the modules by talking to the rack, so it's not a distributor
|
||||
/// </summary>
|
||||
/// <returns>returns true if the devices is an ethernet distributor</returns>
|
||||
public override bool IsEthernetDistributor()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override bool IsSlice6Distributor()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public override bool IsBattery()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override bool IsTSRAIR()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public bool IsSlice6Air()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public bool IsSlice6AirTc()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public override bool IsScheduleEventCountSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void IConfigurationActions.SetFirstUseDate(DateTime firstUseDate, ServiceCallback callback,
|
||||
object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Error("Not supported");
|
||||
}
|
||||
/// <summary>
|
||||
/// Figure out if events have been downloaded
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
public void QueryDownloadedStatus(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
/// <summary>
|
||||
/// Verify that the ConfigData property is correctly constructed
|
||||
/// </summary>
|
||||
/// <param name="DoStrictCheck">Set to true if your're arming</param>
|
||||
public void VerifyConfig(bool DoStrictCheck)
|
||||
{
|
||||
VerifyConfig(DoStrictCheck, null);
|
||||
}
|
||||
public void VerifyConfig(bool DoStrictCheck, ErrorCallback failedChallengeFunc)
|
||||
{
|
||||
if (!DoStrictCheck) return;
|
||||
if (!IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines)) return;
|
||||
var query = new InitializeHardwareLines(this)
|
||||
{
|
||||
CheckStartForShort = true,
|
||||
CheckTriggerForShort = true
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
query.SyncExecute();
|
||||
|
||||
if (query.StartRecordShorted && !IgnoreShortedStart)
|
||||
{
|
||||
//Start Shorted
|
||||
throw new StartShortedException(string.Format(Strings.StartRecordShorted, SerialNumber));
|
||||
}
|
||||
if (query.TriggerInputShorted && !IgnoreShortedTrigger)
|
||||
{
|
||||
//Trigger Shorted
|
||||
throw new TriggerShortedException(string.Format(Strings.TriggerShorted, SerialNumber));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
InitializeHardwareLines.Log(ex, query);
|
||||
}
|
||||
}
|
||||
void IArmActions.ReArm(ServiceCallback callback, object userData, bool autoArm, bool arm, bool repeatEnable)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Error("NotSupported");
|
||||
}
|
||||
public void PreparedArmNow(ServiceCallback callback, object userData, Guid eventGuid, int
|
||||
armNowTimeout, bool testingMode,
|
||||
int maxNumberEvents, bool SysMode)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
try
|
||||
{
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel))
|
||||
{
|
||||
var mppadc = new MeasurePowerProAllDiagnosticChannel(this);
|
||||
mppadc.SyncExecute(); // Just Log it for now
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); }
|
||||
|
||||
var saa = new SetArmAttribute(this);
|
||||
var postTriggerSamples = Convert.ToUInt64(ConfigData.Modules[0].PostTriggerSeconds *
|
||||
ConfigData.Modules[0].SampleRateHz);
|
||||
saa.SetValue(AttributeTypes.ArmAndEventAttributes.PostTriggerSamplesRequested, postTriggerSamples, true);
|
||||
saa.SyncExecute();
|
||||
|
||||
saa = new SetArmAttribute(this);
|
||||
var preTriggerSamples = 0UL;
|
||||
if (ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.CircularBuffer ||
|
||||
ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.CircularBufferPlusUART)
|
||||
{
|
||||
preTriggerSamples =
|
||||
Convert.ToUInt64(Math.Abs(ConfigData.Modules[0].PreTriggerSeconds *
|
||||
ConfigData.Modules[0].SampleRateHz));
|
||||
}
|
||||
saa.SetValue(AttributeTypes.ArmAndEventAttributes.PreTriggerSamplesRequested, preTriggerSamples, true);
|
||||
saa.SyncExecute();
|
||||
|
||||
SetArmMode(ConfigData.Modules[0].RecordingMode);
|
||||
|
||||
try
|
||||
{
|
||||
var arm = new Arm(this);
|
||||
arm.SyncExecute();
|
||||
//17812 DataPRO does not issue EnableFaultChecking when running with POWER PRO and a single DAS
|
||||
//UI code was setting this for non ethernet distributors
|
||||
DASArmStatus.IsArmed = true;
|
||||
SetDASArmStatus();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
info.Success(); //TEMP until PowerPro Event line is not shorted
|
||||
return;
|
||||
}
|
||||
|
||||
info.Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform diagnostics based on the property ChannelDiagnostics and stuff the
|
||||
/// result in ChannelDiagnosticsResults
|
||||
/// </summary>
|
||||
/// <param name="diagnosticsSampleRateHz">sample rate</param>
|
||||
/// <param name="diagnosticsAAFilterFrequencyHz">AA Filter rate</param>
|
||||
/// <param name="whichResult"></param>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
void IDiagnosticsActions.PrepareForDiagnostics(uint diagnosticsSampleRateHz,
|
||||
float diagnosticsAAFilterFrequencyHz,
|
||||
PrePostResults whichResult,
|
||||
ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform diagnostics based on the property ChannelDiagnostics and stuff the
|
||||
/// result in ChannelDiagnosticsResults
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
public void DiagnosAndGetResults(int EventNumber,
|
||||
PrePostResults WhichResult,
|
||||
ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
DiagnosticsHasBeenRun = true;
|
||||
BaseInput = new BaseInputValues();
|
||||
GetBaseInputs(true);
|
||||
ClearChannelDiagnosticsResults(false);
|
||||
info.Success();
|
||||
}
|
||||
public override double MaximumValidInputVoltage { get; set; } = 26D;
|
||||
public void PerformArmChecks(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.PerformArmChecks", new WaitCallback(AsyncPerformArmChecks), info);
|
||||
}
|
||||
|
||||
private void AsyncPerformArmChecks(object o)
|
||||
{
|
||||
var info = o as PowerProAsyncInfo;
|
||||
var dasResults = new ArmCheckResults();
|
||||
info.Progress(25);
|
||||
if (null != ArmCheckActions)
|
||||
{
|
||||
GetBaseInputs(true);
|
||||
if (ArmCheckActions.PerformInputVoltageCheck || ArmCheckActions.PerformBatteryVoltageCheck)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel))
|
||||
{
|
||||
var mppadc = new MeasurePowerProAllDiagnosticChannel(this);
|
||||
mppadc.SyncExecute(); // Just Log it for now
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); }
|
||||
}
|
||||
if (ArmCheckActions.PerformBatteryVoltageCheck)
|
||||
{
|
||||
//if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics))
|
||||
//{
|
||||
try
|
||||
{
|
||||
dasResults.BatteryVoltage = new double?[1];
|
||||
dasResults.BatteryVoltage[0] = BaseInput.BatteryMilliVolts / 1000D;
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to get Battery voltage", ex); }
|
||||
//}
|
||||
}
|
||||
info.Progress(33);
|
||||
if (ArmCheckActions.PerformInputVoltageCheck)
|
||||
{
|
||||
//if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics))
|
||||
//{
|
||||
try
|
||||
{
|
||||
dasResults.InputVoltage = BaseInput.InputMilliVolts / 1000D;
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to get Input voltage", ex); }
|
||||
//}
|
||||
}
|
||||
info.Progress(66);
|
||||
if (ArmCheckActions.PerformSquibResistanceCheck)
|
||||
{
|
||||
// No Squibs in PowerPro
|
||||
}
|
||||
if (ArmCheckActions.PerformEventLineCheck)
|
||||
{
|
||||
((ITriggerCheckActions)this).DoTriggerCheckSync();
|
||||
}
|
||||
if (ArmCheckActions.PerformSensorIdCheck)
|
||||
{
|
||||
//not needed
|
||||
}
|
||||
if (ArmCheckActions.PerformTemperatureCheck)
|
||||
{
|
||||
//// Temperature
|
||||
//dasResults.TemperaturesPre = new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN };
|
||||
|
||||
//var measure = new MeasureS6DBDiagnosticChannel(this);
|
||||
|
||||
////External sensor 1
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_2_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[0] = measure.Measurement;
|
||||
|
||||
////External sensor 2
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_3_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[1] = measure.Measurement;
|
||||
|
||||
////External sensor 3
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_4_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[2] = measure.Measurement;
|
||||
|
||||
////External sensor 4
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_5_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[3] = measure.Measurement;
|
||||
}
|
||||
}
|
||||
info.Progress(100);
|
||||
dasResults.SensorIds = null;
|
||||
dasResults.TiltSensorDataPre = null;
|
||||
dasResults.SquibResistances = null;
|
||||
ArmCheckResults = dasResults;
|
||||
info.Success();
|
||||
}
|
||||
|
||||
public void CheckAlreadyLevelTriggered(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.CheckAlreadyLevelTriggered", AsyncCheckAlreadyLevelTriggered, info);
|
||||
}
|
||||
private void AsyncCheckAlreadyLevelTriggered(object asyncInfo)
|
||||
{
|
||||
var info = asyncInfo as PowerProAsyncInfo;
|
||||
Debug.Assert(info != null, "info != null");
|
||||
try
|
||||
{
|
||||
foreach (var m in ConfigData.Modules)
|
||||
{
|
||||
foreach (var ch in m.Channels)
|
||||
{
|
||||
if (!(ch is AnalogInputDASChannel analog)) continue;
|
||||
analog.AlreadyLevelTriggered = false;
|
||||
analog.MeasuredEULevelTriggerCheck = double.NaN;
|
||||
}
|
||||
}
|
||||
info.Success();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.Error(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
public void DoTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
//this was supposed to be async, why is it executing synchronously? I dont' know
|
||||
//but I'm preserving it as is [dtm] 2019-05-23
|
||||
PowerProAsyncInfo info = null;
|
||||
if (null != callback)
|
||||
{
|
||||
info = new PowerProAsyncInfo(callback, userData);
|
||||
}
|
||||
DoTriggerCheckSync();
|
||||
info?.Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// do the synchronous version of trigger check
|
||||
/// </summary>
|
||||
public void DoTriggerCheckSync()
|
||||
{
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines))
|
||||
{
|
||||
var query = new InitializeHardwareLines(this) { LogCommands = true, CheckStartForShort = true, CheckTriggerForShort = true };
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
query.SyncExecute();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//IHL can throw an exception if the trigger is shorted, we don't want this
|
||||
//but if it's anything else go and rethrow the exception
|
||||
if (!ex.Message.ToLower().Contains("shorted"))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
//var oldStatus = DASArmStatus;
|
||||
var status = new ArmStatus
|
||||
{
|
||||
IsTriggered = query.TriggerInputShorted,
|
||||
//IsArmed = query.TriggerInputShorted || query.StartRecordShorted
|
||||
IsStartShorted = query.StartRecordShorted
|
||||
};
|
||||
|
||||
//10601 Trigger Check can miss the pulse generated by HW
|
||||
//we have to latch the trigger status for the S6DB ... since it does one shot pulse
|
||||
//if (null != oldStatus)
|
||||
//{
|
||||
// status.IsArmed = status.IsArmed || oldStatus.IsArmed;
|
||||
// status.IsTriggered = status.IsTriggered || oldStatus.IsTriggered;
|
||||
// status.IsStartShorted = status.IsStartShorted || oldStatus.IsStartShorted;
|
||||
//}
|
||||
|
||||
status.IsTriggerShorted = status.IsTriggered;
|
||||
//status.IsStartShorted = status.IsArmed;
|
||||
status.IsStartShorted = status.IsStartShorted;
|
||||
SetDASArmStatus(status, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
InitializeHardwareLines.Log(ex, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
void ITriggerCheckActions.PostStartTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
private class EventDiagnosticsAsyncPacket
|
||||
{
|
||||
public PowerProAsyncInfo Info { get; set; }
|
||||
public int EventNumber { get; set; }
|
||||
public PrePostResults WhichResult { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Retrieve the results from the implicit pre and post event diagnostics
|
||||
/// </summary>
|
||||
/// <param name="EventNumber">Which event number to Retrieve from</param>
|
||||
/// <param name="WhichResult">The pre or post test results?</param>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
public void GetEventDiagnosticsResults(int EventNumber, PrePostResults WhichResult,
|
||||
ServiceCallback callback, object userData)
|
||||
{
|
||||
var packet = new EventDiagnosticsAsyncPacket();
|
||||
packet.Info = new PowerProAsyncInfo(callback, userData);
|
||||
packet.EventNumber = EventNumber;
|
||||
packet.WhichResult = WhichResult;
|
||||
|
||||
packet.Info.Success();
|
||||
}
|
||||
public void PerformVoltageCheckTAOnly(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.PerformVoltageCheckTAOnly", AsyncPerformVoltageCheckTAOnly, info);
|
||||
}
|
||||
private void AsyncPerformVoltageCheckTAOnly(object o)
|
||||
{
|
||||
var info = o as PowerProAsyncInfo;
|
||||
info?.Success();
|
||||
}
|
||||
private const double SDB_ERR_VOLTAGE_REPORTING = 100000.0D;
|
||||
/// <summary>
|
||||
/// Retrieve the current arm status from the DAS
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
//void IArmActions.GetArmStatus(ServiceCallback callback, object userData, uint inputVoltageCutoff)
|
||||
//{
|
||||
// var info = new PowerProAsyncInfo(callback, userData);
|
||||
// var status = new ArmStatus { IsArmed = false };
|
||||
// try
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel))
|
||||
// {
|
||||
// var mppadc = new MeasurePowerProAllDiagnosticChannel(this);
|
||||
// mppadc.SyncExecute(); // Just Log it for now
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); }
|
||||
// if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics))
|
||||
// {
|
||||
// var batteryVoltage = 0.0;
|
||||
// try
|
||||
// {
|
||||
|
||||
// var query = new QueryBatteryVoltageMV(this, 3000);
|
||||
// query.SyncExecute();
|
||||
// var d = (double)query.BatteryVoltageMV;
|
||||
// if (d > SDB_ERR_VOLTAGE_REPORTING)
|
||||
// {
|
||||
// d /= 1000.0D;
|
||||
// }
|
||||
|
||||
// status.BatteryMilliVolts = d;
|
||||
|
||||
// batteryVoltage = Math.Round(d / 1000, 1);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// APILogger.Log("Failed to get battery mv", ex);
|
||||
// }
|
||||
|
||||
// try
|
||||
// {
|
||||
// var query = new QueryV1VoltageMV(this, 3000);
|
||||
// query.SyncExecute();
|
||||
// var d = (double)query.V1VoltageMV;
|
||||
// if (d > SDB_ERR_VOLTAGE_REPORTING)
|
||||
// {
|
||||
// d /= 1000.0D;
|
||||
// }
|
||||
|
||||
// status.InputMilliVolts = d;
|
||||
|
||||
// var inputVoltage = Math.Round(d / 1000, 1);
|
||||
|
||||
// if (batteryVoltage < MinimumValidBatteryVoltage || batteryVoltage > MaximumValidBatteryVoltage)
|
||||
// {
|
||||
// batteryVoltage = 0.0;
|
||||
// }
|
||||
|
||||
// BaseInput = new BaseInputValues();
|
||||
// var batteryVoltageStatusColor = DFConstantsAndEnums.VoltageStatusColor.Off;
|
||||
// batteryVoltageStatusColor = BaseInput.ChargeCapacityValid
|
||||
// ? ConvertBatteryCapacity2Color(batteryVoltage, BaseInput.ChargeCapacity)
|
||||
// : ConvertBatteryVoltage2Color(batteryVoltage);
|
||||
// var batteryChargingStatus = string.Empty;
|
||||
// if (batteryVoltage >= MinimumValidBatteryVoltage)
|
||||
// {
|
||||
// batteryChargingStatus = ConvertInputVoltage2BatteryCharging(inputVoltage);
|
||||
// }
|
||||
|
||||
// var statusDisplayBattery =
|
||||
// batteryVoltage < MinimumValidBatteryVoltage || batteryVoltage > MaximumValidBatteryVoltage
|
||||
// ? "---"
|
||||
// : batteryVoltage.ToString(System.Globalization.CultureInfo.InvariantCulture) + " V " +
|
||||
// batteryChargingStatus;
|
||||
// var inputVoltageStatusColor = ConvertInputVoltage2Color(inputVoltage);
|
||||
// BaseInput.InputVoltageStatusColor = inputVoltageStatusColor;
|
||||
// BaseInput.StatusDisplayInput =
|
||||
// inputVoltage < MinimumValidInputVoltage || inputVoltage > MaximumValidInputVoltage
|
||||
// ? "---"
|
||||
// : inputVoltage.ToString(System.Globalization.CultureInfo.InvariantCulture) + " V";
|
||||
// BaseInput.BatteryVoltageStatusColor = batteryVoltageStatusColor;
|
||||
// BaseInput.StatusDisplayBattery = statusDisplayBattery;
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// APILogger.Log("Failed to get input mv", ex);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// SetDASArmStatus(status, true);
|
||||
// }
|
||||
// info.Success();
|
||||
//}
|
||||
void IConfigurationActions.CheckSafetyState(bool bArmed, ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
|
||||
|
||||
//}
|
||||
/// <summary>
|
||||
/// this is a duplicate class of SLICEDb.SDBAsyncInfo, we might want to just use that one, but it is marked private there
|
||||
/// </summary>
|
||||
private class PowerProAsyncInfo
|
||||
{
|
||||
public ServiceCallback Callback { get; set; }
|
||||
public object UserData { get; set; }
|
||||
public object FunctionData { get; set; }
|
||||
|
||||
public PowerProAsyncInfo(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", "PowerPRO ERROR", 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", "PowerPRO ERROR", 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", "PowerPRO ERROR", 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", "PowerPRO ERROR", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class PowerPro_Base<T> : SLICE2_Base<T> where T : IConnection, new()
|
||||
{
|
||||
protected override bool AdjustInputRange(AnalogInputDASChannel analog)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns true if device supports trigger inversion, false otherwise
|
||||
/// <inheritdoc cref="IDASCommunication"/>
|
||||
/// </summary>
|
||||
/// <returns>true if device supports trigger inversion, false otherwise</returns>
|
||||
public override bool SupportsTriggerInversion() => HardwareConstants.SupportsTriggerInversion(GetHardwareType(), ProtocolVersion);
|
||||
/// <summary>
|
||||
/// returns true if device supports start inversion, false otherwise
|
||||
/// <inheritdoc cref="IDASCommunication"/>
|
||||
/// </summary>
|
||||
/// <returns>true if device supports start inversion, false otherwise</returns>
|
||||
public override bool SupportsStartInversion() => HardwareConstants.SupportsStartInversion(GetHardwareType(), ProtocolVersion);
|
||||
|
||||
|
||||
public override bool CheckAAF(float rate) { return true; }
|
||||
public override bool SupportsTimeSynchronization
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override double[] GetNominalRanges(SensorConstants.BridgeType bridgeType)
|
||||
{
|
||||
switch (bridgeType)
|
||||
{
|
||||
case SensorConstants.BridgeType.IEPE:
|
||||
return WinUSBSlice.StaticDASIEPEInfo.NominalRanges;
|
||||
default:
|
||||
return WinUSBSlice.StaticDASBridgeInfo.NominalRanges;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> PowerPro_MinimumProtocols =
|
||||
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 6.0 DB Protocol Limitations
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryMSP430Firmware] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleEvents] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArm] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDefaultMIF] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackSensors] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.TestCommunication] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackLowPowerMode] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetRealtimeSampleRate] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.LevelTrigger] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AttributeStoreBlocks] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MaxEvents] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmDiagnosticDelay] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackChannelAutoArmDiagLevel] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleSamplesRealtime] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
|
||||
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.DiangosShuntDAC] = PowerPRO.DIAGNOS_SHUNT_DAC;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageInsertion] = PowerPRO.DIAGNOS_SHUNT_DAC;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryEthernetMacTable] = PowerPRO.MIN_PROTOCOL_QUERYMACTABLE;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel] = PowerPRO.MIN_PROTOCOL_MEASUREPOWERPROALLDIAGNOSTICCHANNEL;
|
||||
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
|
||||
MinimumProtocols = PowerPro_MinimumProtocols;
|
||||
}
|
||||
protected override Slice<T>.ConfigAttributes GetConfigAttributes(ICommunication com)
|
||||
{
|
||||
return new SLICE6ConfigAttributes(com);
|
||||
}
|
||||
/// <summary>
|
||||
/// SLICE6 config attributes, mostly inherits from SLICE.ConfigAttributes with some functionality removed
|
||||
/// </summary>
|
||||
protected class SLICE6ConfigAttributes : Slice<T>.ConfigAttributes
|
||||
{
|
||||
public SLICE6ConfigAttributes(ICommunication _com)
|
||||
: base(_com)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// QueryEventData also is customized for SLICE6, it needs to perform SLICE6 specific data marshalling
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override QueryEventDataBase GetQueryEventData()
|
||||
{
|
||||
return new QueryEventData_SLICE6(this, QueryEventData_SLICE6.Default_IO_Timeout);
|
||||
}
|
||||
/// <summary>
|
||||
/// we can probably simplify and take common items (slice6+slice1) out of this function, but for now
|
||||
/// it's mostly a copy of SLICE1.AsyncConfigure
|
||||
/// </summary>
|
||||
/// <param name="configAsyncInfo"></param>
|
||||
protected override void AsyncConfigure(object configAsyncInfo)
|
||||
{
|
||||
var info = (SliceConfigServiceAsyncInfo)configAsyncInfo;
|
||||
|
||||
ConfigureHasBeenRun = true;
|
||||
if (info.DiscardDiagnostics) { DiagnosticsHasBeenRun = false; }
|
||||
info.Progress(100);
|
||||
info.Success();
|
||||
}
|
||||
|
||||
#region Voltage Check
|
||||
public void PerformVoltageCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.PerformVoltageCheck", AsyncPerformVoltageCheck, info);
|
||||
}
|
||||
|
||||
private void AsyncPerformVoltageCheck(object o)
|
||||
{
|
||||
var info = o as SliceServiceAsyncInfo;
|
||||
try
|
||||
{
|
||||
GetBaseInputs(true);
|
||||
info?.Success();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
info?.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// hardcoded constants right now ... maybe these belong in attributes in the firmware!
|
||||
/// </summary>
|
||||
protected override uint MaxAAFilterRateHz { get { return PowerPRO.MaxAAFilterRateHz; } }
|
||||
protected override uint MaxSampleRateHz { get { return 400000; } }
|
||||
}
|
||||
}
|
||||
86
DataPRO/IService/Classes/SLICE/S6DBConnectedDevice.cs
Normal file
86
DataPRO/IService/Classes/SLICE/S6DBConnectedDevice.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System.Net.NetworkInformation;
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using DTS.Common.Interface.Communication;
|
||||
|
||||
namespace DTS.DASLib.Service.Classes.SLICE
|
||||
{
|
||||
/// <summary>
|
||||
/// describes a device connected to a S6DB as determined by
|
||||
/// QAUTIL_QUERY_MAC_IP_TABLE
|
||||
/// part of
|
||||
/// 10582 Implement auto-discover and monitor DAS status.
|
||||
/// </summary>
|
||||
public class S6DBConnectedDevice : IDASConnectedDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// the device type of the connected device
|
||||
/// </summary>
|
||||
public HardwareTypes DeviceType { get; } = HardwareTypes.SLICE6_Base;
|
||||
|
||||
/// <summary>
|
||||
/// the port the device is on only positive values are valid
|
||||
/// 0 based
|
||||
/// </summary>
|
||||
public int Port { get; private set; } = -1;
|
||||
/// <summary>
|
||||
/// the position on the chain or port
|
||||
/// only positive values are valid
|
||||
/// 0 based
|
||||
/// </summary>
|
||||
public int SpotOnPort { get; private set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// MAC address
|
||||
/// </summary>
|
||||
public PhysicalAddress PhysicalAddress { get; private set; }
|
||||
/// <summary>
|
||||
/// IP address reported by device
|
||||
/// default value empty string
|
||||
/// </summary>
|
||||
public string IPAddress { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// serial number of device
|
||||
/// default value empty string
|
||||
/// </summary>
|
||||
public string SerialNumber { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// location of device
|
||||
/// default value empty string
|
||||
/// </summary>
|
||||
public string Location { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// version of device
|
||||
/// default value empty string
|
||||
/// </summary>
|
||||
public string Version { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// constructs new connected device record
|
||||
/// </summary>
|
||||
/// <param name="port">port, 0 based</param>
|
||||
/// <param name="spotOnPort">position on port/chain 0 based</param>
|
||||
/// <param name="physicalAddress">mac address</param>
|
||||
/// <param name="ipAddress">ip address</param>
|
||||
/// <param name="serialNumber">serial number of connected device</param>
|
||||
/// <param name="location">location</param>
|
||||
/// <param name="version">version</param>
|
||||
public S6DBConnectedDevice(int port, int spotOnPort, PhysicalAddress physicalAddress, string ipAddress,
|
||||
string serialNumber, string location, string version)
|
||||
{
|
||||
Port = port;
|
||||
SpotOnPort = spotOnPort;
|
||||
PhysicalAddress = physicalAddress;
|
||||
IPAddress = ipAddress;
|
||||
SerialNumber = serialNumber;
|
||||
Location = location;
|
||||
Version = version;
|
||||
if (SerialNumber.StartsWith("S6A"))
|
||||
{
|
||||
DeviceType = HardwareTypes.SLICE6_AIR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
642
DataPRO/IService/Classes/SLICE/SLICE1_5.cs
Normal file
642
DataPRO/IService/Classes/SLICE/SLICE1_5.cs
Normal file
@@ -0,0 +1,642 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DTS.Common;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.DASLib.Command;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.WINUSBConnection;
|
||||
using DTS.DASLib.Command.SLICE.DownloadCommands;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using DTS.Common.Constant.DASSpecific;
|
||||
using DTS.Common.Utilities.LTLogging;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class SLICE1_5<T> : SLICE2_Base<T>, IConfigurationActions where T : IConnection, new()
|
||||
{
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
if (SerialNumber.StartsWith("SG5"))
|
||||
{
|
||||
return HardwareTypes.SLICE1_G5Stack;
|
||||
}
|
||||
if (SerialNumber.Contains("BA0"))
|
||||
{
|
||||
return HardwareTypes.SLICE1_5_Micro_Base;
|
||||
}
|
||||
return HardwareTypes.SLICE1_5_Nano_Base;
|
||||
}
|
||||
public override int[] GetStackChannelConfigTypes() => new int[] { 0 };
|
||||
|
||||
/// <summary>
|
||||
/// 14269 Implement SLICE PRO and Base+ RTC
|
||||
/// my records indicate SLICE1.5 has always supported this feature ...
|
||||
/// </summary>
|
||||
public override bool SupportsTimeSynchronization => true;
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// gets the expected excitation in mV for a given channel
|
||||
/// returns 0 if excitation could not be retrieved, otherwise excitation in mV
|
||||
/// </summary>
|
||||
/// <param name="moduleIndex"></param>
|
||||
/// <param name="channelOnModule"></param>
|
||||
/// <returns></returns>
|
||||
protected override double GetExpectedExcitationMV(int moduleIndex, int channelOnModule)
|
||||
{
|
||||
if (ConfigData?.Modules == null || ConfigData.Modules.Length <= moduleIndex)
|
||||
{
|
||||
APILogger.Log("unable to get excitation, no ConfigData to base excitation on");
|
||||
return 0D;
|
||||
}
|
||||
if (!(ConfigData.Modules[moduleIndex].Channels[channelOnModule] is AnalogInputDASChannel aic))
|
||||
{
|
||||
//only have excitation to consider on analog channels
|
||||
APILogger.Log("unable to get excitation, channel has no excitation (is not analog)");
|
||||
return 0D;
|
||||
}
|
||||
var excitation = Test.Module.Channel.Sensor.GetExcitationVoltageMagnitudeFromEnum(aic.Excitation) * 1000D;
|
||||
try
|
||||
{
|
||||
var qsa = new QuerySystemAttribute_Bridge(this);
|
||||
|
||||
switch (channelOnModule)
|
||||
{
|
||||
case 0:
|
||||
qsa.Key = AttributeTypes.SystemAttributes_Bridge.FactoryCalibratedExcitationAVolts;
|
||||
break;
|
||||
case 1:
|
||||
qsa.Key = AttributeTypes.SystemAttributes_Bridge.FactoryCalibratedExcitationBVolts;
|
||||
break;
|
||||
default:
|
||||
qsa.Key = AttributeTypes.SystemAttributes_Bridge.FactoryCalibratedExcitationCVolts;
|
||||
break;
|
||||
}
|
||||
//note device 0 is the base, the first module starts at 1, so we have to start at an offset of 1
|
||||
qsa.DeviceID = Convert.ToByte(1 + moduleIndex);
|
||||
qsa.SyncExecute();
|
||||
var bridgeExcitation = Convert.ToDouble(qsa.Value) * 1000D;//convert from V to mV
|
||||
var delta = Math.Abs(excitation - bridgeExcitation);
|
||||
if (delta < 500)
|
||||
{
|
||||
excitation = bridgeExcitation;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
return excitation;
|
||||
}
|
||||
public static StaticInformation StaticDASBridge1_5Info = new StaticInformation(new[]
|
||||
{//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
|
||||
});
|
||||
|
||||
protected override float GetLevelTriggerThreshold(AnalogInputDASChannel analog, IDiagnosticResult diagnostics,
|
||||
double thresholdeu, double mvPerEu)
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
if (analog.SensitivityMilliVoltsPerEU < 0 && !analog.RemoveOffset)
|
||||
{
|
||||
var threshold = Convert.ToSingle(thresholdeu * mvPerEu
|
||||
-
|
||||
diagnostics.GetExpectedDataZeroLevelADC(analog.ZeroMethod) *
|
||||
diagnostics.ScalefactorMilliVoltsPerADC);
|
||||
|
||||
try
|
||||
{
|
||||
var s =
|
||||
$"{now.ToShortDateString()} {now.ToShortTimeString()}\r\n{SerialNumber}:{analog.Number}:{analog.SerialNumber} : thresholdEU ({thresholdeu}) * MvPerEU ({mvPerEu}) - DataZeroLevelADC ({diagnostics.GetExpectedDataZeroLevelADC(analog.ZeroMethod)}) * ScaleFactorMvPerADC ({diagnostics.ScalefactorMilliVoltsPerADC})={threshold}; SensitivityMv={analog.SensitivityMilliVoltsPerEU}\r\n";
|
||||
LevelTriggerLogging.LevelTriggerLog(s);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
return threshold;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var threshold = Convert.ToSingle(thresholdeu * mvPerEu
|
||||
+
|
||||
diagnostics.GetExpectedDataZeroLevelADC(analog.ZeroMethod) *
|
||||
diagnostics.ScalefactorMilliVoltsPerADC);
|
||||
try
|
||||
{
|
||||
var s =
|
||||
$"{now.ToShortDateString()} {now.ToShortTimeString()}\r\n{SerialNumber}:{analog.Number}:{analog.SerialNumber} : thresholdEU ({thresholdeu}) * MvPerEU ({mvPerEu}) + DataZeroLevelADC ({diagnostics.GetExpectedDataZeroLevelADC(analog.ZeroMethod)}) * ScaleFactorMvPerADC ({diagnostics.ScalefactorMilliVoltsPerADC})={threshold}; SensitivityMv={analog.SensitivityMilliVoltsPerEU}\r\n";
|
||||
LevelTriggerLogging.LevelTriggerLog(s);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
return threshold;
|
||||
}
|
||||
}
|
||||
|
||||
private const double IEPE_GAIN_DIVIDER = 4.9D;
|
||||
|
||||
//0.2040816327F, 2.0408163265F
|
||||
public static StaticInformation StaticDASIEPE1_5Info = new StaticInformation(new[]
|
||||
{
|
||||
2400D / (1.0D / IEPE_GAIN_DIVIDER),
|
||||
2400D / (10.0D / IEPE_GAIN_DIVIDER),
|
||||
});
|
||||
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> _slice15MinimumProtocols = new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
public override bool RequireDiagnosticRateMatchSampleRate() { return false; }
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 1.5 Protocol Limitations
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.DiangosShuntDAC] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryMSP430Firmware] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleEvents] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArm] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FlashCardInfo] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
//SLICE2_MinimumProtocols.Add(ReqProtoVer.Commands.VoltageInsertion, 133);
|
||||
//SLICE2_MinimumProtocols.Add(ReqProtoVer.Commands.SetDefaultMIF, 140);
|
||||
//SLICE2_MinimumProtocols.Add(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate, 137);
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackSensors] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PhysicalStartAddress] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.TestCommunication] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackLowPowerMode] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
//SLICE2_MinimumProtocols.Add(DFConstantsAndEnums.ProtocolLimitedCommands.StackChannelTypeConfiguration, 134);
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetRealtimeSampleRate] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
//SLICE2_MinimumProtocols.Add(DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration, 134);
|
||||
//SLICE2_MinimumProtocols.Add(DFConstantsAndEnums.ProtocolLimitedCommands.ProgramStackChannels, 136);
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
//SLICE2_MinimumProtocols.Add(DFConstantsAndEnums.ProtocolLimitedCommands.DiagnosticTwoVoltExcitation, 138);
|
||||
//SLICE2_MinimumProtocols.Add(DFConstantsAndEnums.ProtocolLimitedCommands.ExcitationLevel, 133);
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.LevelTrigger] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AttributeStoreBlocks] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MaxEvents] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmDiagnosticDelay] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackChannelAutoArmDiagLevel] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FlashClear] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
//SLICE2_MinimumProtocols.Add(DFConstantsAndEnums.ProtocolLimitedCommands.DiagnosticsMode, 133);
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleSamplesRealtime] = SLICE1_5.MIN_PROTOCOL_VER;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_TimeLeftInArm] = SLICE1_5.QUERY_ARM_AND_TRIGGER_STATUS_TIME_LEFT_IN_ARM;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRecDelayInSecond] = SLICE1_5.START_REC_DELAY_IN_SECOND;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MeasureInternalOffset] = SLICE1_5.MEASURE_INTERNAL_OFFSET;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = SLICE1_5.IGNORE_SHORTED_START_EVENT;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRealtimeStream] = SLICE1_5.START_REALTIME_STREAM;
|
||||
_slice15MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.GenerateEvent] = 9;
|
||||
MinimumProtocols = _slice15MinimumProtocols;
|
||||
|
||||
}
|
||||
protected override DASModule MakeConfigModuleFromInfoModule(InfoResult.Module infoModule)
|
||||
{
|
||||
var configModule = new DASModule(infoModule.ModuleArrayIndex, this);
|
||||
configModule.Channels = new AnalogInputDASChannel[infoModule.NumberOfChannels];
|
||||
|
||||
for (var i = 0; i < infoModule.NumberOfChannels; i++)
|
||||
{
|
||||
var channel = new AnalogInputDASChannel(configModule, i);
|
||||
if (infoModule.TypeOfModule == DFConstantsAndEnums.ModuleType.SLICEIEPE)
|
||||
{
|
||||
channel.IEPEChannel = true;
|
||||
channel.SupportedBridges = new[] { SensorConstants.BridgeType.IEPE };
|
||||
}
|
||||
else
|
||||
{
|
||||
channel.IEPEChannel = false;
|
||||
channel.SupportedBridges = new[] {SensorConstants.BridgeType.FullBridge,
|
||||
SensorConstants.BridgeType.HalfBridge};
|
||||
}
|
||||
configModule.Channels[i] = channel;
|
||||
}
|
||||
return configModule;
|
||||
}
|
||||
|
||||
protected override void PerformVoltageInsertionCheck(IDiagnosticActions[] channelActions, SliceServiceAsyncInfo info, ref IDiagnosticResult[] results)
|
||||
{
|
||||
// first count how many we need to do it on
|
||||
var numToMeasure = channelActions.Count(a => a.PerformVoltageInsertCheck);
|
||||
if (numToMeasure == 0)
|
||||
return;
|
||||
|
||||
//slice 1 bridges can not handle voltage insertion ...
|
||||
|
||||
for (var idx = 0; idx < channelActions.Length; idx++)
|
||||
{
|
||||
if (channelActions[idx].PerformVoltageInsertCheck)
|
||||
{
|
||||
results[idx].MeasuredGain = null;
|
||||
results[idx].TargetGain = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Measure the internal offset on the channels that have it flagged
|
||||
/// </summary>
|
||||
/// <param name="channelActions">An array of actions. One entry per channel</param>
|
||||
/// <param name="info">Our async data</param>
|
||||
/// <param name="results">An array of results. One entry per channel</param>
|
||||
/// <param name="bFinalOffset"></param>
|
||||
protected override void MeasureInternalOffset(IDiagnosticActions[] channelActions, SliceServiceAsyncInfo info, ref IDiagnosticResult[] results, bool bFinalOffset)
|
||||
{
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasureInternalOffset))
|
||||
{
|
||||
#region New internal offset measure
|
||||
// first count how many we need to do it on
|
||||
var numToMeasure = channelActions.Count(a => a.MeasureInternalOffset);
|
||||
if (numToMeasure == 0)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var measuredChannelBiasADC = new short[ChannelDiagnostics.Length];
|
||||
for (var idx = 0; idx < channelActions.Length; idx++)
|
||||
{
|
||||
if (!ChannelDiagnostics[idx].MeasureInternalOffset) continue;
|
||||
var qsab = new QuerySystemAttribute_Bridge(this)
|
||||
{
|
||||
// Get Module number from DAS Channel Number
|
||||
DeviceID = Convert.ToByte(1 + ChannelDiagnostics[idx].DASChannelNumber / 3),
|
||||
// Get Key offset from DAS Channel Number
|
||||
Key = AttributeTypes.SystemAttributes_Bridge.BIAS_ADC_A + (byte)(ChannelDiagnostics[idx].DASChannelNumber % 3)
|
||||
};
|
||||
qsab.SyncExecute();
|
||||
|
||||
if ((ushort)qsab.Value == 0)
|
||||
{
|
||||
// If value comes back as zero our base supports the bridge
|
||||
// attribute but the bridge does not, or has not been calibrated
|
||||
measuredChannelBiasADC[idx] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// convert from ushort to short
|
||||
measuredChannelBiasADC[idx] = Convert.ToInt16((ushort)qsab.Value - Math.Pow(2, 15));
|
||||
}
|
||||
}
|
||||
for (var idx = 0; idx < results.Length; idx++)
|
||||
{
|
||||
info.NewData(new ServiceCallbackData.DiagnosticNewData()
|
||||
{
|
||||
Result = measuredChannelBiasADC[idx],
|
||||
DasChannelNumber = results[idx].DASChannelNumber,
|
||||
Action = ServiceCallbackData.DiagnosticNewData.Actions.MeasureInternalOffset
|
||||
});
|
||||
|
||||
//attempt to resolve the removed adc by using the before and after info
|
||||
try
|
||||
{
|
||||
if (bFinalOffset)
|
||||
{
|
||||
if (null != results[idx] && channelActions[idx].RemoveOffset)
|
||||
{
|
||||
results[idx].RemovedInternalOffsetADC =
|
||||
Convert.ToInt32((double)results[idx].MeasuredInternalOffsetMilliVolts / results[idx].ScalefactorMilliVoltsPerADC -
|
||||
measuredChannelBiasADC[idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
results[idx].RemovedInternalOffsetADC = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
results[idx].MeasuredInternalOffsetMilliVolts = measuredChannelBiasADC[idx] * results[idx].ScalefactorMilliVoltsPerADC;
|
||||
results[idx].ZeroMVInADC = Convert.ToInt16(measuredChannelBiasADC[idx]);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(
|
||||
$"Error Retrieving Internal Offset on {SerialNumber} channel {results[idx].DASChannelNumber}", ex);
|
||||
results[idx].RemovedInternalOffsetADC = 0;
|
||||
results[idx].MeasuredInternalOffsetMilliVolts = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Error Retrieving Internal Offset", ex);
|
||||
foreach (var dr in results)
|
||||
{
|
||||
dr.RemovedInternalOffsetADC = 0;
|
||||
dr.MeasuredInternalOffsetMilliVolts = 0;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
else
|
||||
{
|
||||
//Command not supported
|
||||
foreach (var dr in results)
|
||||
{
|
||||
dr.RemovedInternalOffsetADC = 0;
|
||||
dr.MeasuredInternalOffsetMilliVolts = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert gain code to value based on Slice 1 conversion table
|
||||
/// </summary>
|
||||
/// <param name="gainCode"></param>
|
||||
/// <returns></returns>
|
||||
protected override double GainCodeToGainValue(ushort gainCode)
|
||||
{
|
||||
//Run the same code as Slice 1.0, not base:GainCodeToGainValue which is SLICE 2
|
||||
|
||||
var gainValueString = ((GainCodes)gainCode).ToString();
|
||||
if (!double.TryParse(gainValueString.TrimStart('G'), out var gainValue))
|
||||
{
|
||||
gainValue = 1.0D;
|
||||
}
|
||||
|
||||
return gainValue;
|
||||
}
|
||||
|
||||
public override double[] GetNominalRanges(SensorConstants.BridgeType bridgeType)
|
||||
{
|
||||
switch (bridgeType)
|
||||
{
|
||||
case SensorConstants.BridgeType.IEPE:
|
||||
return WinUSBSlice.StaticDASIEPEInfo.NominalRanges;
|
||||
default:
|
||||
return WinUSBSlice.StaticDASBridgeInfo.NominalRanges;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CheckAAF(float rate) { return true; }
|
||||
|
||||
/// <summary>
|
||||
/// hardcoded constants right now ... maybe these belong in attributes in the firmware!
|
||||
/// </summary>
|
||||
protected override uint MaxAAFilterRateHz => SLICE1_5.MaxAAFilterRateHz;
|
||||
|
||||
protected override uint MaxSampleRateHz => 500000;
|
||||
|
||||
public override long MaxMemory()
|
||||
{
|
||||
if (null == DASInfo || 0 == DASInfo.NumberOfBytesPerSampleClock) { return 0; }
|
||||
|
||||
if (null == DASInfo.MaxEventStorageSpaceInBytes)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (long)(DASInfo.MaxEventStorageSpaceInBytes / DASInfo.NumberOfBytesPerSampleClock);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// calculates the max sample rate
|
||||
/// these are not exact max sample rates, but convenient close enough limits
|
||||
/// drop 100k every module after 3 (starting at 500k)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override uint MaxSampleRate(int numberOfConfiguredChannels)
|
||||
{
|
||||
switch (DASInfo.Modules.Length)
|
||||
{
|
||||
case 1:
|
||||
return MaxSampleRateHz;
|
||||
case 2:
|
||||
return 400000;
|
||||
case 3:
|
||||
return 300000;
|
||||
case 4:
|
||||
default:
|
||||
return 200000;
|
||||
}
|
||||
}
|
||||
|
||||
public override uint MaxAAFilterRate()
|
||||
{
|
||||
return MaxAAFilterRateHz;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// QueryEventData also is customized for SLICE 1.5, it needs to perform SLICE 1.5 specific data marshalling
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override QueryEventDataBase GetQueryEventData()
|
||||
{
|
||||
return new QueryEventData_SLICE1_5(this, AbstractCommandBase.Default_IO_Timeout);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// this meaty class handles skipping parts of the download not needed (start of page to desired start sample)
|
||||
/// [also note we'll need to do the same thing with the end sample too if we want to use the ECC properly,
|
||||
/// but ECC isn't even implemented yet ...]
|
||||
/// </summary>
|
||||
public class QueryEventData_SLICE1_5 : QueryEventDataBase
|
||||
{
|
||||
public override UInt64 FirstSample
|
||||
{
|
||||
get => base.FirstSample;
|
||||
set => base.FirstSample = value;
|
||||
}
|
||||
|
||||
public override UInt64 LastSample
|
||||
{
|
||||
get => base.LastSample;
|
||||
set => base.LastSample = value;
|
||||
}
|
||||
public QueryEventData_SLICE1_5(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock) { LogCommands = false; }
|
||||
|
||||
public QueryEventData_SLICE1_5(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec) { LogCommands = false; }
|
||||
|
||||
private ulong GetRequestedStartSport()
|
||||
{
|
||||
var slice15Usb = recorder as SLICE1_5<WINUSBConnection>;
|
||||
if (recorder is SLICE1_5<EthernetConnection> slice15Ethernet)
|
||||
{
|
||||
return ((WhatToDownloadSlice2)slice15Ethernet.WhatToDownload).RequestedStartSport;
|
||||
}
|
||||
if (null != slice15Usb)
|
||||
{
|
||||
return ((WhatToDownloadSlice2)slice15Usb.WhatToDownload).RequestedStartSport;
|
||||
}
|
||||
throw new NotSupportedException("SLICE1_5::GetRequestedStartSport not supported for " + recorder.ConnectString);
|
||||
}
|
||||
private void PushLeftOverData(ushort[] daters)
|
||||
{
|
||||
var slice15Usb = recorder as SLICE1_5<WINUSBConnection>;
|
||||
var slice15Ethernet = recorder as SLICE1_5<EthernetConnection>;
|
||||
if (null != slice15Usb) { slice15Usb.PushLeftOverData(daters); }
|
||||
else
|
||||
{
|
||||
slice15Ethernet?.PushLeftOverData(daters);
|
||||
}
|
||||
}
|
||||
protected override CommandReceiveAction WholePackagePost()
|
||||
{
|
||||
// now send the data to the user
|
||||
var stat = CommandStatus.Success;
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
var s = (int)response.Status;
|
||||
APILogger.LogString("QueryEventData.WholePackagePost: reporting failure, status==" + CommandPacketBase.StatusLabels[s] + " (0x" + s.ToString("X") + ")");
|
||||
stat = CommandStatus.Failure;
|
||||
}
|
||||
|
||||
var cbReport = new QueryEventDataReport(stat, UserCallbackData);
|
||||
cbReport.Data = new short[_channelsDownloaded][];
|
||||
|
||||
for (var i = 0; i < _channelsDownloaded; i++)
|
||||
GetChannelData(i, out cbReport.Data[i]);
|
||||
|
||||
//we have processed some data, but there may be some left over (since data isn't channel sample aligned ...)
|
||||
//figure out what we used and what's left over
|
||||
//now we have two situations, one, we have already skimmed beyond all the data we need
|
||||
//or two, we are somewhere in between, we need to skip a few samples
|
||||
|
||||
var requestedStartSpot = GetRequestedStartSport();
|
||||
|
||||
if ((FirstSample + (ulong)_data.Length) < requestedStartSpot)
|
||||
{
|
||||
//push no data, we don't want it!
|
||||
}
|
||||
else if (FirstSample > requestedStartSpot)
|
||||
{//we want everything in here ...
|
||||
var samplesProcessed = Convert.ToInt32(Math.Truncate(_data.Length / (double)ChannelsDownloaded));
|
||||
var leftover = new ushort[_data.Length - (samplesProcessed * ChannelsDownloaded)];
|
||||
for (var i = 0; i < leftover.Length; i++)
|
||||
{
|
||||
leftover[i] = _data[i + samplesProcessed * ChannelsDownloaded];
|
||||
}
|
||||
PushLeftOverData(leftover);
|
||||
}
|
||||
else
|
||||
{
|
||||
//we need to calculate samples only from the start of the data we are interested in
|
||||
var offset = Convert.ToInt32(requestedStartSpot - FirstSample);
|
||||
var samplesProcessed = Convert.ToInt32(Math.Truncate((_data.Length - (double)offset) / ChannelsDownloaded));
|
||||
var leftover = new ushort[(_data.Length - offset) - (samplesProcessed * ChannelsDownloaded)];
|
||||
for (var i = 0; i < leftover.Length; i++)
|
||||
{
|
||||
leftover[i] = _data[i + offset + samplesProcessed * ChannelsDownloaded];
|
||||
}
|
||||
PushLeftOverData(leftover);
|
||||
}
|
||||
|
||||
return UserCallback(cbReport);
|
||||
}
|
||||
|
||||
protected virtual ushort[] PopLeftOverData()
|
||||
{
|
||||
var slice15Usb = recorder as SLICE1_5<WINUSBConnection>;
|
||||
var slice15Ethernet = recorder as SLICE1_5<EthernetConnection>;
|
||||
if (null != slice15Usb)
|
||||
{
|
||||
return slice15Usb.PopLeftOverData();
|
||||
}
|
||||
if (null != slice15Ethernet)
|
||||
{
|
||||
return slice15Ethernet.PopLeftOverData();
|
||||
}
|
||||
throw new NotSupportedException("SLICE1_5::PopLeftOverData not supported for " + recorder.ConnectString);
|
||||
}
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
//we are going to process the data shortly, but before we do we'll need to
|
||||
//pre-pend any left over data we have to the new incoming data
|
||||
//since we already count the samples downloaded for samples in the left over stuff
|
||||
//we don't need to recount it, just the new incoming samples
|
||||
_samplesDownloaded = (ulong)(response.Parameter.Length) / 2;
|
||||
var leftover = PopLeftOverData();
|
||||
_data = new ushort[_samplesDownloaded + (ulong)leftover.Length];
|
||||
leftover.CopyTo(_data, 0);
|
||||
for (var i = 0; (ulong)i < _samplesDownloaded; i++)
|
||||
{
|
||||
response.GetParameter(2 * i, out _data[i + leftover.Length]);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void GetChannelData(int channel, out short[] signedADC)
|
||||
{
|
||||
if (channel < 0 || channel > _channelsDownloaded)
|
||||
{
|
||||
throw new ApplicationException("QueryEventData.GetChannelData: Data requested on a channel that wasn't downloaded.");
|
||||
}
|
||||
|
||||
//first short circuit if we know we are still completely skipping data
|
||||
if (((ulong)_data.Length + FirstSample) < GetRequestedStartSport())//(slice2.WhatToDownload as WhatToDownloadSlice2).RequestedStartSport)
|
||||
{
|
||||
signedADC = new short[0];//nothing to see here (we are completely before the start of our requested data)
|
||||
return;
|
||||
}
|
||||
|
||||
//now we have two situations, one, we have already skimmed beyond all the data we need
|
||||
//or two, we are somewhere in between, we need to skip a few samples
|
||||
var offset = 0;
|
||||
if (GetRequestedStartSport() > FirstSample)
|
||||
{
|
||||
offset = Convert.ToInt32(GetRequestedStartSport() - FirstSample);
|
||||
}
|
||||
|
||||
// Data order for a 9 channel stack
|
||||
// 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 etc.
|
||||
ushort val;
|
||||
var rv = new List<short>(1024);
|
||||
|
||||
System.Diagnostics.Trace.Assert(_data.Length > offset, @"data length is less than offset");
|
||||
|
||||
var completeSamples = Convert.ToInt32(Math.Truncate((_data.Length - offset) / (double)ChannelsDownloaded));
|
||||
|
||||
for (var i = 0; i < completeSamples; i++)
|
||||
{
|
||||
val = _data[i * ChannelsDownloaded + channel + offset];
|
||||
rv.Add((short)((((val & 0x00FF) << 8) | ((val >> 8) & 0x00FF)) + 0x8000));
|
||||
}
|
||||
signedADC = rv.ToArray();
|
||||
}
|
||||
// this function isn't used by SLICEWare, but it is used by the FirmwareTestUtility
|
||||
// SW uses the GetChannelData above
|
||||
public override void GetRawIndexedData(int index, out ushort[] data)
|
||||
{
|
||||
data = new ushort[_samplesDownloaded];
|
||||
for (var i = 0; i < data.Length; i++)
|
||||
{
|
||||
data[i] = _data[i + index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5714
DataPRO/IService/Classes/SLICE/SLICE2.cs
Normal file
5714
DataPRO/IService/Classes/SLICE/SLICE2.cs
Normal file
File diff suppressed because it is too large
Load Diff
1135
DataPRO/IService/Classes/SLICE/SLICE6.cs
Normal file
1135
DataPRO/IService/Classes/SLICE/SLICE6.cs
Normal file
File diff suppressed because it is too large
Load Diff
1654
DataPRO/IService/Classes/SLICE/SLICE6AIR.cs
Normal file
1654
DataPRO/IService/Classes/SLICE/SLICE6AIR.cs
Normal file
File diff suppressed because it is too large
Load Diff
281
DataPRO/IService/Classes/SLICE/SLICE6AIRBR.cs
Normal file
281
DataPRO/IService/Classes/SLICE/SLICE6AIRBR.cs
Normal file
@@ -0,0 +1,281 @@
|
||||
using DTS.Common.Constant.DASSpecific;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class SLICE6AIRBR<T> : SLICE6_Base<T>, IAlignUDPToPPSAware where T : IConnection, new()
|
||||
{
|
||||
public bool AlignUDPToPPS { get; set; }
|
||||
public override bool SupportsRemoveLeapSeconds => true;
|
||||
public override bool SupportsADCSamplesPerPacket => true;
|
||||
protected override bool RequiresNon0QualificationSamples => true;
|
||||
protected override byte[] GetRTChannelIndices(RealTimeAsyncPacket packet)
|
||||
{
|
||||
return new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
|
||||
}
|
||||
public override void SetIsStreamingSupported(bool supported)
|
||||
{
|
||||
IsStreamingSupported = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// the order of this DAS among multiple das
|
||||
/// </summary>
|
||||
public int DASIndex { get; set; } = -1;
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 6.0 Protocol Limitations
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArm] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmRepeatEnable] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDefaultMIF] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackSensors] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.TestCommunication] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackLowPowerMode] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetRealtimeSampleRate] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.LevelTrigger] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AttributeStoreBlocks] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MaxEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmDiagnosticDelay] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackChannelAutoArmDiagLevel] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FlashClear] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleSamplesRealtime] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.DiangosShuntDAC] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageInsertion] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPTimestamp] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRecDelayInSecond] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryTiltSensorData] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InSliceTiltSensorADCPre] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRealtimeStream] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.UDPRealtimeStream] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.GenerateEvent] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPSyncStatus] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetClockSyncConfig] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDSPFilterSettings] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPDomainID] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ActiveRAM] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.RecordAndStreamSubSample] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.RemoveLeapSeconds] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.RecordOnBoot] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.UDPAlignOnPPS] = SLICE6AIRBR.UDPALIGNONPPS_PROTOCOL;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ADCSamplesPerPacket] = SLICE6AIRBR.ADC_SAMPLES_PER_PACKET_VER;
|
||||
MinimumProtocols = SLICE6AIR_BR_MinimumProtocols;
|
||||
}
|
||||
|
||||
#region protocol settings/overrides
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> SLICE6AIR_BR_MinimumProtocols =
|
||||
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
protected override int MIN_PROTOCOL_TMATS_INTERVAL => SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
private uint maxSampleRateHz = 0;
|
||||
protected override uint MaxSampleRateHz
|
||||
{
|
||||
get
|
||||
{
|
||||
if (0 == maxSampleRateHz)
|
||||
{
|
||||
try
|
||||
{
|
||||
var qsa = new QuerySystemAttributeSLICE6(this)
|
||||
{
|
||||
Key = AttributeTypes.SystemAttributesSLICE6.MaximumSampleRate
|
||||
};
|
||||
qsa.SyncExecute();
|
||||
maxSampleRateHz = (uint)qsa.Value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Error getting S6A-BR max sample rate, returning 50K");
|
||||
APILogger.LogException(ex);
|
||||
return 50000;
|
||||
}
|
||||
}
|
||||
return maxSampleRateHz;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected override DASModule MakeConfigModuleFromInfoModule(InfoResult.Module infoModule)
|
||||
{
|
||||
//per LP: can stream, no IEPE
|
||||
var configModule = new DASModule(infoModule.ModuleArrayIndex, this);
|
||||
configModule.Channels = new DASChannel[infoModule.NumberOfChannels];
|
||||
|
||||
for (var i = 0; i < infoModule.NumberOfChannels; i++)
|
||||
{
|
||||
if (DFConstantsAndEnums.ModuleType.StreamOut == configModule.ModuleType())
|
||||
{
|
||||
var streamOutChannel = new StreamOutputDASChannel(configModule, i);
|
||||
configModule.Channels[i] = streamOutChannel;
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = new AnalogInputDASChannel(configModule, i);
|
||||
|
||||
channel.SupportedBridges = new SensorConstants.BridgeType[]
|
||||
{
|
||||
SensorConstants.BridgeType.FullBridge,
|
||||
SensorConstants.BridgeType.HalfBridge,
|
||||
};
|
||||
configModule.Channels[i] = channel;
|
||||
}
|
||||
}
|
||||
|
||||
return configModule;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// we can probably simplify and take common items (slice6+slice1) out of this function, but for now
|
||||
/// it's mostly a copy of SLICE1.AsyncConfigure
|
||||
/// </summary>
|
||||
/// <param name="configAsyncInfo"></param>
|
||||
protected override void AsyncConfigure(object configAsyncInfo)
|
||||
{
|
||||
var info = configAsyncInfo as SliceConfigServiceAsyncInfo;
|
||||
SetUDPAlignOnPPS();
|
||||
SetRemoveSeconds();
|
||||
if ((info.StreamADCPerPacket != null) && info.StreamADCPerPacket.ContainsKey(this))
|
||||
{
|
||||
SetADCSamplesPerPacket(info.StreamADCPerPacket[this]);
|
||||
}
|
||||
|
||||
//12638 DAS does not record data in recorder mode during calibration ~ 40% of time.
|
||||
//for SLICE6 we call reseteventlist here, prior to configuring and NOT before arming
|
||||
ResetEventListPriorToConfigure();
|
||||
|
||||
int progressValue = 0;
|
||||
bool bReleased = true;
|
||||
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.ProgramStackChannels))
|
||||
{
|
||||
ReconfigureAccordingToConfig();
|
||||
}
|
||||
|
||||
PresetSampleRate();
|
||||
|
||||
SetVoltageRequirements();
|
||||
|
||||
SetPolarity();
|
||||
|
||||
SetArmDisableShortCheck();
|
||||
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
bReleased = false;
|
||||
// loop thru the modules (slices) and configure the non-UART channels
|
||||
var numChannels = DASInfo.Modules.Sum(mod => mod.NumberOfChannels);
|
||||
var numStreamingChannels = DASInfo.Modules.Sum(mod => DFConstantsAndEnums.ModuleType.StreamOut == mod.TypeOfModule ? mod.NumberOfChannels : 0);
|
||||
var rangeArray = new float[numChannels];
|
||||
//var IsHalfBridgeArray = new bool[numChannels];
|
||||
var bridgeModeArray = new byte[numChannels];
|
||||
var BridgeResistanceArray = new ushort[numChannels];
|
||||
var IsACCoupledArray = new bool[numChannels];
|
||||
//18294 Implement Bridge AC / DC coupling(fw update dependent)
|
||||
var bridgeACCouplingArray = new bool[numChannels];
|
||||
// level trigger values
|
||||
var enableLowerLevelTriggerThreshold = new bool[numChannels];
|
||||
var enableUpperLevelTriggerThreshold = new bool[numChannels];
|
||||
var lowerLevelTriggerThreshold = new float[numChannels];
|
||||
var upperLevelTriggerThreshold = new float[numChannels];
|
||||
var qualificationSamples = new int[numChannels];
|
||||
|
||||
var diagnosticChannels = new List<byte>();
|
||||
|
||||
var bModified = false;
|
||||
CommonConfigureWork(diagnosticChannels, qualificationSamples, ref bReleased,
|
||||
info, bridgeModeArray, IsACCoupledArray, BridgeResistanceArray,
|
||||
ref bModified, rangeArray, enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold,
|
||||
enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold, bridgeACCouplingArray);
|
||||
if (bReleased) { return; }
|
||||
// report progress
|
||||
progressValue = 5;
|
||||
info.Progress(progressValue);
|
||||
|
||||
StoreConfigAttributes(info, rangeArray, ref bReleased, ref progressValue, bridgeModeArray,
|
||||
IsACCoupledArray, BridgeResistanceArray, enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold,
|
||||
enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold, qualificationSamples, numChannels,
|
||||
out var config, bridgeACCouplingArray, 0, numStreamingChannels);
|
||||
|
||||
progressValue = 20;
|
||||
info.Progress(progressValue);
|
||||
|
||||
RemainingConfigWork(ref progressValue, info, diagnosticChannels, config, ref bReleased, null, null, null);
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Cancel();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Error(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
info.Progress(100);
|
||||
info.Success();
|
||||
}
|
||||
/// <summary>
|
||||
/// returns true if the device is known to be streaming
|
||||
/// does not query device, just returns a flag if it has been set
|
||||
/// </summary>
|
||||
public override bool GetIsStreaming()
|
||||
{
|
||||
if (null == DASArmStatus) { return false; }
|
||||
//18852 Cannot use Stop streaming / (Dis)Auto Arm button if one or more DAS is idle
|
||||
//can't rely on just having received invalid mode, QATS will still have a status of realtime
|
||||
//when streaming, so we'll use either for now.
|
||||
return DASArmStatus.ReceivedInvalidModeDuringSetup || DASArmStatus.IsInRealtime;
|
||||
}
|
||||
}
|
||||
}
|
||||
693
DataPRO/IService/Classes/SLICE/SLICE6AIRTC.cs
Normal file
693
DataPRO/IService/Classes/SLICE/SLICE6AIRTC.cs
Normal file
@@ -0,0 +1,693 @@
|
||||
using DTS.Common.Classes.DASFactory;
|
||||
using DTS.Common.Constant.DASSpecific;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.Common.Interface.DASFactory.Download;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.DASLib.Command;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.DASLib.Command.SLICE.RealtimeCommands;
|
||||
using DTS.DASLib.Service.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using static DTS.Common.Enums.DASFactory.DFConstantsAndEnums;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
#pragma warning disable S101 // Types should be named in PascalCase
|
||||
public class SLICE6AIRTC<T> : SLICE6_Base<T>, IAlignUDPToPPSAware, IDASReconfigure, ITCDiagnosticResults, IUARTDownloadActions,
|
||||
IUARTDownload where T : IConnection, new()
|
||||
#pragma warning restore S101 // Types should be named in PascalCase
|
||||
{
|
||||
public IUARTDownloadRequest WhatUARTToDownload { get; set; }
|
||||
public void SetWhatUARTToDownload(IUARTDownloadRequest request, bool bSetInDb = true)
|
||||
{
|
||||
UARTDownloadRequest.SetWhatToDownload(this, request, bSetInDb);
|
||||
}
|
||||
public uint BaudRate { get; private set; }
|
||||
public uint DataBits { get; private set; }
|
||||
public StopBits StopBits { get; private set; }
|
||||
public Parity Parity { get; private set; }
|
||||
public Handshake FlowControl { get; private set; }
|
||||
public UartDataFormat DataFormat { get; private set; }
|
||||
public void UARTDownload(ServiceCallback callback, object userData)
|
||||
{
|
||||
var state = new SliceUARTDownloadState(callback, userData, null);
|
||||
state.Error("Not supported");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve UART info about available events to download
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
void IUARTDownloadActions.QueryUARTDownload(ServiceCallback callback, object userData, int eventIndex, TDASServiceSetupInfo setupInfo)
|
||||
{
|
||||
var info = new QueryDownloadAsyncInfo(callback, userData, eventIndex);
|
||||
LaunchAsyncWorker("Slice.QueryUARTDownload", AsyncQueryUARTDownload, info);
|
||||
}
|
||||
|
||||
protected virtual void AsyncQueryUARTDownload(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is QueryDownloadAsyncInfo info)) { return; }
|
||||
if (!IsCommandSupported(ProtocolLimitedCommands.QueryUARTDownload))
|
||||
{
|
||||
info.Error("Query UART download is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
void IUARTDownloadActions.GetUARTSettings(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("Slice.GetUARTSettings", AsyncGetUARTSettings, info);
|
||||
}
|
||||
|
||||
protected virtual void AsyncGetUARTSettings(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is SliceServiceAsyncInfo info)) { return; }
|
||||
if (!IsCommandSupported(ProtocolLimitedCommands.GetUARTSettings))
|
||||
{
|
||||
info.Error("Get UART settings is not supported");
|
||||
return;
|
||||
}
|
||||
var bLocked = false;
|
||||
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
bLocked = true;
|
||||
|
||||
try
|
||||
{
|
||||
var qsaUARTSettings = new QuerySystemAttributeSLICE6AIR(this, AbstractCommandBase.Default_IO_Timeout);
|
||||
qsaUARTSettings.Key = AttributeTypes.SystemAttributesSLICE6AIR.S6A_GpsCanUARTSettings;
|
||||
qsaUARTSettings.SyncExecute();
|
||||
//we made it, set results
|
||||
var uartSettings = (uint[])qsaUARTSettings.Value;
|
||||
|
||||
BaudRate = uartSettings[0];
|
||||
DataBits = uartSettings[1];
|
||||
StopBits = (StopBits)uartSettings[2];
|
||||
Parity = (Parity)uartSettings[3];
|
||||
FlowControl = (Handshake)uartSettings[4];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Problem getting UART settings", ex);
|
||||
}
|
||||
|
||||
bLocked = false;
|
||||
Release();
|
||||
info.Success();
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
if (bLocked)
|
||||
{
|
||||
bLocked = false;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Cancel();
|
||||
}
|
||||
catch (CommandException ce)
|
||||
{
|
||||
if (bLocked)
|
||||
{
|
||||
Release();
|
||||
bLocked = false;
|
||||
}
|
||||
|
||||
straightFailures++;
|
||||
if (straightFailures > PERMITTED_FAILURES)
|
||||
{
|
||||
APILogger.Log("GetUARTSettings error - has failed ", straightFailures, " times, giving up", ce);
|
||||
info.Error(ce.Message, ce);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.Success();
|
||||
APILogger.Log("GetUARTSettings error", ce);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (bLocked)
|
||||
{
|
||||
bLocked = false;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Error(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (bLocked)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IUARTDownloadActions.SetUARTSettings(ServiceCallback callback, object userData, uint baudRate, uint dataBits, uint stopBits, uint parity, uint flowControl)
|
||||
{
|
||||
var info = new SetUARTSettingsAsyncInfo(callback, userData, baudRate, dataBits, stopBits, parity, flowControl);
|
||||
LaunchAsyncWorker("Slice.SetUARTSettings", AsyncSetUARTSettings, info);
|
||||
}
|
||||
|
||||
protected virtual void AsyncSetUARTSettings(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is SetUARTSettingsAsyncInfo info)) { return; }
|
||||
if (!IsCommandSupported(ProtocolLimitedCommands.SetUARTSettings))
|
||||
{
|
||||
info.Error("Set UART settings is not supported");
|
||||
return;
|
||||
}
|
||||
var bLocked = false;
|
||||
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
bLocked = true;
|
||||
var value = new uint[] { info.BaudRate, info.DataBits, info.StopBits, info.Parity, info.FlowControl };
|
||||
try
|
||||
{
|
||||
var ssaUARTSettings =
|
||||
new SetSystemAttributeSLICE6AIR(this, AbstractCommandBase.Default_IO_Timeout);
|
||||
ssaUARTSettings.SetValue(AttributeTypes.SystemAttributesSLICE6AIR.S6A_GpsCanUARTSettings,
|
||||
value, true);
|
||||
ssaUARTSettings.SyncExecute();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Problem setting UART settings", ex);
|
||||
}
|
||||
|
||||
bLocked = false;
|
||||
Release();
|
||||
info.Success();
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
if (bLocked)
|
||||
{
|
||||
bLocked = false;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Cancel();
|
||||
}
|
||||
catch (CommandException ce)
|
||||
{
|
||||
if (bLocked)
|
||||
{
|
||||
Release();
|
||||
bLocked = false;
|
||||
}
|
||||
|
||||
straightFailures++;
|
||||
if (straightFailures > PERMITTED_FAILURES)
|
||||
{
|
||||
APILogger.Log("SetUARTSettings error - has failed ", straightFailures, " times, giving up", ce);
|
||||
info.Error(ce.Message, ce);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.Success();
|
||||
APILogger.Log("SetUARTSettings error", ce);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (bLocked)
|
||||
{
|
||||
bLocked = false;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Error(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (bLocked)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
public ITCDiagnosticResult[] TCDiagnosticResults { get; private set; } = new ITCDiagnosticResult[0];
|
||||
public void ClearTCDiagnosticResults()
|
||||
{
|
||||
TCDiagnosticResults = new ITCDiagnosticResult[0];
|
||||
}
|
||||
public void SetTCDiagnosticResults(ITCDiagnosticResult[] results)
|
||||
{
|
||||
TCDiagnosticResults = results;
|
||||
}
|
||||
private void InitializeTCDiagnostics()
|
||||
{
|
||||
TCDiagnosticResults = new TCDiagnosticResult[24];
|
||||
for (var i = 0; i < TCDiagnosticResults.Length; i++)
|
||||
{
|
||||
TCDiagnosticResults[i] = new TCDiagnosticResult()
|
||||
{
|
||||
ChannelIndex = i,
|
||||
ChannelName = GetChannelName(i),
|
||||
Status = Common.Interface.Sensors.AnalogDiagnostics.DiagnosticStatus.Untested,
|
||||
CurrentReading = null
|
||||
};
|
||||
}
|
||||
}
|
||||
protected override void AsyncDiagnosAndGetResults(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is SliceServiceAsyncInfo info)) { return; }
|
||||
InitializeTCDiagnostics();
|
||||
_ = MeasureOffsets(info);
|
||||
_ = MeasureShunts(info);
|
||||
base.AsyncDiagnosAndGetResults(asyncInfo);
|
||||
}
|
||||
private bool MeasureShunts(SliceServiceAsyncInfo info)
|
||||
{
|
||||
try
|
||||
{
|
||||
var queryChannelShuntResults = new QueryChannelShuntResults(this);
|
||||
queryChannelShuntResults.DeviceID = 0; // send to base
|
||||
byte[] shuntChannelList = new byte[TCDiagnosticResults.Length];
|
||||
int channelCounter = 0;
|
||||
for (int idx = 0; idx < TCDiagnosticResults.Length; idx++)
|
||||
{
|
||||
shuntChannelList[channelCounter] = (byte)TCDiagnosticResults[idx].ChannelIndex;
|
||||
channelCounter++;
|
||||
}
|
||||
queryChannelShuntResults.StackChannelList = shuntChannelList;
|
||||
queryChannelShuntResults.SyncExecute();
|
||||
for( var idx = 0; idx < TCDiagnosticResults.Length; idx++)
|
||||
{
|
||||
var actual = queryChannelShuntResults.ActualDeflectionMV[idx];
|
||||
if (Utils.IsZero(actual))
|
||||
{
|
||||
TCDiagnosticResults[idx].ConnectionStatus = ConnectionStatuses.ModuleNotConnected;
|
||||
}
|
||||
else if (Utils.AlmostEqual(actual, 100))
|
||||
{
|
||||
TCDiagnosticResults[idx].ConnectionStatus = ConnectionStatuses.Connected;
|
||||
}
|
||||
else { TCDiagnosticResults[idx].ConnectionStatus = ConnectionStatuses.NotConnected; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch( Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
info.Error($"Failed to check connections [{SerialNumber}] - {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private bool MeasureOffsets(SliceServiceAsyncInfo info)
|
||||
{
|
||||
try
|
||||
{
|
||||
var measureOffset = new RetrieveSampleAverage(this);
|
||||
measureOffset.DeviceID = 0; // send to base
|
||||
measureOffset.Samples = 4000;
|
||||
if (measureOffset.Samples < 1) { measureOffset.Samples = 1; }
|
||||
measureOffset.SyncExecute();
|
||||
for( var i = 0; i < TCDiagnosticResults.Length; i++)
|
||||
{
|
||||
var result = TCDiagnosticResults[i];
|
||||
result.CurrentReading = measureOffset.GetChannelData(result.ChannelIndex) * .1D;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
info.Error($"Failed to retrieve average temperatures [{SerialNumber}] - {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private string GetChannelName(int index)
|
||||
{
|
||||
if (null == ((IDASCommunication)this).ConfigData) { return string.Empty; }
|
||||
var config = ((IDASCommunication)this).ConfigData;
|
||||
if (config.Modules == null || 0 == config.Modules.Length) { return string.Empty; }
|
||||
var match = Array.Find(config.Modules[0].Channels, x => x.Number == index);
|
||||
if (null == match) { return string.Empty; }
|
||||
return string.IsNullOrWhiteSpace(match.UserChannelName) ? match.IsoChannelName : match.UserChannelName;
|
||||
}
|
||||
|
||||
private const int MAX_TMATS_FILE_LENGTH = 32000;
|
||||
public override bool IsSlice6AirTc()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override int GetMaxFileLengthTMATS()
|
||||
{
|
||||
return MAX_TMATS_FILE_LENGTH;
|
||||
}
|
||||
public bool AlignUDPToPPS { get; set; }
|
||||
public override bool SupportsRemoveLeapSeconds => true;
|
||||
public override bool SupportsADCSamplesPerPacket => true;
|
||||
protected override bool RequiresNon0QualificationSamples => true;
|
||||
protected override byte[] GetRTChannelIndices(RealTimeAsyncPacket packet)
|
||||
{
|
||||
switch(_maxModuleCount)
|
||||
{
|
||||
case 0:
|
||||
return new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
|
||||
case 1:
|
||||
return new byte[] { 0, 1, 2, 3, 4, 5 ,6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||
case 2:
|
||||
default:
|
||||
return new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
|
||||
|
||||
}
|
||||
}
|
||||
protected override IGetRealtimeSamples GetRealtimeSamplesClass(DTS.Common.Interface.DASFactory.ICommunication iCommunication, bool bPolling = false)
|
||||
{
|
||||
if (IsCommandSupported(ProtocolLimitedCommands.StartRealtimeStream) && !bPolling)
|
||||
{
|
||||
return new RealtimeStreamingNextSamples(iCommunication) { SignedData = true };
|
||||
}
|
||||
return base.GetRealtimeSamplesClass(this, bPolling);
|
||||
}
|
||||
public override void SetIsStreamingSupported(bool supported = false)
|
||||
{
|
||||
IsStreamingSupported = true;
|
||||
}
|
||||
///// <summary>
|
||||
///// the order of this DAS among multiple das
|
||||
///// </summary>
|
||||
//public int DASIndex { get; set; } = -1;
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 6.0 Protocol Limitations
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.AutoArm] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.AutoArmRepeatEnable] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.SetDefaultMIF] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.FileData] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.StackSensors] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.BaseSystemTime] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.TestCommunication] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.StackLowPowerMode] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.SetRealtimeSampleRate] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.SLICE2_OneWireID] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.HardwareRevision] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.HardwareConfiguration] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.EventFaultFlags] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.EventArmAttempts] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.QueryActualSampleRateImmediate] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.InitHardwareInputLines] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.VoltageSysAttributes] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.AttributeStoreBlocks] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.MaxEvents] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.AutoArmDiagnosticDelay] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.StackChannelAutoArmDiagLevel] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.FlashClear] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.MultipleSamplesRealtime] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.BaseCalibrationDate] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.IgnoreShortedStartEvent] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.ResetAttributeStore] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.PTPTimestamp] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.StartRealtimeStream] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.UDPRealtimeStream] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.GenerateEvent] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.PTPSyncStatus] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.SetClockSyncConfig] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.SetDSPFilterSettings] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.PTPDomainID] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.RemoveLeapSeconds] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.UDPAlignOnPPS] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.ADCSamplesPerPacket] = SLICE6AIRTC.ADC_SAMPLES_PER_PACKET_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.GetUARTSettings] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.SetUARTSettings] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.AutoArmUDPSetting] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_TC_MinimumProtocols[ProtocolLimitedCommands.AutoArmRecordDelay] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
MinimumProtocols = SLICE6AIR_TC_MinimumProtocols;
|
||||
}
|
||||
protected class S6ATCConfigAttributes : SLICE6ConfigAttributes
|
||||
{
|
||||
public override void ConfigureCoupling(bool[] IsACCoupledArray)
|
||||
{
|
||||
//not supported in S6ATC - so NOOP
|
||||
}
|
||||
public override void ConfigureBridge(byte[] bridgeModeArray)
|
||||
{
|
||||
//not supported in S6A-TC - so NOOP
|
||||
}
|
||||
public override void ConfigureBridgeResistance(ushort[] BridgeResistanceArray)
|
||||
{
|
||||
//not supported in S6A-TC - so NOOP
|
||||
}
|
||||
|
||||
public S6ATCConfigAttributes(ICommunication _com) : base(_com) { }
|
||||
}
|
||||
|
||||
protected override ConfigAttributes GetConfigAttributes(ICommunication com)
|
||||
{
|
||||
return new S6ATCConfigAttributes(this);
|
||||
}
|
||||
#region protocol settings/overrides
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> SLICE6AIR_TC_MinimumProtocols =
|
||||
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
protected override int MIN_PROTOCOL_TMATS_INTERVAL => SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
private uint maxSampleRateHz = 0;
|
||||
protected override uint MaxSampleRateHz
|
||||
{
|
||||
get
|
||||
{
|
||||
if (0 == maxSampleRateHz)
|
||||
{
|
||||
try
|
||||
{
|
||||
var qsa = new QuerySystemAttributeSLICE6(this)
|
||||
{
|
||||
Key = AttributeTypes.SystemAttributesSLICE6.MaximumSampleRate
|
||||
};
|
||||
qsa.SyncExecute();
|
||||
maxSampleRateHz = (uint)qsa.Value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Error getting S6A-BR max sample rate, returning 50K");
|
||||
APILogger.LogException(ex);
|
||||
return 50000;
|
||||
}
|
||||
}
|
||||
return maxSampleRateHz;
|
||||
}
|
||||
}
|
||||
void IDASReconfigure.SetMaxModuleCount(int count)
|
||||
{
|
||||
SetMaxModuleCount(count, false);
|
||||
_maxModuleCount = count;
|
||||
}
|
||||
private int _maxModuleCount = -1;
|
||||
/// <summary>
|
||||
/// gets the physical max number of modules.
|
||||
/// this value is cached
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
int IDASReconfigure.GetMaxModuleCount()
|
||||
{
|
||||
_maxModuleCount = GetMaxModuleCount(_maxModuleCount);
|
||||
return _maxModuleCount;
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected override DASModule MakeConfigModuleFromInfoModule(InfoResult.Module infoModule)
|
||||
{
|
||||
var configModule = new DASModule(infoModule.ModuleArrayIndex, this);
|
||||
configModule.Channels = new DASChannel[infoModule.NumberOfChannels];
|
||||
|
||||
for (var i = 0; i < infoModule.NumberOfChannels; i++)
|
||||
{
|
||||
if (ModuleType.StreamOut == configModule.ModuleType())
|
||||
{
|
||||
var streamOutChannel = new StreamOutputDASChannel(configModule, i);
|
||||
configModule.Channels[i] = streamOutChannel;
|
||||
}
|
||||
else if ( ModuleType.UART == configModule.ModuleType())
|
||||
{
|
||||
configModule.Channels[i] = new UARTInputDASChannel(configModule, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = new AnalogInputDASChannel(configModule, i);
|
||||
|
||||
channel.SupportedBridges = new SensorConstants.BridgeType[]
|
||||
{
|
||||
SensorConstants.BridgeType.FullBridge,
|
||||
SensorConstants.BridgeType.HalfBridge,
|
||||
};
|
||||
configModule.Channels[i] = channel;
|
||||
}
|
||||
}
|
||||
|
||||
return configModule;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// we can probably simplify and take common items (slice6+slice1) out of this function, but for now
|
||||
/// it's mostly a copy of SLICE1.AsyncConfigure
|
||||
/// </summary>
|
||||
/// <param name="configAsyncInfo"></param>
|
||||
protected override void AsyncConfigure(object configAsyncInfo)
|
||||
{
|
||||
var info = configAsyncInfo as SliceConfigServiceAsyncInfo;
|
||||
SetUDPAlignOnPPS();
|
||||
SetRemoveSeconds();
|
||||
SetADCSamplesPerPacket(info.StreamADCPerPacket[this]);
|
||||
|
||||
//12638 DAS does not record data in recorder mode during calibration ~ 40% of time.
|
||||
//for SLICE6 we call reseteventlist here, prior to configuring and NOT before arming
|
||||
ResetEventListPriorToConfigure();
|
||||
|
||||
int progressValue = 0;
|
||||
bool bReleased = true;
|
||||
|
||||
if (IsCommandSupported(ProtocolLimitedCommands.ProgramStackChannels))
|
||||
{
|
||||
ReconfigureAccordingToConfig();
|
||||
}
|
||||
|
||||
PresetSampleRate();
|
||||
|
||||
SetVoltageRequirements();
|
||||
|
||||
SetPolarity();
|
||||
|
||||
SetArmDisableShortCheck();
|
||||
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
bReleased = false;
|
||||
// loop thru the modules (slices) and configure the non-UART channels
|
||||
var numChannels = DASInfo.Modules.Sum(mod => mod.NumberOfChannels);
|
||||
var numStreamingChannels = DASInfo.Modules.Sum(mod => ModuleType.StreamOut == mod.TypeOfModule ? mod.NumberOfChannels : 0);
|
||||
var numUart = DASInfo.Modules.Sum(mod => ModuleType.UART == mod.TypeOfModule ? mod.NumberOfChannels : 0);
|
||||
var rangeArray = new float[numChannels];
|
||||
var bridgeModeArray = new byte[numChannels];
|
||||
var BridgeResistanceArray = new ushort[numChannels];
|
||||
var IsACCoupledArray = new bool[numChannels];
|
||||
//18294 Implement Bridge AC / DC coupling(fw update dependent)
|
||||
var bridgeACCouplingArray = new bool[numChannels];
|
||||
// level trigger values
|
||||
var enableLowerLevelTriggerThreshold = new bool[numChannels];
|
||||
var enableUpperLevelTriggerThreshold = new bool[numChannels];
|
||||
var lowerLevelTriggerThreshold = new float[numChannels];
|
||||
var upperLevelTriggerThreshold = new float[numChannels];
|
||||
var qualificationSamples = new int[numChannels];
|
||||
|
||||
var diagnosticChannels = new List<byte>();
|
||||
|
||||
var bModified = false;
|
||||
CommonConfigureWork(diagnosticChannels, qualificationSamples, ref bReleased,
|
||||
info, bridgeModeArray, IsACCoupledArray, BridgeResistanceArray,
|
||||
ref bModified, rangeArray, enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold,
|
||||
enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold, bridgeACCouplingArray);
|
||||
if (bReleased) { return; }
|
||||
// report progress
|
||||
progressValue = 5;
|
||||
info.Progress(progressValue);
|
||||
|
||||
StoreConfigAttributes(info, rangeArray, ref bReleased, ref progressValue, bridgeModeArray,
|
||||
IsACCoupledArray, BridgeResistanceArray, enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold,
|
||||
enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold, qualificationSamples, numChannels,
|
||||
out var config, bridgeACCouplingArray, numUart, numStreamingChannels);
|
||||
|
||||
progressValue = 20;
|
||||
info.Progress(progressValue);
|
||||
|
||||
RemainingConfigWork(ref progressValue, info, diagnosticChannels, config, ref bReleased, null, null, null);
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Cancel();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Error(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
info.Progress(100);
|
||||
info.Success();
|
||||
}
|
||||
/// <summary>
|
||||
/// returns true if the device is known to be streaming
|
||||
/// does not query device, just returns a flag if it has been set
|
||||
/// </summary>
|
||||
public override bool GetIsStreaming()
|
||||
{
|
||||
if (null == DASArmStatus) { return false; }
|
||||
//18852 Cannot use Stop streaming / (Dis)Auto Arm button if one or more DAS is idle
|
||||
//can't rely on just having received invalid mode, QATS will still have a status of realtime
|
||||
//when streaming, so we'll use either for now.
|
||||
return DASArmStatus.ReceivedInvalidModeDuringSetup || DASArmStatus.IsInRealtime;
|
||||
}
|
||||
public override int[] GetStackChannelConfigTypes()
|
||||
{
|
||||
try
|
||||
{
|
||||
var queryChannelTypes = new QueryArmAttribute(this) { Key = AttributeTypes.ArmAndEventAttributes.StackChannelConfigType };
|
||||
queryChannelTypes.SyncExecute();
|
||||
|
||||
var list = new List<int>();
|
||||
if (queryChannelTypes.Value is byte[] bytes)
|
||||
{
|
||||
foreach (var channelType in bytes)
|
||||
{
|
||||
list.Add(channelType);
|
||||
}
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
return new int[] { 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2218
DataPRO/IService/Classes/SLICE/SLICE6DB.cs
Normal file
2218
DataPRO/IService/Classes/SLICE/SLICE6DB.cs
Normal file
File diff suppressed because it is too large
Load Diff
41
DataPRO/IService/Classes/SLICE/SLICE6DB3.cs
Normal file
41
DataPRO/IService/Classes/SLICE/SLICE6DB3.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// SLICE6DB3 is a limited version of SLICE6DB, it notably does not have ie1588/ptp support
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class SLICE6DB3<T> : SLICE6DB<T>
|
||||
where T : IConnection,
|
||||
new()
|
||||
{
|
||||
|
||||
|
||||
#region IClockSyncActions
|
||||
public override void SetClockSyncConfig(ServiceCallback callback, object userData, ClockSyncProfile profile)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData) { functionData = profile };
|
||||
info.Success();
|
||||
}
|
||||
|
||||
public override void GetClockSyncStatus(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
public override void SetPTPDomainID(ServiceCallback callback, object userData, byte domainID)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData) { functionData = domainID };
|
||||
info.Success();
|
||||
}
|
||||
|
||||
public override void GetPTPDomainID(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
95
DataPRO/IService/Classes/SLICE/SLICEPRODB.cs
Normal file
95
DataPRO/IService/Classes/SLICE/SLICEPRODB.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.Communication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.DASLib.Service.Interfaces;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class SLICEPRODB<T> : SLICE6DB<T>,
|
||||
IDownloadActions
|
||||
where T : IConnection,
|
||||
new()
|
||||
{
|
||||
/// <summary>
|
||||
/// populates the connected devices field
|
||||
/// </summary>
|
||||
public override void QueryConnectedDevices()
|
||||
{
|
||||
//no functionality for this with SLICEPRO DB
|
||||
var connectedDevices = new List<IDASConnectedDevice>();
|
||||
((ICommunication)this).DASInfo.SetConnectedDevices(connectedDevices.ToArray());
|
||||
}
|
||||
|
||||
public override bool IsSlice6Distributor()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsBattery()
|
||||
{
|
||||
//um maybe?
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void AsyncQueryConfiguration(object configAsyncInfo)
|
||||
{
|
||||
var info = (SliceServiceAsyncInfo)configAsyncInfo;
|
||||
|
||||
InitMinProto(); _haveInited = true;
|
||||
ConfigData = MakeDefaultConfigFromInfo();
|
||||
info.Success();
|
||||
}
|
||||
|
||||
protected override bool SupportsTemperatureCheck => true;
|
||||
protected override bool SupportsTiltCheck => true;
|
||||
protected override bool SupportsClockSyncCheck => true;
|
||||
public override bool SupportsTimeSynchronization => false;
|
||||
|
||||
private const int MIN_PROTOCOL_VER = 1;
|
||||
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> SLICEPRODB_MinProtocols =
|
||||
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 6 DB Protocol Limitations
|
||||
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MeasureBaseDiagnosticChannel] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InSliceTemperatureCPre] = byte.MaxValue;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = MIN_PROTOCOL_VER;
|
||||
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPSyncStatus] = byte.MaxValue;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetClockSyncConfig] = byte.MaxValue;
|
||||
|
||||
// SLICE_DB Protocol Limitations
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.Arm] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EnableFaultChecking] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.OnOverride] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.OMAP_GPIO] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryBatteryVoltage] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRealtimeStream] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryEthernetMacTable] = byte.MaxValue;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryTempLogFile] = byte.MaxValue;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryTiltSensorData] = byte.MaxValue;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryExternalTiltInfo] = byte.MaxValue;
|
||||
MinimumProtocols = SLICEPRODB_MinProtocols;
|
||||
}
|
||||
}
|
||||
}
|
||||
854
DataPRO/IService/Classes/SLICE/SLICERecorder.cs
Normal file
854
DataPRO/IService/Classes/SLICE/SLICERecorder.cs
Normal file
@@ -0,0 +1,854 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.DASLib.Service;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Utilities;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.DASLib.Command.SLICE.DownloadCommands;
|
||||
using DTS.DASLib.Command.SLICE.RealtimeCommands;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Service.FirmwareUtility
|
||||
{
|
||||
#region SLICE Recorder class
|
||||
public class SLICERecorder
|
||||
{
|
||||
private ICommunication unit;
|
||||
public delegate void SetAttributeMethod(object val);
|
||||
|
||||
public SLICERecorder(DTS.Common.Interface.DASFactory.ICommunication _unit)
|
||||
{
|
||||
unit = _unit;
|
||||
}
|
||||
|
||||
public ushort EventNumber { get; set; }
|
||||
|
||||
public void QueryFirmwareVersion(out string firmwareversion)
|
||||
{
|
||||
var fvq = new QueryFirmwareVersion(unit);
|
||||
fvq.SyncExecute();
|
||||
firmwareversion = fvq.Version;
|
||||
}
|
||||
|
||||
public void QuerySerialNumber(out string serialnumber)
|
||||
{
|
||||
var snq = new QuerySerialNumber(unit);
|
||||
snq.SyncExecute();
|
||||
serialnumber = snq.SerialNumber;
|
||||
}
|
||||
|
||||
public void RunFlashSelfTest(UInt32 BlocksToTest, out double[] BlockTimingMicroSeconds)
|
||||
{
|
||||
const UInt32 skip = 4;
|
||||
const UInt32 FirstSector = 827392 + skip;
|
||||
|
||||
// Have the recorder run the test
|
||||
var fstest = new SelfTestFlash(unit);
|
||||
fstest.BlocksToTest = BlocksToTest;
|
||||
fstest.SyncExecute();
|
||||
|
||||
// Pick up the results, skipping skip
|
||||
BlocksToTest -= skip;
|
||||
BlockTimingMicroSeconds = new double[BlocksToTest - 1];
|
||||
|
||||
ulong[] ticks = new ulong[BlocksToTest];
|
||||
var flashread = new ReadArbitraryFlash(unit);
|
||||
|
||||
for (UInt32 CurrentSector = 0; CurrentSector < BlocksToTest; CurrentSector++)
|
||||
{
|
||||
flashread.Address = (CurrentSector + FirstSector) * 512;
|
||||
flashread.Length = 16;
|
||||
|
||||
flashread.SyncExecute();
|
||||
byte[] u64 = new byte[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
u64[i] = flashread.Data[2 * i + 1];
|
||||
}
|
||||
ByteConvertor.Convert(u64, 0, out ticks[(int)CurrentSector]);
|
||||
}
|
||||
|
||||
for (UInt32 CurrentSector = 0; CurrentSector < BlocksToTest - 1; CurrentSector++)
|
||||
{
|
||||
BlockTimingMicroSeconds[(int)CurrentSector] = (ticks[(int)CurrentSector + 1] - ticks[(int)CurrentSector]) / 10.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void QuerySystemAttributes(out Dictionary<AttributeTypes.SystemAttributes, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QuerySystemAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributes, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributes)key;
|
||||
var query = new QuerySystemAttribute(unit);
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttribute(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QuerySystemAttributes_SLICE6DB(out Dictionary<AttributeTypes.SystemAttributesSLICE6DB, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QuerySystemAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributesSLICE6DB, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributesSLICE6DB)key;
|
||||
var query = new QuerySystemAttributeSLICE6DB(unit);
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttributeSLICE6DB(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QuerySystemAttributes_SLICE6AIR(out Dictionary<AttributeTypes.SystemAttributesSLICE6AIR, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QuerySystemAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributesSLICE6AIR, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributesSLICE6AIR)key;
|
||||
var query = new QuerySystemAttributeSLICE6AIR(unit);
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttributeSLICE6AIR(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QuerySystemAttributes_SLICE6(out Dictionary<AttributeTypes.SystemAttributesSLICE6, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QuerySystemAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributesSLICE6, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributesSLICE6)key;
|
||||
var query = new QuerySystemAttributeSLICE6(unit);
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttributeSLICE6(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QuerySystemAttributes_SLICE2(out Dictionary<AttributeTypes.SystemAttributesSLICE2, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QuerySystemAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributesSLICE2, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributesSLICE2)key;
|
||||
var query = new QuerySystemAttributeSLICE2(unit);
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttributeSLICE2(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryBridgeAttributes_SLICE2(byte bridgeID, out Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE2, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = System.Enum.GetValues(typeof(AttributeTypes.SystemAttributes_Bridge_SLICE2));
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE2, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributes_Bridge_SLICE2)key;
|
||||
var query = new QuerySystemAttribute_Slice2Bridge(unit);
|
||||
query.DeviceID = bridgeID;
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttribute_Bridge_SLICE2(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryBridgeAttributes_TOM(byte bridgeID, out Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE_TOM, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = System.Enum.GetValues(typeof(AttributeTypes.SystemAttributes_Bridge_SLICE_TOM));
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE_TOM, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributes_Bridge_SLICE_TOM)key;
|
||||
var query = new QuerySystemAttribute_Slice_TOM(unit);
|
||||
query.DeviceID = bridgeID;
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttributes_Bridge_SLICE_TOM(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryBridgeAttributes(byte bridgeID, out Dictionary<AttributeTypes.SystemAttributes_Bridge, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = System.Enum.GetValues(typeof(AttributeTypes.SystemAttributes_Bridge));
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributes_Bridge, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributes_Bridge)key;
|
||||
var query = new QuerySystemAttribute_Bridge(unit);
|
||||
query.DeviceID = bridgeID;
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttribute_Bridge(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public delegate object UpdateAttribute(object value, bool overwrite);
|
||||
|
||||
public void SetSystemAttribute(AttributeTypes.SystemAttributes key, object value, bool ShouldOverwrite)
|
||||
{
|
||||
var set = new SetSystemAttribute(unit);
|
||||
set.SetValue(key, value, ShouldOverwrite);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void SetUserAttribute(AttributeTypes.SliceUserAttributes key, object value, bool ShouldOverwrite)
|
||||
{
|
||||
var set = new SetUserAttribute(unit);
|
||||
set.SetValue(key, value, ShouldOverwrite);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void QueryUserAttributes(out Dictionary<AttributeTypes.SliceUserAttributes, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QueryUserAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SliceUserAttributes, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SliceUserAttributes)key;
|
||||
var query = new QueryUserAttribute(unit);
|
||||
query.Key = (AttributeTypes.SliceUserAttributes)key;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetUserAttribute(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryArmAttributes(out Dictionary<AttributeTypes.ArmAndEventAttributes, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QueryArmAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.ArmAndEventAttributes, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.ArmAndEventAttributes)key;
|
||||
var query = new QueryArmAttribute(unit);
|
||||
query.Key = (AttributeTypes.ArmAndEventAttributes)key;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetArmAttribute(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void SetArmAttribute(AttributeTypes.ArmAndEventAttributes key, object value, bool ShouldOverwrite)
|
||||
{
|
||||
var set = new SetArmAttribute(unit);
|
||||
set.SetValue(key, value, ShouldOverwrite);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void QueryEventAttributes(ushort EventNumber, out Dictionary<AttributeTypes.ArmAndEventAttributes, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
ushort TotalEvents;
|
||||
attributes = new Dictionary<AttributeTypes.ArmAndEventAttributes, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
keys = new List<int>();
|
||||
|
||||
GetTotalEventsStored(out TotalEvents);
|
||||
if (0 == TotalEvents) return;
|
||||
|
||||
var getKeys = new QueryEventAttributeKeys(unit);
|
||||
getKeys.EventNumber = EventNumber;
|
||||
getKeys.SyncExecute();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.ArmAndEventAttributes)key;
|
||||
var query = new QueryEventAttribute(unit);
|
||||
query.EventNumber = EventNumber;
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetEventAttribute(unit);
|
||||
attrSet.EventNumber = EventNumber;
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEventAttribute(ushort EventNumber, AttributeTypes.ArmAndEventAttributes key, object value, bool ShouldOverwrite)
|
||||
{
|
||||
var set = new SetEventAttribute(unit);
|
||||
set.EventNumber = EventNumber;
|
||||
set.SetValue(key, value, ShouldOverwrite);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void SetAntiAliasFilterImmediately(float cutoffFrequencyHz)
|
||||
{
|
||||
var aafilterSet = new SetAAFilterImmediate(unit);
|
||||
aafilterSet.FrequencyHz = cutoffFrequencyHz;
|
||||
aafilterSet.SyncExecute();
|
||||
}
|
||||
|
||||
public void ResetEventList()
|
||||
{
|
||||
var reset = new ResetEventList(unit);
|
||||
reset.SyncExecute();
|
||||
}
|
||||
|
||||
public void Arm()
|
||||
{
|
||||
var arm = new Arm(unit);
|
||||
arm.SyncExecute();
|
||||
}
|
||||
|
||||
public void Disarm()
|
||||
{
|
||||
var disarm = new Disarm(unit);
|
||||
disarm.SyncExecute();
|
||||
}
|
||||
|
||||
public void GetSingleSample(out short[] adc, out int channels)
|
||||
{
|
||||
var ss = new RetrieveSingleSample(unit);
|
||||
ss.SyncExecute();
|
||||
channels = ss.Channels;
|
||||
adc = new short[channels];
|
||||
for (int i = 0; i < channels; i++)
|
||||
{
|
||||
adc[i] = ss.GetChannelData(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetTotalEventsStored(out ushort TotalEvents)
|
||||
{
|
||||
var eventCountQuery = new QuerySystemAttribute(unit);
|
||||
eventCountQuery.Key = AttributeTypes.SystemAttributes.TotalEventsStored;
|
||||
eventCountQuery.SyncExecute();
|
||||
|
||||
TotalEvents = (ushort)eventCountQuery.Value;
|
||||
}
|
||||
|
||||
public void GetTotalChannelsByEvent(ushort EventNumberFromZero, out byte TotalChannels)
|
||||
{
|
||||
ushort TotalEvents;
|
||||
GetTotalEventsStored(out TotalEvents);
|
||||
if (TotalEvents <= EventNumberFromZero)
|
||||
{
|
||||
TotalChannels = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var totalChannelsQuery = new QueryEventAttribute(unit);
|
||||
totalChannelsQuery.EventNumber = EventNumberFromZero;
|
||||
totalChannelsQuery.Key = AttributeTypes.ArmAndEventAttributes.TotalChannels;
|
||||
totalChannelsQuery.SyncExecute();
|
||||
TotalChannels = (byte)totalChannelsQuery.Value;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public bool IsEventAlreadyStored(ushort EventNumberFromZero)
|
||||
{
|
||||
ushort TotalEvents;
|
||||
GetTotalEventsStored(out TotalEvents);
|
||||
return (TotalEvents > EventNumberFromZero);
|
||||
}
|
||||
|
||||
public bool IsChannelValidForEvent(ushort EventNumberFromZero, byte ChannelNumberFromZero)
|
||||
{
|
||||
byte TotalChannels;
|
||||
GetTotalChannelsByEvent(EventNumberFromZero, out TotalChannels);
|
||||
return (ChannelNumberFromZero <= TotalChannels);
|
||||
}
|
||||
|
||||
public void QueryEventDescription(ushort EventNumberFromZero, out string EventDescription)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
EventDescription = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the EventDescription event attribute
|
||||
var descriptionQuery = new QueryEventAttribute(unit);
|
||||
descriptionQuery.EventNumber = EventNumberFromZero;
|
||||
descriptionQuery.Key = AttributeTypes.ArmAndEventAttributes.Description;
|
||||
descriptionQuery.SyncExecute();
|
||||
|
||||
if (null == descriptionQuery.Value)
|
||||
{
|
||||
EventDescription = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
EventDescription = (string)descriptionQuery.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryEventID(ushort EventNumberFromZero, out string EventID)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
EventID = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the EventDescription event attribute
|
||||
var idQuery = new QueryEventAttribute(unit);
|
||||
idQuery.EventNumber = EventNumberFromZero;
|
||||
idQuery.Key = AttributeTypes.ArmAndEventAttributes.Name;
|
||||
idQuery.SyncExecute();
|
||||
|
||||
if (null == idQuery.Value)
|
||||
{
|
||||
EventID = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
EventID = (string)idQuery.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryEventSampleRate(ushort EventNumberFromZero, out UInt32 SampleRate)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
SampleRate = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the EventDescription event attribute
|
||||
var sampleRateQuery = new QueryEventAttribute(unit);
|
||||
sampleRateQuery.EventNumber = EventNumberFromZero;
|
||||
sampleRateQuery.Key = AttributeTypes.ArmAndEventAttributes.SampleRate;
|
||||
sampleRateQuery.SyncExecute();
|
||||
|
||||
if (null == sampleRateQuery.Value)
|
||||
{
|
||||
SampleRate = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SampleRate = (UInt32)sampleRateQuery.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetPreTriggerSamplesByEvent(ushort EventNumberFromZero, out ulong PreTriggerSamples)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
PreTriggerSamples = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the TotalSamples event attribute
|
||||
var preTriggerSamplesQuery = new QueryEventAttribute(unit);
|
||||
preTriggerSamplesQuery.EventNumber = EventNumberFromZero;
|
||||
preTriggerSamplesQuery.Key = AttributeTypes.ArmAndEventAttributes.PreTriggerSamplesRequested;
|
||||
preTriggerSamplesQuery.SyncExecute();
|
||||
|
||||
if (null == preTriggerSamplesQuery.Value)
|
||||
{
|
||||
PreTriggerSamples = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
PreTriggerSamples = (ulong)preTriggerSamplesQuery.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetPostTriggerSamplesByEvent(ushort EventNumberFromZero, out ulong PostTriggerSamples)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
PostTriggerSamples = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the TotalSamples event attribute
|
||||
var postTriggerSamplesQuery = new QueryEventAttribute(unit);
|
||||
postTriggerSamplesQuery.EventNumber = EventNumberFromZero;
|
||||
postTriggerSamplesQuery.Key = AttributeTypes.ArmAndEventAttributes.PostTriggerSamplesRequested;
|
||||
postTriggerSamplesQuery.SyncExecute();
|
||||
|
||||
if (null == postTriggerSamplesQuery.Value)
|
||||
{
|
||||
PostTriggerSamples = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
PostTriggerSamples = (ulong)postTriggerSamplesQuery.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetTotalSamplesByEvent(ushort EventNumberFromZero, out ulong TotalSamples)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
TotalSamples = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the TotalSamples event attribute
|
||||
var totalSamplesQuery = new QueryEventAttribute(unit);
|
||||
totalSamplesQuery.EventNumber = EventNumberFromZero;
|
||||
totalSamplesQuery.Key = AttributeTypes.ArmAndEventAttributes.TotalSamplesRecorded;
|
||||
try
|
||||
{
|
||||
totalSamplesQuery.SyncExecute();
|
||||
TotalSamples = (ulong)totalSamplesQuery.Value;
|
||||
}
|
||||
|
||||
// Store the value in the out param, but take care because it may not
|
||||
// have been stored in the event's attribute store
|
||||
catch
|
||||
{
|
||||
TotalSamples = 0;
|
||||
}
|
||||
|
||||
// If the param is 0, fake it by summing pre and post trigger samples
|
||||
// requested for the event
|
||||
if (0 == TotalSamples)
|
||||
{
|
||||
ulong PreTriggerSamples, PostTriggerSamples;
|
||||
GetPreTriggerSamplesByEvent(EventNumberFromZero, out PreTriggerSamples);
|
||||
GetPostTriggerSamplesByEvent(EventNumberFromZero, out PostTriggerSamples);
|
||||
|
||||
TotalSamples = PreTriggerSamples + PostTriggerSamples;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetEventDataByChannel(ushort EventNumberFromZero, byte ChannelNumberFromZero, out short[] adc)
|
||||
{
|
||||
// Make sure the channel is valid for the event requested
|
||||
if (false == IsChannelValidForEvent(EventNumberFromZero, ChannelNumberFromZero))
|
||||
{
|
||||
adc = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab all the event data for the event
|
||||
List<short[]> adc_all;
|
||||
GetEventDataByEvent(EventNumberFromZero, out adc_all);
|
||||
|
||||
if (null == adc_all)
|
||||
{
|
||||
adc = null;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
adc = new short[adc_all[0].Length];
|
||||
}
|
||||
|
||||
// Copy out the requested channel
|
||||
Buffer.BlockCopy(adc_all[ChannelNumberFromZero], 0, adc, 0, 2 * adc_all[ChannelNumberFromZero].Length);
|
||||
}
|
||||
|
||||
public void GetEventDataByEvent(ushort EventNumberFromZero, out List<short[]> adc)
|
||||
{
|
||||
// Figure out how many samples are stored and then ...
|
||||
ulong TotalSamples;
|
||||
GetTotalSamplesByEvent(EventNumberFromZero, out TotalSamples);
|
||||
|
||||
// Grab them all
|
||||
GetEventSampleRangeByEvent(EventNumberFromZero, out adc, 0, TotalSamples - 1);
|
||||
}
|
||||
|
||||
public QueryEventDataBase GetQueryEventData(DTS.Common.Interface.DASFactory.ICommunication unit)
|
||||
{
|
||||
return new QueryEventDataBase(unit, QueryEventDataBase.Default_IO_Timeout);
|
||||
//need to do something else if unit is slice2 ...
|
||||
}
|
||||
public void GetEventSampleRangeByEvent(ushort EventNumberFromZero, out List<short[]> adc,
|
||||
ulong FirstSample, ulong LastSample)
|
||||
{
|
||||
if (FirstSample > LastSample)
|
||||
{
|
||||
adc = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
adc = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Figure out how many samples are stored
|
||||
ulong TotalSamples;
|
||||
GetTotalSamplesByEvent(EventNumberFromZero, out TotalSamples);
|
||||
|
||||
// Make sure the samples requested are in the available window
|
||||
ulong SamplesToGet = LastSample - FirstSample + 1;
|
||||
if (FirstSample + SamplesToGet > TotalSamples)
|
||||
{
|
||||
adc = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Figure out how many channels were stored
|
||||
byte channels;
|
||||
GetTotalChannelsByEvent(EventNumberFromZero, out channels);
|
||||
|
||||
// Grab the data
|
||||
//var dataQuery = new QueryEventData(unit);
|
||||
var dataQuery = GetQueryEventData(unit);
|
||||
dataQuery.EventNumber = EventNumberFromZero;
|
||||
dataQuery.LastSample = LastSample;
|
||||
dataQuery.ChannelsDownloaded = channels;
|
||||
|
||||
ulong SamplesGotten = 0;
|
||||
adc = null;
|
||||
while (SamplesGotten < SamplesToGet)
|
||||
{
|
||||
dataQuery.FirstSample = SamplesGotten;
|
||||
dataQuery.SyncExecute();
|
||||
ulong SamplesThisTime = 0;
|
||||
if (null == adc)
|
||||
{
|
||||
adc = new List<short[]>(dataQuery.ChannelsDownloaded);
|
||||
for (int i = 0; i < adc.Capacity; i++)
|
||||
{
|
||||
adc.Add(new short[SamplesToGet]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < dataQuery.ChannelsDownloaded; i++)
|
||||
{
|
||||
short[] tmp;
|
||||
dataQuery.GetChannelData(i, out tmp);
|
||||
SamplesThisTime = (ulong)tmp.Length;
|
||||
Buffer.BlockCopy(tmp, 0, adc[i], (int)(2 * SamplesGotten),
|
||||
tmp.Length > (int)(SamplesToGet - SamplesGotten) ? (int)(2 * (SamplesToGet - SamplesGotten)) : 2 * tmp.Length);
|
||||
}
|
||||
|
||||
SamplesGotten += SamplesThisTime;
|
||||
}
|
||||
}
|
||||
|
||||
#region private members
|
||||
// empty
|
||||
#endregion
|
||||
|
||||
public void QueryBridgeAttributes_SLICE2_GEN3(byte bridgeID, out Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE2_GEN3, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = System.Enum.GetValues(typeof(AttributeTypes.SystemAttributes_Bridge_SLICE2_GEN3));
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE2_GEN3, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributes_Bridge_SLICE2_GEN3)key;
|
||||
var query = new QuerySystemAttribute_Slice2Bridge_GEN3(unit);
|
||||
query.DeviceID = bridgeID;
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttribute_Slice2Bridge_GEN3(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public enum SLICEPRO_Generation
|
||||
{
|
||||
SLICEPRO_GEN2 = 0, // baseType = 0
|
||||
SLICEPRO_GEN3 = 1, // baseType = 0
|
||||
SLICEPRO_REVC = 2 // baseType = 0,3,4 reserve for board 204revC
|
||||
}
|
||||
|
||||
public SLICEPRO_Generation GetSLICEProHardwareVersion(DTS.Common.Interface.DASFactory.ICommunication comm)
|
||||
{
|
||||
byte hardwareVersion = (byte)SLICEPRO_Generation.SLICEPRO_GEN2;
|
||||
if (comm.IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision))
|
||||
{
|
||||
QuerySystemAttributeSLICE2 qsas2 = new QuerySystemAttributeSLICE2(comm, 1000);
|
||||
qsas2.DeviceGroup = 0;
|
||||
qsas2.DeviceID = 0;
|
||||
qsas2.Key = AttributeTypes.SystemAttributesSLICE2.BaseHardwareRevision;
|
||||
qsas2.SyncExecute();
|
||||
hardwareVersion = (byte)qsas2.Value;
|
||||
}
|
||||
return (SLICEPRO_Generation)hardwareVersion;
|
||||
}
|
||||
|
||||
public enum SLICEPRO_BaseType
|
||||
{
|
||||
SLICEPRO_BASE_SIM = 0,
|
||||
SLICE_NANO_PHRDR = 1,
|
||||
SLICE_BASE_PLUS = 2,
|
||||
SLICEPRO_DIM = 3,
|
||||
SLICEPRO_TOM = 4,
|
||||
// reserve 5 for Trigger Distributor Module which has no com to PC.
|
||||
SLICE6 = 6,
|
||||
SLICE6DB = 7,
|
||||
SLICE6AIR = 8,
|
||||
POWER_PRO = 9,
|
||||
TSRAIR = 10,
|
||||
SLICE6DB_3 = 11,
|
||||
}
|
||||
|
||||
// type
|
||||
public SLICEPRO_BaseType GetSLICEProBaseType(DTS.Common.Interface.DASFactory.ICommunication comm)
|
||||
{
|
||||
byte baseType = (byte)SLICEPRO_BaseType.SLICEPRO_BASE_SIM;
|
||||
|
||||
QuerySystemAttributeSLICE2 qsa = new QuerySystemAttributeSLICE2(comm, 2000);
|
||||
qsa.Key = AttributeTypes.SystemAttributesSLICE2.BaseType;
|
||||
qsa.SyncExecute();
|
||||
baseType = Convert.ToByte(qsa.Value);
|
||||
|
||||
return (SLICEPRO_BaseType)baseType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
2012
DataPRO/IService/Classes/SLICE/SliceDB.cs
Normal file
2012
DataPRO/IService/Classes/SLICE/SliceDB.cs
Normal file
File diff suppressed because it is too large
Load Diff
2476
DataPRO/IService/Classes/SLICE/TSRAIR.cs
Normal file
2476
DataPRO/IService/Classes/SLICE/TSRAIR.cs
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user