using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Xml.Serialization;
using System.IO;
using DTS.Common;
using DTS.Common.DASResource;
using DTS.Common.Enums;
using DTS.Common.Interface.DASFactory;
using DTS.DASLib.Command.Ribeye;
using DTS.Common.Utilities.Logging;
using DTS.Common.Enums.Sensors;
using DTS.Common.Classes.Connection;
using DTS.Common.Interface.Connection;
using DTS.Common.Interface.DASFactory.Diagnostics;
using DTS.DASLib.Service.Classes.Diagnostics;
using DTS.Common.Enums.DASFactory;
using DTS.Common.Interface.DASFactory.ARM;
using DTS.Common.Interface.DASFactory.Download;
using DTS.Common.Interface.DASFactory.Config;
using DTS.Common.ICommunication;
using DTS.Common.Interface.StatusAndProgressBar;
using DTS.Common.Enums.Hardware;
using static DTS.Common.Enums.DASFactory.DFConstantsAndEnums;
using System.IO.Ports;
using DTS.Common.Classes.DSP;
namespace DTS.DASLib.Service
{
///
/// The Ribeye class implements the required services for a Ribeye device
///
/// Type of connection (e.g. Ethernet)
public partial class Ribeye : Communication,
IDASCommunication,
IConfigurationActions,
IDiagnosticsActions,
IRealTimeActions,
IArmActions,
IDownloadActions
where T : IConnection, new()
{
public ExcitationStatus ExcitationStatus { get; set; } = ExcitationStatus.Unknown;
///
///
///
public string TestDirectory { get; set; }
public IOptimizationValues OptimizationValues { get; set; }
///
/// returns true if the unit is capable of reading arm status
/// 17800 Trigger status is "waiting" but PPRO has indeed triggered
///
///
bool IDASCommunication.GetCanCheckArmStatus() { return true; }
void IDASCommunication.SetIsStreamingSupported(bool supported = false)
{
IsStreamingSupported = false;
}
void IDASCommunication.ReadFirstUseDate()
{
IsFirstUseDateSupported = false;
FirstUseDate = null;
}
///
/// 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"
///
public DateTime? FirstUseDate { get; set; } = null;
///
/// 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"
///
public bool IsFirstUseDateSupported { get; set; } = false;
///
/// returns whether or not the hardware and firmware support streaming
///
public bool IsStreamingSupported { get; set; } = false;
public bool ConnectionCheck()
{
try
{
var querySerialNumber = new QuerySerialNumber(this);
querySerialNumber.SyncExecute();
return true;
}
catch (Exception ex)
{
APILogger.Log(ex);
}
return false;
}
public HardwareTypes GetHardwareType() => HardwareTypes.Ribeye;
public int[] GetStackChannelConfigTypes() => new int[] { 0 };
public int RecordId { get; set; } = HardwareConstants.INVALID_IDASCOMMUNICATION_RECORD_ID;
void IDiagnosticsActions.ClearTriggerOut(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
void IConfigurationActions.SetFirstUseDate(DateTime firstUseDate, ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Error("Not supported");
}
void IDiagnosticsActions.ClearLatches(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
///
/// clears any das trigger lines (N/A to ribeye)
///
void IDiagnosticsActions.ClearDASTriggerLine(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
bool IConfiguration.SupportsAutoDetect => false;
void IConfigurationActions.AutoDetect(bool QueryConfiguration, ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
///
/// queries for any connected devices
/// currently Ribeye can not discover devices
///
public void QueryConnectedDevices() { }
public string MACAddress { get; set; }
public string[] DownstreamMACAddresses { get; set; }
public bool IsEthernetDistributor() { return false; }
public bool IsSlice6Distributor() { return false; }
public bool IsBattery() { return false; }
public bool IsTSRAIR() { return false; }
public bool IsSlice6Air() { return false; }
public bool IsSlice6AirTc() { return false; }
public bool IsScheduleEventCountSupported() { return false; }
public double[] GetNominalRanges(SensorConstants.BridgeType bridge)
{
throw new NotImplementedException();
}
public int MaxModules
{
get => 1;
set {; }
}
///
/// phase shift information not known for ribeye, so assume 0 for now
///
///
///
///
///
public ulong GetPhaseShiftSamples(uint ModuleIndex, double ActualSampleRate, uint HardwareAAF, ulong originalT0) { return 0; }
///
/// initiates background flash erase for units that support it
/// will return immediately after flash erase begins
///
///
///
void IArmActions.BeginBackgroundFlashErase(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
///
/// returns whether unit is capable of flash erase
///
bool IArmActions.SupportsBackgroundFlashErase => false;
///
/// returns whether unit has started background flash erase
///
bool IArmActions.BackgroundFlashEraseStarted => false;
DateTime? IArmActions.BackgroundFlashEraseStartTime => null;
int IConfiguration.GetDASDisplayOrder() { return -1; }
int[] IConfiguration.GetChannelDisplayOrder() { return new int[] { -1 }; }
void IConfiguration.SetDASDisplayOrder(int order) { throw new NotSupportedException("Not supported for Ribeye"); }
void IConfiguration.SetChannelDisplayOrder(int[] order) { throw new NotSupportedException("Not supported for Ribeye"); }
public bool RequireDiagnosticRateMatchSampleRate() { return false; }
public DateTime SystemBaseTime => DateTime.MinValue;
public bool SupportsTimeSynchronization => false;
public bool RangeBandwidthLimited => false;
void IArmActions.ReadyForArming(ServiceCallback callback, object userData, Guid eventGuid, int armNowTimeout, bool testingMode,
int maxNumberEvents, bool DummyArm, bool SysMode)
{
var info = new RibeyeArmNowPacket(callback, userData, armNowTimeout);
LaunchAsyncWorker("Ribeye.ReadyArming", new WaitCallback(AsyncReadyArming), info);
}
private void AsyncReadyArming(object asyncInfo)
{
var info = asyncInfo as RibeyeArmNowPacket;
info.Success();
return;
}
public bool CheckAAF(float rate) { return true; }
long IDASCommunication.MaxMemory() { return long.MaxValue; }
//don't know the actual max rate, but hopefully it doesn't run by itself and is controlled by the
//max rate of other hardware
uint IDASCommunication.MaxSampleRate(int numberOfConfiguredChannels) { return uint.MaxValue; }
uint IDASCommunication.MinSampleRate() { return uint.MinValue; }
public uint MaxAAFilterRate() { return uint.MaxValue; }
public float InputLowVoltage { get; set; }
public float InputMediumVoltage { get; set; }
public float InputHighVoltage { get; set; }
public float BatteryLowVoltage { get; set; }
public float BatteryMediumVoltage { get; set; }
public float BatteryHighVoltage { get; set; }
public double MinimumValidInputVoltage { get; set; }
public double MaximumValidInputVoltage { get; set; }
public double MinimumValidBatteryVoltage { get; set; }
public double MaximumValidBatteryVoltage { get; set; }
public bool AutoArmed { get => false; set { } }
///
/// the UDP settings to broadcast auto arm status to on auto arm boot
/// 17583 Monitor Test UI
///
public string AutoArmUDPSetting { get; set; } = "239.1.2.3:8504";
///
/// Auto Arm a single DAS now
///
/// The function to call with information
/// Whatever you want to pass along
/// A unique GUID that this event will be tagged
/// with
void IArmActions.AutoArmNow(ServiceCallback callback, object userData, Guid eventGuid, int
armNowTimeout, bool testingMode, uint diagnosticsDelayMs, int maxNumberEvents, bool repeatEnable, bool preserveDiagnostics)
{
throw new NotSupportedException("AutoArmNow not supported for Ribeye");
}
private Dictionary Ribeye_MinimumProtocols = new Dictionary();
public override void InitMinProto()
{
// Ribeye Protocol Limitations
MinimumProtocols = Ribeye_MinimumProtocols;
}
private const float RibeyeSampleRate = 10000.0F;
private const string RIBEYE_CONFIGURATION_FILE = "ribeye.xml";
#region Configuration
///
/// ConfigData contains all configuration information about the Ribeye
///
public IConfigurationData ConfigData { get; set; }
///
/// Verify that the ConfigData property is correctly constructed
///
/// Set to true if your're arming
void IConfigurationActions.VerifyConfig(bool DoStrictCheck)
{
VerifyConfig(DoStrictCheck, null);
}
void IConfigurationActions.StoreTestSetupXML(ServiceCallback callback, object userData, string testSetupXML)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
void IConfigurationActions.ResetHardwareLines(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
void IConfigurationActions.CheckAAFilterRate(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
void IConfigurationActions.VerifyConfig(bool DoStrictCheck, ErrorCallback failedChallengeFunc)
{
VerifyConfig(DoStrictCheck, failedChallengeFunc);
}
void VerifyConfig(bool DoStrictCheck, ErrorCallback failedChallengeFunc)
{
// look thru all the config data and make sure it's fit to be used
// our caller have already checked for null, but...
if (ConfigData == null)
{
// "Slice.VerifyConfig: ConfigData is null"
throw new ArgumentException(Strings.Slice_VerifyConfig_Err1);
}
if (string.IsNullOrEmpty(ConfigData.Description))
{
// "Slice.VerifyConfig: ConfigData.Description is null"
//throw new ArgumentException(Strings.Slice_VerifyConfig_Err2);
ConfigData.Description = "";
}
if (DoStrictCheck && string.IsNullOrEmpty(ConfigData.TestID))
{
// "Slice.VerifyConfig: ConfigData.TestID is null"
throw new ArgumentException(Strings.Slice_VerifyConfig_Err3);
//ConfigData.TestID = "Default Test ID";
}
// we don't care about EID's here
if (ConfigData.Modules == null || ConfigData.Modules.Length == 0 || ConfigData.Modules.Length > DASInfo.Modules.Length)
{
// "Slice.VerifyConfig: ConfigData.Modules is null, empty or too long"
throw new ArgumentException(Strings.Slice_VerifyConfig_Err4);
}
for (int moduleIdx = 0; moduleIdx < ConfigData.Modules.Length; moduleIdx++)
{
var module = ConfigData.Modules[moduleIdx];
if (module.ModuleArrayIndex != moduleIdx)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].ModuleNumber doesn't mach index"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err5, moduleIdx));
}
if (module.RecordingMode != DFConstantsAndEnums.RecordingMode.CircularBuffer &&
module.RecordingMode != DFConstantsAndEnums.RecordingMode.RecorderMode)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Mode has incorrect value"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err7, moduleIdx));
}
if (module.SampleRateHz != RibeyeSampleRate)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].SampleRateHz must be below {1}"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err8, moduleIdx, RibeyeSampleRate));
}
if ((uint)((module.PreTriggerSeconds + module.PostTriggerSeconds) * module.SampleRateHz) > DASInfo.Modules[moduleIdx].MaxRecordingSamples)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}] total number of samples must be below {1}"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err9, moduleIdx, DASInfo.Modules[moduleIdx].MaxRecordingSamples));
}
if (module.Channels == null || module.Channels.Length == 0 || module.Channels.Length > DASInfo.Modules[moduleIdx].NumberOfChannels)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels is null, empty or too long"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err10, moduleIdx));
}
for (int channelIdx = 0; channelIdx < module.Channels.Length; channelIdx++)
{
var channel = (DASChannel)module.Channels[channelIdx];
if (channel.ConfigurationMode == DFConstantsAndEnums.ConfigMode.Disabled)
continue;
if (channel.OwningModule != module)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}].OwningModule doesn't mach owner"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err11, moduleIdx, channelIdx));
}
if (channel.ModuleChannelNumber != channelIdx)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}].ChannelNumber doesn't mach index"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err12, moduleIdx, channelIdx));
}
if (channel.DiagnosticsMode) { throw new ArgumentException("no Diagnostics Mode support for Ribeye"); }
if (channel.ConfigurationMode != DFConstantsAndEnums.ConfigMode.Normal &&
channel.ConfigurationMode != DFConstantsAndEnums.ConfigMode.DummyArm &&
channel.ConfigurationMode != DFConstantsAndEnums.ConfigMode.Disabled)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}].mode has incorrect value"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err13, moduleIdx, channelIdx));
}
if (!(channel is AnalogInputDASChannel))
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}] is not an analog input channel"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err14, moduleIdx, channelIdx));
}
var analog = channel as AnalogInputDASChannel;
if (analog.TypeOfBridge != SensorConstants.BridgeType.FullBridge)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}].Bridge has incorrect value"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err15, moduleIdx, channelIdx));
}
if (analog.ShuntIsEnabled)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}].BridgeResistanceOhms is outside the allowed range({2}-{3})"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err16, moduleIdx, channelIdx, 0, 0));
}
if (analog.VoltageInsertionCheckEnabled)
{
throw new NotSupportedException("No voltage insertion supported for Ribeye");
}
if (analog.IsProportionalToExcitation)
{
throw new ArgumentException(string.Format(Strings.Ribeye_VerifyConfig_ProportionalNotSupported, moduleIdx * 3 + channelIdx));
}
if (analog.BypassAAFilter)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}], bypassing AA filter is not supported"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err17, moduleIdx, channelIdx));
}
if (analog.DesiredRangeWithHeadroomEU < 0)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}].DesiredRange must be positive"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err18, moduleIdx, channelIdx));
}
if (DoStrictCheck && string.IsNullOrEmpty(analog.EngineeringUnits))
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}].EngineeringUnits can't be null or empty"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err19, moduleIdx, channelIdx));
}
if (analog.Excitation != ExcitationVoltageOptions.ExcitationVoltageOption.Volt5)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}].Excitation only 5 volts is supported"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err20, moduleIdx, channelIdx));
}
if (analog.ZeroMethod != ZeroMethodType.AverageOverTime &&
analog.ZeroMethod != ZeroMethodType.UsePreEventDiagnosticsZero)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}].ZeroMethod has invalid value"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err22, moduleIdx, channelIdx));
}
if (DoStrictCheck && analog.ZeroMethod == ZeroMethodType.AverageOverTime)
{
if (analog.ZeroAverageStartSeconds >= analog.ZeroAverageStopSeconds)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}] zero average start must be less than zero average stop"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err23, moduleIdx, channelIdx));
}
if (analog.ZeroAverageStopSeconds > module.PostTriggerSeconds)
{
// "Slice.VerifyConfig: ConfigData.Module[{0}].Channels[{1}] zero average stop must be less than post-trigger"
throw new ArgumentException(string.Format(Strings.Slice_VerifyConfig_Err25, moduleIdx, channelIdx));
}
}
}
}
}
///
/// Apply the data in the ConfigData property to the DAS
///
/// The function to call with information
/// Whatever you want to pass along
void IConfigurationActions.CheckSafetyState(bool bArmed, ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.CheckSafetyState", new WaitCallback(AsyncCheckSafetyState), info);
}
void IConfigurationActions.QueryTestSetup(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
///
/// Apply the data in the ConfigData property to the DAS
///
/// The function to call with information
/// Whatever you want to pass along
void IConfigurationActions.Configure(ServiceCallback callback, object userData, bool EventConfig, bool DummyConfig, double [] maxAAF, bool configureDigitalOutputs, uint crc, bool turnOffAAFRealtime,
IStreamingFilterProfile dspFilterType, bool discardDiagnostics, Dictionary timeChannelIds, Dictionary dataChannelIds,
Dictionary streamProfiles, Dictionary streamADCPerPacket, Dictionary irigTDPIntervals,
Dictionary addresses, Dictionary tmnsConfigs,
Dictionary baudRates, Dictionary dataBits, Dictionary stopBits,
Dictionary parities, Dictionary flowControls, Dictionary dataFormats,
Dictionary tmatsIntervals
)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.DiscardDiagnostics = discardDiagnostics;
LaunchAsyncWorker("Ribeye.Configure", new WaitCallback(AsyncConfigure), info);
}
void IConfigurationActions.ApplyLevelTriggers(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.ApplyLevelTriggers", AsyncApplyLevelTriggers, info);
}
private void AsyncApplyLevelTriggers(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
info.Success();
}
private const string KEY_TESTID = "TestID";
private const string KEY_TEST_DESCRIPTION = "TestDescription";
private const string KEY_TEST_GUID = "TestGUID";
private const string KEY_FAULT_FLAGS = "FaultFlags";
private const string KEY_SAMPLE_RATE = "SampleRate";
private const string KEY_RECORDING_MODE = "RecordingMode";
private const string KEY_PRETRIGGER_SECONDS = "PretriggerSeconds";
private const string KEY_POSTTRIGGER_SECONDS = "PosttriggerSeconds";
private const string KEY_CONFIGDATA = "ConfigData";
private void AsyncConfigure(object configAsyncInfo)
{
var info = configAsyncInfo as RibeyeServiceAsyncInfo;
var Configuration = new Utility.XmlDictionary(); ;
var serializer = new XmlSerializer(Configuration.GetType());
if (File.Exists(RIBEYE_CONFIGURATION_FILE))
{
try
{
using (var sr = new StreamReader(RIBEYE_CONFIGURATION_FILE))
{
Configuration = (Utility.XmlDictionary)serializer.Deserialize(sr);
}
}
catch (Exception)
{
}
}
Configuration.Dictionary[KEY_TESTID] = ConfigData.TestID;
Configuration.Dictionary[KEY_TEST_DESCRIPTION] = ConfigData.Description;
Configuration.Dictionary[KEY_SAMPLE_RATE] = ConfigData.Modules.FirstOrDefault().SampleRateHz;
Configuration.Dictionary[KEY_RECORDING_MODE] = ConfigData.Modules.FirstOrDefault().RecordingMode;
Configuration.Dictionary[KEY_PRETRIGGER_SECONDS] = ConfigData.Modules.FirstOrDefault().PreTriggerSeconds;
Configuration.Dictionary[KEY_POSTTRIGGER_SECONDS] = ConfigData.Modules.FirstOrDefault().PostTriggerSeconds;
Configuration.Dictionary[KEY_CONFIGDATA] = ConfigurationData.Serialize((ConfigurationData)ConfigData);
using (var writer = new StreamWriter(RIBEYE_CONFIGURATION_FILE))
{
serializer.Serialize(writer, Configuration);
writer.Close();
}
ConfigurationData.SetConfiguration(this, File.ReadAllText(RIBEYE_CONFIGURATION_FILE), ConfigurationData.DIAGNOSTIC_FILESTORE);
ConfigureHasBeenRun = true;
if (info.DiscardDiagnostics) { DiagnosticsHasBeenRun = false; }
info.Success();
}
private void AsyncCheckSafetyState(object configAsyncInfo)
{
// ribeye doesn't have safety switch info, so might as well return right away.
var info = configAsyncInfo as RibeyeServiceAsyncInfo;
info.Success();
}
///
/// Retrieve configuration from DAS and store it in the ConfigData property
///
/// The function to call with information
/// Whatever you want to pass along
void IConfigurationActions.QueryConfiguration(ServiceCallback callback, object userData, uint crc, string strConfig, bool bReadIds, bool bDeviceScaleFactors,
bool differentModuleCountsAreOK)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.QueryConfiguration", new WaitCallback(AsyncQueryConfiguration), info);
}
void IConfigurationActions.UpdateConfigurationFromFile(ServiceCallback callback, object userData,
string filePath)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.UpdateConfigurationFromFile", new WaitCallback(AsyncUpdateConfigurationFromFile),
info);
}
private void AsyncUpdateConfigurationFromFile(object asyncInfo)
{
var info = asyncInfo as RibeyeServiceAsyncInfo;
info.Error("Not supported yet");
return;
}
private void AsyncQueryConfiguration(object configAsyncInfo)
{
var info = configAsyncInfo as RibeyeServiceAsyncInfo;
try
{
var Configuration = new Utility.XmlDictionary(); ;
var serializer = new XmlSerializer(Configuration.GetType());
if (File.Exists(RIBEYE_CONFIGURATION_FILE))
{
try
{
using (var sr = new StreamReader(RIBEYE_CONFIGURATION_FILE))
{
Configuration = (Utility.XmlDictionary)serializer.Deserialize(sr);
}
}
catch (Exception)
{
}
}
if (Configuration.Dictionary.ContainsKey(KEY_CONFIGDATA))
{
ConfigData = ConfigurationData.DeserializeFromString((string)Configuration.Dictionary[KEY_CONFIGDATA]);
}
else
{
ConfigData = MakeDefaultConfigFromInfo();
}
if (Configuration.Dictionary.ContainsKey(KEY_TESTID))
{
ConfigData.TestID = Configuration.Dictionary[KEY_TESTID] as string;
}
if (Configuration.Dictionary.ContainsKey(KEY_TEST_DESCRIPTION))
{
ConfigData.Description = Configuration.Dictionary[KEY_TEST_DESCRIPTION] as string;
}
else
{
ConfigData.Description = "";
}
if (Configuration.Dictionary.ContainsKey(KEY_SAMPLE_RATE))
{
ConfigData.Modules.FirstOrDefault().SampleRateHz = (uint)Configuration.Dictionary[KEY_SAMPLE_RATE];
}
if (Configuration.Dictionary.ContainsKey(KEY_PRETRIGGER_SECONDS))
{
ConfigData.Modules.FirstOrDefault().PreTriggerSeconds = (double)Configuration.Dictionary[KEY_PRETRIGGER_SECONDS];
}
if (Configuration.Dictionary.ContainsKey(KEY_POSTTRIGGER_SECONDS))
{
ConfigData.Modules.FirstOrDefault().PostTriggerSeconds = (double)Configuration.Dictionary[KEY_POSTTRIGGER_SECONDS];
}
// get scale factors
try
{
var scaleFactors = GetScaleFactors();
// set the OwningDAS and OwningModule since it was skipped during serialization
foreach (var iDASModule in ConfigData.Modules)
{
var module = (DASModule)iDASModule;
module.OwningDAS = this;
foreach (var iDASchannel in module.Channels)
{
var channel = (DASChannel)iDASchannel;
channel.OwningModule = module;
// pick up the scalefactor for this channel
if (channel is AnalogInputDASChannel analog)
{
var dasChannelNumber = DASInfo.MapModuleArrayIndexAndChannelNum2DASChannel(module.ModuleArrayIndex, analog.ModuleChannelNumber);
analog.ScalefactorMilliVoltsPerADC = scaleFactors[dasChannelNumber];
analog.IDs = RetriveEIDs(dasChannelNumber);
}
}
}
}
catch
{
// we don't need no stinking scale factors
}
// get sensor ID's
if (ConfigData.Modules != null)
{
foreach (var iDASModule in ConfigData.Modules)
{
var module = (DASModule)iDASModule;
module.OwningDAS = this; // in case bailed out above
foreach (var iDASChannel in module.Channels)
{
var channel = (DASChannel)iDASChannel;
channel.OwningModule = module; // in case bailed out above
var dasChannelNumber = DASInfo.MapModuleArrayIndexAndChannelNum2DASChannel(module.ModuleArrayIndex, channel.ModuleChannelNumber);
channel.IDs = RetriveEIDs(dasChannelNumber);
}
}
}
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
private DASModule MakeConfigModuleFromInfoModule(InfoResult.Module infoModule)
{
var configModule = new DASModule(infoModule.ModuleArrayIndex, this);
if (infoModule.TypeOfModule != DFConstantsAndEnums.ModuleType.RibeyeLED)
{
throw new Exception("Ribeye.MakeConfigModuleFromInfoModule: Unsupported slice type " + infoModule.TypeOfModule.ToString());
}
configModule.Channels = new AnalogInputDASChannel[infoModule.NumberOfChannels];
for (var channelIdx = 0; channelIdx < infoModule.NumberOfChannels; channelIdx++)
{
configModule.Channels[channelIdx] = new AnalogInputDASChannel(configModule, channelIdx);
}
return configModule;
}
private ConfigurationData MakeDefaultConfigFromInfo()
{
var conf = new ConfigurationData();
if (DASInfo != null && DASInfo.Modules != null && DASInfo.Modules.Length > 0)
{
conf.Modules = new DASModule[DASInfo.Modules.Length];
for (var moduleIdx = 0; moduleIdx < DASInfo.Modules.Length; moduleIdx++)
{
conf.Modules[moduleIdx] = MakeConfigModuleFromInfoModule((InfoResult.Module)DASInfo.Modules[moduleIdx]);
}
}
return conf;
}
void IConfigurationActions.Reboot(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
///
/// Retrieve the EID's and store it in the ConfigData property
///
/// The function to call with information
/// Whatever you want to pass along
void IConfigurationActions.UpdateIDs(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.UpdateIDs", new WaitCallback(AsyncUpdateIDs), info);
}
void IConfigurationActions.UpdateId(ServiceCallback callback, object userData, DASModule module, DASChannel channel)
{
var info = new UpdateIdsInfo(callback, userData, module, channel);
LaunchAsyncWorker("Ribeye.UpdateId", new WaitCallback(AsyncUpdateId), info);
}
private class UpdateIdsInfo : RibeyeServiceAsyncInfo
{
public DASModule Module { get; set; }
public DASChannel Channel { get; set; }
public UpdateIdsInfo(ServiceCallback callback, object userData, DASModule module, DASChannel channel)
: base(callback, userData)
{
Module = module;
Channel = channel;
}
}
private void AsyncUpdateIDs(object configAsyncInfo)
{
var info = configAsyncInfo as RibeyeServiceAsyncInfo;
if (ConfigData == null)
{
info.Error("DAS doesn't have any ConfigData");
return;
}
try
{
// get sensor ID's
if (ConfigData.Modules != null)
{
foreach (var module in ConfigData.Modules)
{
foreach (var channel in module.Channels)
{
var dasChannelNumber = DASInfo.MapModuleArrayIndexAndChannelNum2DASChannel(module.ModuleArrayIndex, channel.ModuleChannelNumber);
channel.IDs = RetriveEIDs(dasChannelNumber);
}
}
}
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
private void AsyncUpdateId(object configAsyncInfo)
{
var info = configAsyncInfo as UpdateIdsInfo;
try
{
// get sensor ID's
var dasChannelNumber = DASInfo.MapModuleArrayIndexAndChannelNum2DASChannel(info.Module.ModuleArrayIndex, info.Channel.ModuleChannelNumber);
info.Channel.IDs = RetriveEIDs(dasChannelNumber);
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
private float[] GetScaleFactors()
{
var LEDQuery = new QueryNumberOfLEDs(this);
LEDQuery.SyncExecute();
var ScaleFactors = new float[LEDQuery.NumberOfLEDs * 3];
for (var Index = 0; Index < ScaleFactors.Length; Index++)
{
ScaleFactors[Index] = (float)(1.0 / 100.0);
}
return ScaleFactors;
}
private EID[] RetriveEIDs(byte DASChannelNumber)
{
if (RunTestVariables.BypassEIDRead) { return new EID[0]; }
var idList = new List();
uint LEDNumber = (uint)DASChannelNumber / 3;
uint AxisNumber = (uint)DASChannelNumber % 3;
var EID = "E" + SerialNumber + LEDNumber.ToString("00") + AxisNumber.ToString("0");
idList.Add(new EID(EID));
return idList.ToArray();
}
#endregion
#region Diagnostics
// our public diagnostics member
///
/// ChannelDiagnostics is used to indicate which diagnostics are requested
///
public IDiagnosticActions[] ChannelDiagnostics { get; set; }
public IArmCheckActions ArmCheckActions { get; set; }
public IArmCheckResults ArmCheckResults { get; set; }
///
/// ChannelDiagnosticsResults contains the results of a diagnostics service.
///
public IDiagnosticResult[] ChannelDiagnosticsResults { get; set; }
public void SetChannelDiagnosticActions(IDiagnosticActions[] actions, bool setInDb = true)
{
DiagnosticsActions.SetChannelDiagnosticActions(this, actions, setInDb);
}
public void ClearChannelDiagnosticsResults(bool bClearDb = true)
{
DiagnosticsResultActions.ClearChannelDiagnosticsResults(this, bClearDb);
}
public void SetChannelDiagnosticsResults(IDiagnosticResult[] results, bool setInDb)
{
DiagnosticsResultActions.SetChannelDiagnosticsResults(this, results, setInDb);
}
public IModuleDiagnosticsResult[] ModuleDiagnosticsResults { get; set; }
///
/// BaseInput contains information about diagnostics for the module.
///
public IBaseInputValues BaseInput { get; set; }
#region Clock Sync
public IDictionary DASClockSyncStatus { get; set; } = null;
public bool ClockSyncInUTC { get; set; } = false;
public ClockSyncProfile DASClockSyncProfile { get; set; }
public byte PTPDomainID { get; set; }
#endregion
void IDiagnosticsActions.GetBridgeMeasurement(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.GetBridgeMeasurement", new WaitCallback(AsyncDiagnosAndGetResults), info);
}
void IDiagnosticsActions.MeasureTransferSpeed(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
#region Voltage Check
public void PerformVoltageCheck(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.PerformVoltageCheck", new WaitCallback(AsyncPerformVoltageCheck), info);
}
private void AsyncPerformVoltageCheck(object o)
{
RibeyeServiceAsyncInfo info = o as RibeyeServiceAsyncInfo;
info.Success();
}
public void PerformVoltageCheckTAOnly(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.PerformVoltageCheckTAOnly", new WaitCallback(AsyncPerformVoltageCheckTAOnly), info);
}
private void AsyncPerformVoltageCheckTAOnly(object o)
{
RibeyeServiceAsyncInfo info = o as RibeyeServiceAsyncInfo;
info.Success();
}
void IDiagnosticsActions.PerformArmChecks(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.PerformArmChecks", new WaitCallback(AsyncPerformArmChecks), info);
}
void IDiagnosticsActions.SaveTiltSensorDataPre(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.SaveTiltSensorDataPre", new WaitCallback(AsyncSaveTiltSensorDataPre), info);
}
void IDiagnosticsActions.SaveTemperaturesPre(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.SaveTemperaturesPre", new WaitCallback(AsyncSaveTemperaturesPre), info);
}
#endregion Voltage Check
private void AsyncPerformArmChecks(object o)
{
if (!(o is RibeyeServiceAsyncInfo info)) { return; }
info.Success();
}
private void AsyncSaveTiltSensorDataPre(object o)
{
if (!(o is RibeyeServiceAsyncInfo info)) { return; }
info.Success();
}
private void AsyncSaveTemperaturesPre(object o)
{
if (!(o is RibeyeServiceAsyncInfo info)) { return; }
info.Success();
}
///
/// Perform diagnostics based on the property ChannelDiagnostics and stuff the
/// result in ChannelDiagnosticsResults
///
/// The function to call with information
/// Whatever you want to pass along
/// The AA filter frequency for diagnostics. Not used by Ribeye
/// The sample rate for diagnostics. Not used by Ribeye
void IDiagnosticsActions.PrepareForDiagnostics(UInt32 DiagnosticsSampleRateHz,
float DiagnosticsAAFilterFrequencyHz,
PrePostResults WhichResult,
ServiceCallback callback,
object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.PrepareForDiagnostics", new WaitCallback(AsyncPrepareForDiagnostics), info);
}
///
/// the working guts of PrepareForDiagnostics
///
/// our async data
private void AsyncPrepareForDiagnostics(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
try
{
// we're done
info.Success();
}
catch (CanceledException)
{
// like most tv shows, we have been canceled
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
///
/// Perform diagnostics based on the property ChannelDiagnostics and stuff the
/// result in ChannelDiagnosticsResults
///
/// The function to call with information
/// Whatever you want to pass along
/// The AA filter rate for
/// diagnostics. Not used by Ribeye
/// The sample rate for diagnostics. Not
/// used by Ribeye
void IDiagnosticsActions.PrepareForBridgeResistanceMeasurement(UInt32 DiagnosticsSampleRateHz,
float DiagnosticsAAFilterFrequencyHz,
ServiceCallback callback,
object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.PrepareForBridgeResistanceMeasurement", new WaitCallback(AsyncPrepareForBridgeResistanceMeasurement), info);
}
///
/// the working guts of PrepareForBridgeResistanceMeasurement
///
/// our async data
private void AsyncPrepareForBridgeResistanceMeasurement(object asyncInfo)
{
var info = asyncInfo as RibeyeServiceAsyncInfo;
try
{
// we're done
info.Success();
}
catch (CanceledException)
{
// like most tv shows, we have been canceled
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
public void SetStatusIndicator(DiagnosticsStatusIndicatorState state, ServiceCallback callback, object userData)
{
}
public void TurnOffT0Lights(ServiceCallback callback, object userData)
{
}
///
/// Perform diagnostics based on the property ChannelDiagnostics and stuff the
/// result in ChannelDiagnosticsResults
///
/// The function to call with information
/// Whatever you want to pass along
void IDiagnosticsActions.DiagnosAndGetResults(int EventNumber,
PrePostResults WhichResult,
ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.DiagnosAndGetResults", new WaitCallback(AsyncDiagnosAndGetResults), info);
}
///
/// the working guts of DiagnosAndGetResults
///
/// our async data
private void AsyncDiagnosAndGetResults(object asyncInfo)
{
var info = asyncInfo as RibeyeServiceAsyncInfo;
try
{
// prepare the result array
var results = new DiagnosticsResult[ChannelDiagnostics.Length];
for (var idx = 0; idx < ChannelDiagnostics.Length; idx++)
{
results[idx] = new DiagnosticsResult();
results[idx].DASChannelNumber = ChannelDiagnostics[idx].DASChannelNumber;
results[idx].EventNumber = DFConstantsAndEnums.EVENT_NUMBER_PRETEST_DIAG; // it's not really an event
}
// There's only one diagnostic, the current positions
var Query = new QueryCurrentPositions(this);
Query.SyncExecute();
var ScaleFactors = GetScaleFactors();
for (var idx = 0; idx < ChannelDiagnostics.Length; idx++)
{
results[idx].ExpectedExcitationMilliVolts = 5000;
results[idx].MeasuredOffsetMilliVolts = Query.Positions[ChannelDiagnostics[idx].DASChannelNumber];
// This is not the real scale factor. But it will make the diagnostics happy. It's OK
// do to this because the real scale factor is queried elsewhere for use with download
var ModuleIndex = ChannelDiagnostics[idx].DASChannelNumber / ConfigData.Modules[0].NumberOfChannels();
var ChannelIndex = ChannelDiagnostics[idx].DASChannelNumber % 3;
AnalogInputDASChannel channel = ConfigData.Modules[ModuleIndex].Channels[ChannelIndex] as AnalogInputDASChannel;
if (null == channel)
{
results[idx].ScalefactorMilliVoltsPerADC = ScaleFactors[ChannelDiagnostics[idx].DASChannelNumber];
}
else
{
results[idx].ScalefactorMilliVoltsPerADC = channel.SensorCapacityEU / Constants.ADC_MIDPOINT;
// Need to update this value for consistency
channel.ScalefactorMilliVoltsPerADC = results[idx].ScalefactorMilliVoltsPerADC;
channel.NoiseAsPercentOfFullScale = null != results[idx].NoisePercentFullScale ? (double)results[idx].NoisePercentFullScale : 0D;
}
results[idx].FinalOffsetADC = (short)(results[idx].MeasuredOffsetMilliVolts / results[idx].ScalefactorMilliVoltsPerADC);
if (channel.RemoveOffset)
{
var ADC = (double)results[idx].MeasuredOffsetMilliVolts / results[idx].ScalefactorMilliVoltsPerADC;
var devPercent = 100D * ADC / short.MaxValue;
results[idx].AutoZeroPercentDeviation = devPercent;
}
else { results[idx].AutoZeroPercentDeviation = null; }
}
SetChannelDiagnosticsResults(results, true);
info.Success();
}
catch (CanceledException)
{
// like most tv shows, we have been canceled
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
///
/// Retrieve the results from the implicit pre and post event diagnostics
///
/// Which event number to Retrieve from
/// The pre or post test results?
/// The function to call with information
/// Whatever you want to pass along
void IDiagnosticsActions.GetEventDiagnosticsResults(int EventNumber,
PrePostResults WhichResult,
ServiceCallback callback,
object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.GetEventDiagnosticsResults", new WaitCallback(AsyncGetEventDiagnosticsResults), info);
}
private void AsyncGetEventDiagnosticsResults(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
try
{
DiagnosticsResult[] resultArray = null;
var scaleFactors = GetScaleFactors();
resultArray = new DiagnosticsResult[scaleFactors.Length];
for (int idx = 0; idx < scaleFactors.Length; idx++)
{
resultArray[idx] = new DiagnosticsResult();
resultArray[idx].DASChannelNumber = idx;
resultArray[idx].EventNumber = 1;
resultArray[idx].ScalefactorMilliVoltsPerADC = scaleFactors[idx];
}
SetChannelDiagnosticsResults(resultArray, true);
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
#endregion
#region Realtime
///
/// indicates whether the DAS supports streaming
/// 10572 implement SW side for single command streaming realtime
///
public bool SupportsIndividualChannelRealtimeStreaming => false;
public bool SupportsHardwareInputCheck() { return false; }
public bool ControlsDAQ() { return true; }
public bool SupportsAutoArm() { return false; }
public bool SupportsLevelTrigger() { return false; }
public bool SupportsMultipleEvents() { return false; }
public bool SupportsMultipleConfigurations() { return false; }
public bool SupportsRealtime() { return false; }
public bool SupportsStartInversion() => HardwareConstants.SupportsStartInversion(GetHardwareType(), ProtocolVersion);
public bool SupportsTriggerInversion() => HardwareConstants.SupportsTriggerInversion(GetHardwareType(), ProtocolVersion);
public bool InvertTrigger
{
get => false;
set { if (value) { throw new NotSupportedException("Ribeye doesn't support trigger inversion"); } }
}
public bool InvertStart
{
get => false;
set { if (value) { throw new NotSupportedException("Ribeye doesn't support start inversion"); } }
}
public bool IgnoreShortedStart
{
get => false;
set { if (value) { throw new NotSupportedException("Ribeye doesn't support ignore shorted start"); } }
}
public bool IgnoreShortedTrigger
{
get => false;
set { if (value) { throw new NotSupportedException("Ribeye doesn't support ignore shorted trigger"); } }
}
public bool SupportsMultipleSampleRealtime() { return false; }
///
/// A list of channels to use with the Realtime service.
///
public List RealtimeDASChannels { get; set; }
public List TiltAxisData { get; set; }
EventWaitHandle QuitRealtime;
private class RealTimeAsyncPacket
{
public RibeyeServiceAsyncInfo Info { get; set; }
public System.Threading.Timer Timer { get; set; }
public int SamplesPerSecond { get; set; }
public int MillisecBetweenSamples { get; set; }
public bool AllowMultipleSampleRealtime { get; set; }
}
void IRealTimeActions.RealTime(int samplesPerSecond,
int millisecBetweenSamples,
ServiceCallback callback,
object userData,
bool allowMultipleSampleRealtime,
int moduleIndex,
ManualResetEvent stopEvent,
byte[] channels,
double aaf,
int minCAllbackUpdateTimeMs,
bool UseUDPStreaming,
string hostIPAddress)
{
var packet = new RealTimeAsyncPacket();
packet.Info = new RibeyeServiceAsyncInfo(callback, userData);
packet.SamplesPerSecond = samplesPerSecond;
packet.MillisecBetweenSamples = millisecBetweenSamples;
packet.AllowMultipleSampleRealtime = allowMultipleSampleRealtime;
QuitRealtime = new EventWaitHandle(false, EventResetMode.ManualReset);
LaunchAsyncWorker("Ribeye.RealTime", new WaitCallback(AsyncRealTime), packet);
}
void IRealTimeActions.RealTimePolling(ServiceCallback callback,
object userData,
ManualResetEvent stopEvent,
byte[] channels
)
{
var packet = new RealTimeAsyncPacket();
packet.Info.Success();
}
void IRealTimeActions.RealTimeTiltPolling(ServiceCallback callback, object userData, ManualResetEvent stopEvent)
{
var packet = new RealTimeAsyncPacket();
packet.Info.Success();
}
private void AsyncRealTime(object asyncInfo)
{
var packet = (RealTimeAsyncPacket)asyncInfo;
packet.Info.Success();
}
void IRealTimeActions.ExitRealTimeMode(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.ExitRealTimeMode", new WaitCallback(AsyncExitRealTimeMode), info);
}
private void AsyncExitRealTimeMode(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
try
{
QuitRealtime.Set();
if (null != DASArmStatus) DASArmStatus.IsInRealtime = false;// FB15550: Update IsInRealtime flag if we exit RT so DataPRO is aware
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
public string UDPStreamAddress { get; }
void IRealTimeActions.SetUDPStreamProfile(ServiceCallback callback, object userData, UDPStreamProfile streamProfile, string udpAddress, ushort timeChannelId, ushort dataChannelId, uint[] tmnsConfig, ushort irigTimeDataPacketIntervalMs)
{
var packet = new RealTimeAsyncPacket();
packet.Info.Success();
}
void IRealTimeActions.GetUDPStreamProfile(ServiceCallback callback, object userData)
{
var packet = new RealTimeAsyncPacket();
packet.Info.Success();
}
#endregion
#region Arming
///
/// The arm status information
///
public IArmStatusData DASArmStatus { get; set; }
public bool GetIsInArm()
{
if (null == DASArmStatus) { return false; }
return DASArmStatus.IsArmed;
}
public bool GetIsInRealtime()
{
if (null == DASArmStatus) { return false; }
return DASArmStatus.IsInRealtime;
}
///
/// returns true if the unit is known to be streaming
/// does not query the hardware, just returns a flag if it has been set
///
///
public bool GetIsStreaming()
{
return false;
}
public void SetDASArmStatus(IArmStatusData status, bool bSetInDb)
{
ArmStatus.SetArmStatus(this, status, bSetInDb);
}
public void SetInArm(bool WriteToDb)
{
if (null == DASArmStatus)
{
var armStatus = new ArmStatus()
{
IsArmed = true
};
ArmStatus.SetArmStatus(this, armStatus, WriteToDb);
}
else
{
DASArmStatus.IsArmed = true;
if (WriteToDb)
{
SetDASArmStatus();
}
}
}
public void SetInRealtime(bool WriteToDb, bool ExitRealtimeIfPossible)
{
if (null == DASArmStatus)
{
var armStatus = new ArmStatus()
{
IsInRealtime = true
};
ArmStatus.SetArmStatus(this, armStatus, WriteToDb);
}
else
{
DASArmStatus.IsInRealtime = true;
if (WriteToDb)
{
SetDASArmStatus();
}
}
}
public void SetDASArmStatus()
{
ArmStatus.SetArmStatus(this, DASArmStatus, true);
}
public DFConstantsAndEnums.CommandStatus AutoArmStatus { get; set; } = DFConstantsAndEnums.CommandStatus.StatusNoError;
public FlashEraseStatus DASFlashEraseStatus { get; set; }
void IArmActions.BeginFlashErase(ServiceCallback callback, object userData, bool DummyArm)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
void IArmActions.QueryFlashEraseStatus(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
var eraseStatus = new FlashEraseStatus();
eraseStatus.PercentComplete = 100.0f;
eraseStatus.LastError = DFConstantsAndEnums.CommandStatus.StatusNoError;
DASFlashEraseStatus = eraseStatus;
info.Success();
}
///
/// Arm a single DAS now
///
/// The function to call with information
/// Whatever you want to pass along
/// A unique GUID that this event will be tagged
/// with
void IArmActions.ArmNow(ServiceCallback callback, object userData,
Guid eventGuid, int armNowTimeout, bool testingMode, int maxNumberEvents, bool SysMode)
{
var info = new RibeyeArmNowPacket(callback, userData, armNowTimeout);
LaunchAsyncWorker("Ribeye.ArmNow", new WaitCallback(AsyncArmNow), info);
var Configuration = new Utility.XmlDictionary(); ;
var serializer = new XmlSerializer(Configuration.GetType());
if (File.Exists(RIBEYE_CONFIGURATION_FILE))
{
try
{
using (var sr = new StreamReader(RIBEYE_CONFIGURATION_FILE))
{
Configuration = (Utility.XmlDictionary)serializer.Deserialize(sr);
}
}
catch (Exception)
{
}
}
Configuration.Dictionary[KEY_TEST_GUID] = eventGuid;
using (var writer = new StreamWriter(RIBEYE_CONFIGURATION_FILE))
{
serializer.Serialize(writer, Configuration);
writer.Close();
}
}
void IArmActions.PrepareForArmNow(ServiceCallback callback, object userData,
Guid eventGuid, int armNowTimeout, bool testingMode, int maxNumberEvents, bool SysMode)
{
var info = new RibeyeArmNowPacket(callback, userData, armNowTimeout);
LaunchAsyncWorker("Ribeye.PrepareForArmNow", new WaitCallback(AsyncPrepareForArmNow), info);
var Configuration = new Utility.XmlDictionary(); ;
var serializer = new XmlSerializer(Configuration.GetType());
if (File.Exists(RIBEYE_CONFIGURATION_FILE))
{
try
{
using (var sr = new StreamReader(RIBEYE_CONFIGURATION_FILE))
{
Configuration = (Utility.XmlDictionary)serializer.Deserialize(sr);
}
}
catch (Exception)
{
}
}
Configuration.Dictionary[KEY_TEST_GUID] = eventGuid;
using (var writer = new StreamWriter(RIBEYE_CONFIGURATION_FILE))
{
serializer.Serialize(writer, Configuration);
writer.Close();
}
}
void IArmActions.ReArm(ServiceCallback callback, object userData, bool autoArm, bool arm, bool repeatEnable)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Error("NotSupported");
}
void IArmActions.PreparedArmNow(ServiceCallback callback, object userData,
Guid eventGuid, int armNowTimeout, bool testingMode, int maxNumberEvents, bool SysMode)
{
var info = new RibeyeArmNowPacket(callback, userData, armNowTimeout);
LaunchAsyncWorker("Ribeye.PreparedArmNow", new WaitCallback(AsyncPreparedArmNow), info);
var Configuration = new Utility.XmlDictionary(); ;
var serializer = new XmlSerializer(Configuration.GetType());
if (File.Exists(RIBEYE_CONFIGURATION_FILE))
{
try
{
using (var sr = new StreamReader(RIBEYE_CONFIGURATION_FILE))
{
Configuration = (Utility.XmlDictionary)serializer.Deserialize(sr);
}
}
catch (Exception)
{
}
}
Configuration.Dictionary[KEY_TEST_GUID] = eventGuid;
using (var writer = new StreamWriter(RIBEYE_CONFIGURATION_FILE))
{
serializer.Serialize(writer, Configuration);
writer.Close();
}
}
private void AsyncArmNow(object asyncInfo)
{
var info = asyncInfo as RibeyeArmNowPacket;
try
{
var Prepare = new PrepareForDataCollection(this, 60000);
Prepare.SyncExecute();
// After we've reset the event list, our (the DAS) EventInfo property is now invalid
SetEventInfo(null);
var ArmNow = new Arm(this, info.ArmNowTimeout);
// Ribeye has different logic than we do. Map theirs to ours
if (ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.CircularBuffer)
{
ArmNow.TStopMS = 0;
ArmNow.TPostMS = (uint)(1000.0 * ConfigData.Modules[0].PostTriggerSeconds);
}
else
{
ArmNow.TStopMS = (uint)(1000.0 * (ConfigData.Modules[0].PostTriggerSeconds + ConfigData.Modules[0].PreTriggerSeconds));
ArmNow.TPostMS = (uint)(1000.0 * ConfigData.Modules[0].PostTriggerSeconds);
}
ArmNow.SyncExecute();
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
private void AsyncPrepareForArmNow(object asyncInfo)
{
var info = (RibeyeArmNowPacket)asyncInfo;
try
{
var Prepare = new PrepareForDataCollection(this, 60000);
Prepare.SyncExecute();
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
private void AsyncPreparedArmNow(object asyncInfo)
{
var info = (RibeyeArmNowPacket)asyncInfo;
try
{
// After we've reset the event list, our (the DAS) EventInfo property is now invalid
SetEventInfo(null);
var ArmNow = new Arm(this, info.ArmNowTimeout);
// Ribeye has different logic than we do. Map theirs to ours
if (ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.CircularBuffer)
{
ArmNow.TStopMS = 0;
ArmNow.TPostMS = (uint)(1000.0 * ConfigData.Modules[0].PostTriggerSeconds);
}
else
{
ArmNow.TStopMS = (uint)(1000.0 * (ConfigData.Modules[0].PostTriggerSeconds + ConfigData.Modules[0].PreTriggerSeconds));
ArmNow.TPostMS = (uint)(1000.0 * ConfigData.Modules[0].PostTriggerSeconds);
}
ArmNow.SyncExecute();
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
///
/// Arm multiple chained DAS now
///
/// The function to call with information
/// Whatever you want to pass along
void IArmActions.EnableFaultChecking(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.EnableFaultChecking", new WaitCallback(AsyncEnableFaultChecking), info);
}
void IArmActions.CheckAlreadyLevelTriggered(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.CheckAlreadyLevelTriggered", new WaitCallback(AsyncCheckAlreadyLevelTriggered), info);
}
private void AsyncCheckAlreadyLevelTriggered(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
try
{
foreach (var m in ConfigData.Modules)
{
foreach (var ch in m.Channels)
{
if (ch is AnalogInputDASChannel)
{
(ch as AnalogInputDASChannel).AlreadyLevelTriggered = false;
}
}
}
info.Success();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
private void AsyncEnableFaultChecking(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
try
{
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
///
/// DisAutoArm the DAS
///
/// The function to call with information
/// Whatever you want to pass along
void IArmActions.DisAutoArm(ServiceCallback callback, object userData)
{
throw new NotSupportedException("DisAutoArm not supported for Ribeye");
}
///
/// Disarm the DAS
///
/// The function to call with information
/// Whatever you want to pass along
void IArmActions.Disarm(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.EnableDisarm", new WaitCallback(AsyncDisarm), info);
}
private void AsyncDisarm(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
try
{
var DisarmCommand = new Disarm(this);
DisarmCommand.SyncExecute();
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
void IArmActions.GetExtendedFaultIds(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.GetExtendedFaultIds", new WaitCallback(RibeyeAsyncGetExtendedFaultIds), info);
}
private void RibeyeAsyncGetExtendedFaultIds(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
info.Success();
}
///
/// Retrieve the current arm status from the DAS
///
/// The function to call with information
/// Whatever you want to pass along
void IArmActions.GetArmStatus(ServiceCallback callback, object userData, uint inputVoltageCutoff, int maxTimeout)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.GetArmStatus", new WaitCallback(RibeyeAsyncGetArmStatus), info);
}
private void RibeyeAsyncGetArmStatus(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
try
{
var armStatus = new ArmStatus();
var Status = new QueryArmAndTriggerStatus(this);
Status.IO_Timeout = 3000;
try
{
Status.SyncExecute();
}
catch (Exception)
{
Flush(500);
Status = new QueryArmAndTriggerStatus(this);
Status.IO_Timeout = 3000;
Status.SyncExecute();
}
armStatus.IsArmed = Status.IsArmed;
armStatus.IsFaulted = false;
armStatus.IsRecording = Status.IsRecording;
armStatus.IsTriggered = Status.IsTriggered;
armStatus.IsInRealtime = false;
armStatus.IsRearming = false;
// !!!! Do something better!!!!!
armStatus.TotalSamples = 300000;
armStatus.CurrentSample = 0;
armStatus.SampleRate = (uint)RibeyeSampleRate;
armStatus.TimeRemainingSeconds = 30;
armStatus.EventNumber = 0;
armStatus.RecordingMode = 0;
SetDASArmStatus(armStatus, true);
Thread.Sleep(50);
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
///
/// Retrieve the current arm status from the DAS
///
/// The function to call with information
/// Whatever you want to pass along
void IArmActions.GetAutoArmStatus(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.GetAutoArmStatus", new WaitCallback(RibeyeAsyncGetAutoArmStatus), info);
}
private void RibeyeAsyncGetAutoArmStatus(object asyncInfo)
{
var info = asyncInfo as RibeyeServiceAsyncInfo;
AutoArmStatus = DFConstantsAndEnums.CommandStatus.StatusUnimplemented;
info.Success();
}
///
/// Set the DAS to low power mode
///
/// The function to call with information
/// Whatever you want to pass along
void IArmActions.EnterLowPowerMode(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.LowPowerMode", new WaitCallback(RibeyeAsyncLowPowerMode), info);
}
private void RibeyeAsyncLowPowerMode(object asyncInfo)
{
var info = asyncInfo as RibeyeServiceAsyncInfo;
DiagnosticsHasBeenRun = false;
try
{
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
///
/// Tells the DAS to start record
///
/// The function to call with information
/// Whatever you want to pass along
void IArmActions.StartRecord(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.StartRecord", new WaitCallback(RibeyeAsyncStartRecord), info);
}
private void RibeyeAsyncStartRecord(object asyncInfo)
{
// ribeye doesn't have software start. Trigger is the next best thing.
RibeyeAsyncTrigger(asyncInfo);
}
///
/// Sends trigger signal to HW
///
/// The function to call with information
/// Whatever you want to pass along
void IArmActions.Trigger(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.Trigger", new WaitCallback(RibeyeAsyncTrigger), info);
}
private void RibeyeAsyncTrigger(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
try
{
Trigger Trigger = new Trigger(this);
Trigger.SyncExecute();
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
#endregion
#region Trigger check
// our public trigger check member
public ITriggerCheckResult TriggerResult { get; set; }
#endregion
#region Downloading
void IDownloadActions.SetEventInfo(int eventIndex,
string id,
Guid guid,
ulong totalSamples,
ulong[] triggerSamples,
ulong startRecordSample,
UInt32 eventHasDownloaded,
ServiceCallback callback,
object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Error("Setting event info not supported on Ribeye");
}
private class RibeyeDownloadState : RibeyeServiceAsyncInfo
{
public IDownloadRequest Request;
public ulong SamplesDownloaded; // how many samples have we downloaded so far
public DownloadTestData DownloadCommand;
public RibeyeDownloadState(ServiceCallback cb, object cbObj, IDownloadRequest _Request)
: base(cb, cbObj)
{
Request = _Request;
SamplesDownloaded = 0;
DownloadCommand = null;
}
}
public IDownloadRequest WhatToDownload { get; set; }
public void SetWhatToDownload(IDownloadRequest request, bool bSetInDb = true)
{
DownloadRequest.SetWhatToDownload(this, request, bSetInDb);
}
public IDownloadReport EventInfo { get; set; }
public void SetEventInfo(IDownloadReport eventInfo, bool bSetInDb = true)
{
DownloadReport.SetEventInfo(this, eventInfo, bSetInDb);
}
public bool[] EventDownloadedStatus { get; set; }
public void SetEventDownloadStatus(bool[] status, bool storeInDb = true)
{
DownloadReport.SetEventDownloadStatus(this, status, storeInDb);
}
public void SetEventGuids(Guid[] guids, bool storeInDb = true)
{
DownloadReport.SetEventGuids(this, guids, storeInDb);
}
public Guid[] EventGuids { get; set; }
public ushort[] FaultFlags { get; set; }
public void SetEventFaultFlags(ushort[] flags, bool storeInDb = true)
{
DownloadReport.SetEventFaultFlags(this, flags, storeInDb);
}
public byte[] ArmAttempts { get; set; }
uint[] IDownload.ExtendedFaultFlags1 { get; set; }
uint[] IDownload.ExtendedFaultFlags2 { get; set; }
uint[] IDownload.ExtendedFaultFlags3 { get; set; }
uint[] IDownload.ExtendedFaultFlags4 { get; set; }
void IDownload.SetExtendedFaultFlags(uint[][] flags)
{
DownloadExtendedFaultFunctions.SetExtendedFaultFlags(flags, this);
}
public void SetEventArmAttemps(byte[] armAttempts, bool storeInDb = true)
{
DownloadReport.SetEventArmAttempts(this, armAttempts, storeInDb);
}
///
/// Download the data specified in the WhatToDownload property
///
/// The function to call with information
/// Whatever you want to pass along
void IDownloadActions.Download(ServiceCallback callback, object userData)
{
var state = new RibeyeDownloadState(callback, userData, WhatToDownload);
LaunchAsyncWorker("Ribeye.Download", new WaitCallback(Download), state);
}
private void Download(object asyncInfo)
{
var state = asyncInfo as RibeyeDownloadState;
try
{
var NumberOfChannels = EventInfo.Events[WhatToDownload.EventNumber].Modules.Sum(module => module.NumberOfChannels());
// these two are per channel of course
var TotalNumberOfSamples = WhatToDownload.EndSample - WhatToDownload.StartSample + 1;
// allocate array to return to user
var Data = new short[NumberOfChannels][];
for (var idx = 0; idx < NumberOfChannels; idx++)
{
Data[idx] = new short[TotalNumberOfSamples];
}
const uint DownloadChunkMS = 100;
for (uint CurrentMS = 0; CurrentMS < TotalNumberOfSamples / RibeyeSampleRate * 1000.0; CurrentMS += DownloadChunkMS)
{
const int MaximumRetries = 10;
var Sucess = false;
var Download = new DownloadTestData(this);
for (var CurrentRetryCount = 0; CurrentRetryCount < MaximumRetries && false == Sucess; CurrentRetryCount++)
{
Download = new DownloadTestData(this);
Download.IO_Timeout = 5000;
var StartTimeMS = (int)(WhatToDownload.StartSample / RibeyeSampleRate * 1000D + CurrentMS - EventInfo.Events[0].Modules[0].PreTriggerSeconds * 1000D);
Download.StartTimeMS = StartTimeMS;
Download.StopTimeMS = (int)Math.Min(StartTimeMS + DownloadChunkMS, (WhatToDownload.EndSample * 1000D / RibeyeSampleRate - EventInfo.Events[0].Modules[0].PreTriggerSeconds * 1000.0));
try
{
Download.SyncExecute();
Sucess = true;
}
catch (Exception)
{
APILogger.LogString("Ribeye download timed out. Retrying");
Flush(500);
}
}
// OK, we have our data block
var newData = new short[NumberOfChannels][];
for (var channelIdx = 0; channelIdx < NumberOfChannels; channelIdx++)
{
Download.GetChannelData(channelIdx, out newData[channelIdx]);
}
state.SamplesDownloaded = (ulong)(CurrentMS * RibeyeSampleRate / 1000);
state.NewData(newData, state.SamplesDownloaded, ulong.MinValue, ulong.MinValue);
var ratio = Math.Min(1D, state.SamplesDownloaded / (double)(state.Request.EndSample - state.Request.StartSample + 1));
state.Progress((int)(ratio * 100D));
}
state.Progress(100);
// send data to user
state.Success();
}
catch (CanceledException)
{
state.Cancel();
}
catch (Exception ex)
{
state.Error(ex.Message, ex);
}
}
///
/// Retrieve info about available events to download
///
/// The function to call with information
/// Whatever you want to pass along
void IDownloadActions.QueryDownload(ServiceCallback callback, object userData, int eventIndex, TDASServiceSetupInfo setupInfo)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
if (eventIndex > 0) { info.Error("only single event support - RibEye"); }
else { LaunchAsyncWorker("Ribeye.QueryDownload", new WaitCallback(RibeyeAsyncQueryDownload), info); }
}
private void RibeyeAsyncQueryDownload(object asyncInfo)
{
var info = asyncInfo as RibeyeServiceAsyncInfo;
var Configuration = new Utility.XmlDictionary();
var serializer = new XmlSerializer(Configuration.GetType());
if (File.Exists(RIBEYE_CONFIGURATION_FILE))
{
try
{
using (var sr = new StreamReader(RIBEYE_CONFIGURATION_FILE))
{
Configuration = (Utility.XmlDictionary)serializer.Deserialize(sr);
}
}
catch (Exception)
{
}
}
try
{
uint EventCount = 1;
var dlReport = new DownloadReport();
// we'll also freshen up the cached event GUIDs
var eventGuids = new Guid[EventCount];
var faultFlags = new ushort[EventCount];
try
{
dlReport.Events = new DownloadReport.EventInfo[EventCount];
for (var eventIdx = 0; eventIdx < EventCount; eventIdx++)
{
// the object to store it all in
var eventInfo = new DownloadReport.EventInfo();
// get the event level values
if (Configuration.Dictionary.ContainsKey(KEY_TEST_DESCRIPTION))
{
eventInfo.Description = Configuration.Dictionary[KEY_TEST_DESCRIPTION] as string;
}
else
{
eventInfo.Description = "";
}
if (Configuration.Dictionary.ContainsKey(KEY_TESTID))
{
eventInfo.TestID = Configuration.Dictionary[KEY_TESTID] as string;
}
eventInfo.EventNumber = eventIdx;
if (Configuration.Dictionary.ContainsKey(KEY_TEST_GUID))
{
eventInfo.TestGUID = (Guid)Configuration.Dictionary[KEY_TEST_GUID];
eventInfo.FaultFlags = (UInt16)Configuration.Dictionary[KEY_FAULT_FLAGS];
eventInfo.ClearFaults();
}
eventGuids[eventIdx] = eventInfo.TestGUID;
faultFlags[eventIdx] = 0;
eventInfo.HasBeenDownloaded = false;
var LEDs = new QueryNumberOfLEDs(this);
LEDs.SyncExecute();
var Data = new QueryDataAvailable(this);
Data.SyncExecute();
eventInfo.Modules = new DASModule[LEDs.NumberOfLEDs];
var numberOfSamples = Data.TotalMS / 1000.0 * RibeyeSampleRate;
var triggerSampleNumber = Data.PreTriggerMS / 1000.0 * RibeyeSampleRate;
//this appears to be not be used, so I commented it out to reduce compiler warnings
// 6/10/2010 - dtm
//var eventStartRecordSampleNumber = 0;
var eventStartTime = DateTime.Now;
for (var moduleIdx = 0; moduleIdx < eventInfo.Modules.Length; moduleIdx++)
{
var module = new DASModule(moduleIdx, this);
// now update the module with dynamic data
module.NumberOfSamples = (ulong)(Data.TotalMS / 1000.0 * RibeyeSampleRate);
module.TriggerSampleNumbers = new UInt64[1]; // only one so far
module.TriggerSampleNumbers[0] = (ulong)(Data.PreTriggerMS / 1000.0 * RibeyeSampleRate);
var phaseshift = GetPhaseShiftSamples(Convert.ToUInt32(module.ModuleArrayIndex),
Convert.ToDouble(ConfigData.Modules[moduleIdx].SampleRateHz),
Convert.ToUInt32(ConfigData.Modules[moduleIdx].AAFilterRateHz),
module.TriggerSampleNumbers[0]);
module.TriggerSampleNumbers[0] += phaseshift;
module.StartRecordSampleNumber = 0;
module.PreTriggerSeconds = Data.PreTriggerMS / 1000.0;
module.PostTriggerSeconds = (Data.PreTriggerMS + Data.PostTriggerMS) / 1000.0;
module.Channels = new DASChannel[3];
module.AAFilterRateHz = ConfigData.Modules[moduleIdx].AAFilterRateHz;
module.SampleRateHz = ConfigData.Modules[moduleIdx].SampleRateHz;
module.Channels = (DASChannel[])ConfigData.Modules[moduleIdx].Channels.Clone();
// update the channel info
for (uint channelIdx = 0; channelIdx < module.Channels.Length; channelIdx++)
{
module.Channels[channelIdx].EventStartTime = eventStartTime;
}
// store it in the object
eventInfo.Modules[moduleIdx] = module;
}
// store it in the object
dlReport.Events[eventIdx] = eventInfo;
}
}
finally
{
SetEventGuids(eventGuids);
SetEventFaultFlags(faultFlags);
}
// now assigned the data to the public property
SetEventInfo(dlReport);
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
void CopyDownloadChannelDataFromConfigData(AnalogInputDASChannel SourceChannel, ref AnalogInputDASChannel DestinationChannel)
{
if (null == SourceChannel)
{
throw new ArgumentException("The internal representation of a source channel was expected to be an AnalogInputDASChannel, but it was null");
}
if (null == DestinationChannel)
{
throw new ArgumentException("The internal representation of a destination channel was expected to be an AnalogInputDASChannel, but it was null");
}
DestinationChannel.BridgeResistanceOhms = SourceChannel.BridgeResistanceOhms;
DestinationChannel.ZeroPoint = SourceChannel.ZeroPoint;
DestinationChannel.BypassAAFilter = SourceChannel.BypassAAFilter;
DestinationChannel.ConfigurationMode = SourceChannel.ConfigurationMode;
DestinationChannel.DiagnosticsMode = SourceChannel.DiagnosticsMode;
}
///
/// Figure out if events have been downloaded
///
/// The function to call with information
/// Whatever you want to pass along
void IDownloadActions.QueryDownloadedStatus(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.QueryDownloadedStatus", new WaitCallback(AsyncQueryDownloadedStatus), info);
}
private void AsyncQueryDownloadedStatus(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
try
{
int EventCount = 1;
var eventDownloadedStatus = new bool[EventCount];
for (var eventIdx = 0; eventIdx < EventCount; eventIdx++)
{
eventDownloadedStatus[eventIdx] = true;
}
// now assigned the data to the public property
SetEventDownloadStatus(eventDownloadedStatus);
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
///
/// Update the recorded trigger sample numbers in HW
///
/// The function to call with information
/// Whatever you want to pass along
void IDownloadActions.SetTriggerSampleNumbers(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.SetTriggerSampleNumbers", new WaitCallback(AsyncSetTriggerSampleNumbers), info);
}
private void AsyncSetTriggerSampleNumbers(object asyncInfo)
{
var info = (RibeyeServiceAsyncInfo)asyncInfo;
try
{
info.Success();
}
catch (CanceledException)
{
info.Cancel();
}
catch (Exception ex)
{
info.Error(ex.Message, ex);
}
}
void IDownloadActions.SetDownloaded(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
info.Success();
}
#endregion
#region Information
///
/// well, something interesting going on here
/// there are multiple definitions for DASInfo property in the inherited interfaces
/// the other one is Communication_DASInfo from ICommunication
/// but since that's a different type, I'm presuming this property was intended to hide that one
/// 6/29/10 - dtm
///
public new IInfoResult DASInfo { get; set; }
public void SetDASInfo(IInfoResult dasInfo, bool bSetInDb = true)
{
InfoResult.SetDASInfo(this, dasInfo, bSetInDb);
}
public void SetDASInfo() { InfoResult.SetDASInfo(this); }
#endregion
#region Misc
///
/// Provides a string representation of this object.
///
/// a string representing this object
public override string ToString()
{
var sn = SerialNumber;
if (!string.IsNullOrEmpty(sn))
return sn;
return "Unknown DAS";
}
///
/// The number of channels that have been configured. For a Ribeye all channels are always configured
///
/// The number of channels configured
public int NumberOfConfiguredChannels()
{
if (ConfigData == null)
return 0;
return ConfigData.NumberOfConfiguredChannels();
}
///
/// The number of channels in this ribeye
///
/// The number of channels in this ribeye
public int NumberOfChannels()
{
if (ConfigData == null)
return 0;
return ConfigData.NumberOfChannels();
}
///
/// CompareTo delegate for sorting, etc.
///
/// The das to compare with this das
///
public int CompareTo(IDASCommunication das)
{
if (das == null || string.IsNullOrEmpty(das.SerialNumber) || string.IsNullOrEmpty(SerialNumber))
return 0;
return SerialNumber.CompareTo(das.SerialNumber);
}
///
/// Tracks if diagnostics have been run
///
public bool DiagnosticsHasBeenRun { get; set; }
public bool ConfigureHasBeenRun { get; set; } = false;
private class RibeyeArmNowPacket : RibeyeServiceAsyncInfo
{
public int ArmNowTimeout { get; set; }
public RibeyeArmNowPacket(ServiceCallback callback, object userData, int armNowTimeout)
: base(callback, userData)
{
ArmNowTimeout = armNowTimeout;
}
}
private class RibeyeServiceAsyncInfo
{
public ServiceCallback Callback { get; set; }
public object UserData { get; set; }
public object FunctionData { get; set; }
public bool DiscardDiagnostics { get; set; } = true;
public RibeyeServiceAsyncInfo(ServiceCallback _callback, object _userData)
{
Callback = _callback;
UserData = _userData;
}
public void Error(string msg, Exception ex)
{
try
{
var cbData = new ServiceCallbackData();
cbData.Status = ServiceCallbackData.CallbackStatus.Failure;
cbData.ErrorMessage = msg;
cbData.ErrorException = ex;
cbData.UserData = UserData;
Callback(cbData);
}
catch (Exception eex)
{
APILogger.Log("MessageBox", Strings.RibeyeAsyncInfoError, eex);
}
}
public void Error(string msg)
{
Error(msg, null);
}
public void Progress(int value)
{
try
{
var progressData = new ServiceCallbackData();
progressData.Status = ServiceCallbackData.CallbackStatus.ProgressReport;
progressData.ProgressValue = value;
progressData.UserData = UserData;
Callback(progressData);
}
catch (Exception ex)
{
APILogger.Log("MessageBox", Strings.RibeyeAsyncInfoProgressError, ex);
}
}
public void NewData(short[][] data, ulong samplenumber, ulong timeStamp, ulong sequenceNumber)
{
try
{
var progressData = new ServiceCallbackData();
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
progressData.ProgressValue = 0;
progressData.UserData = UserData;
progressData.AddSampleData(data, samplenumber, timeStamp, sequenceNumber);
Callback(progressData);
}
catch (Exception ex)
{
APILogger.Log("MessageBox", Strings.RibeyeAsyncInfoNewDataError, ex);
}
}
public void Success()
{
try
{
var success = new ServiceCallbackData();
success.Status = ServiceCallbackData.CallbackStatus.Success;
success.UserData = UserData;
Callback(success);
}
catch (Exception ex)
{
APILogger.Log("MessageBox", Strings.RibeyeAsyncInfoSuccessError, ex);
}
}
public void Cancel()
{
try
{
var cancelReport = new ServiceCallbackData();
cancelReport.Status = ServiceCallbackData.CallbackStatus.Canceled;
cancelReport.ProgressValue = 0;
cancelReport.UserData = UserData;
Callback(cancelReport);
}
catch (Exception ex)
{
APILogger.Log("MessageBox", Strings.RibeyeAsyncInfoCancelError, ex);
}
}
}
private void LaunchAsyncWorker(string Invoker, WaitCallback cb, object asyncInfo)
{
if (!Connected)
{
// "{0}: Not currently connected"
throw new NotConnectedException(string.Format(Strings.Slice_LaunchAsyncWorker_Err1, Invoker));
}
if (!ThreadPool.QueueUserWorkItem(cb, asyncInfo))
{
// "{0}: Unable to enqueue function"
throw new Exception(string.Format(Strings.Slice_LaunchAsyncWorker_Err2, Invoker));
}
}
#endregion
void IDiagnosticsActions.SquibFireCheckArm(double delay, double duration, ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.SquibFireCheckArm", new WaitCallback(AsyncSquibFireCheckArm), info);
}
///
/// the working guts of PrepareForDiagnostics
///
/// our async data
private void AsyncSquibFireCheckArm(object asyncInfo)
{
var packet = (RibeyeServiceAsyncInfo)asyncInfo;
packet.Success();
}
void IDiagnosticsActions.TriggerCheckTrigger(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.TriggerCheckTrigger", new WaitCallback(AsyncTriggerCheckTrigger), info);
}
///
/// the working guts of PrepareForDiagnostics
///
/// our async data
private void AsyncTriggerCheckTrigger(object asyncInfo)
{
var packet = asyncInfo as RibeyeServiceAsyncInfo;
packet.Success();
}
void IDiagnosticsActions.TriggerCheckDownload(double delay, double duration, float dummyAAFilterFrequencyHz, uint dummySampleRateHz, ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.TriggerCheckDownload", new WaitCallback(AsyncTriggerCheckDownload), info);
}
///
/// the working guts of PrepareForDiagnostics
///
/// our async data
private void AsyncTriggerCheckDownload(object asyncInfo)
{
var packet = asyncInfo as RibeyeServiceAsyncInfo;
packet.Success();
}
public void CorrectT0s(ServiceCallback callback, object userData)
{
var info = new RibeyeServiceAsyncInfo(callback, userData);
LaunchAsyncWorker("Ribeye.CorrectT0s", new WaitCallback(AsyncCorrectT0s), info);
}
private void AsyncCorrectT0s(object asyncInfo)
{
var packet = asyncInfo as RibeyeServiceAsyncInfo;
packet.Error("Not supported");
return;
}
}
///
/// EthernetRibeye is a empty wrapper for a Ribeye connected over ethernet
///
public class EthernetRibeye : Ribeye
{
}
}