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

View 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;
}
}
}

View 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; } }
}
}

View 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;
}
}
}
}

View 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];
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,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;
}
}
}

View 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 };
}
}
}
}

File diff suppressed because it is too large Load Diff

View 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
}
}

View 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;
}
}
}

View 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
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff