2219 lines
96 KiB
C#
2219 lines
96 KiB
C#
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.Sensors;
|
|
using DTS.Common.Interface.Communication;
|
|
using DTS.Common.Interface.Connection;
|
|
using DTS.Common.Enums.DASFactory;
|
|
using DTS.Common.Interface.StatusAndProgressBar;
|
|
using DTS.Common.Enums;
|
|
using DTS.DASLib.Service.Interfaces;
|
|
using DTS.Common;
|
|
using DTS.Common.ICommunication;
|
|
using DTS.DASLib.Command;
|
|
using TiltMIF;
|
|
using DTS.DASLib.Command.SLICE.DownloadCommands;
|
|
using DTS.Common.Constant.DASSpecific;
|
|
using DTS.Common.Enums.Hardware;
|
|
using DTS.Common.Classes.DASFactory;
|
|
using DTS.Common.Interface.DASFactory.Download;
|
|
|
|
namespace DTS.DASLib.Service
|
|
{
|
|
public class SLICE6DB<T> : SLICE2_Base<T>,
|
|
IConfigurationActions,
|
|
IDiagnosticsActions,
|
|
ITriggerCheckActions,
|
|
IRealTimeActions,
|
|
IArmActions,
|
|
IDownloadActions,
|
|
IClockSyncActions
|
|
where T : IConnection,
|
|
new()
|
|
{
|
|
protected override uint[] GetExtendedFaultFlags(int eventIndex)
|
|
{
|
|
try
|
|
{
|
|
var qee = new QueryArmAttribute(this) { Key = AttributeTypes.ArmAndEventAttributes.ExtFaultFlags };
|
|
qee.SyncExecute();
|
|
return (uint[])qee.Value;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
}
|
|
return new uint[] { 0, 0, 0, 0 };
|
|
}
|
|
protected override void SetArmAttribute(AttributeTypes.ArmAndEventAttributes key, DFConstantsAndEnums.RecordingMode value)
|
|
{
|
|
var mode = value;
|
|
switch (mode)
|
|
{
|
|
case DFConstantsAndEnums.RecordingMode.MultipleEventRAMActive:
|
|
mode = DFConstantsAndEnums.RecordingMode.AutoCircularBufferMode;
|
|
break;
|
|
case DFConstantsAndEnums.RecordingMode.RAMActive:
|
|
mode = DFConstantsAndEnums.RecordingMode.CircularBuffer;
|
|
break;
|
|
}
|
|
|
|
base.SetArmAttribute(key, mode);
|
|
}
|
|
/// <summary>
|
|
/// whether RTC battery (Yuba) is present
|
|
/// </summary>
|
|
public bool RTCBatteryPresent { get; set; } = false;
|
|
/// <summary>
|
|
/// the serial number of the RTC battery if present
|
|
/// </summary>
|
|
public uint? RTCSerialNumber { get; set; } = null;
|
|
/// <summary>
|
|
/// the RTC production date if present and set
|
|
/// </summary>
|
|
public DateTime? RTCProductionDate { get; set; } = null;
|
|
/// <summary>
|
|
/// the RTC battery install date if present and set
|
|
/// </summary>
|
|
public DateTime? RTCBatteryInstallationDate { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// returns true if device supports start inversion, false otherwise
|
|
/// <inheritdoc cref="IDASCommunication"/>
|
|
/// </summary>
|
|
/// <returns>true if unit supports start inversion, false otherwise</returns>
|
|
public override bool SupportsStartInversion() => HardwareConstants.SupportsStartInversion(GetHardwareType(), ProtocolVersion);
|
|
/// <summary>
|
|
/// returns true if device supports trigger inversion, false otherwise
|
|
/// <inheritdoc cref="IDASCommunication"/>
|
|
/// </summary>
|
|
/// <returns>true if unit supports trigger inversion, false otherwise</returns>
|
|
public override bool SupportsTriggerInversion() => HardwareConstants.SupportsTriggerInversion(GetHardwareType(), ProtocolVersion);
|
|
|
|
|
|
public override bool? ChargingEnabled
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// populates the connected devices field
|
|
/// </summary>
|
|
public override void QueryConnectedDevices()
|
|
{
|
|
List<IDASConnectedDevice> connectedDevices = new List<IDASConnectedDevice>();
|
|
if (!RunTestVariables.InRunTest || RunTestVariables.QueryConnectedDevicesInRunTest)
|
|
{
|
|
if (!IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.QueryEthernetMacTable)) { }
|
|
else
|
|
{
|
|
var cmd = new QueryEthernetMacIpTable(this);
|
|
cmd.UpdateBuffer = false;
|
|
cmd.SyncExecute();
|
|
var ips = new List<string>();
|
|
foreach (var entry in cmd.MacIpTable)
|
|
{
|
|
string address = Encoding.UTF8.GetString(entry.Mac, 0, 18);
|
|
address = address.Replace("\0", " ").Split(' ')[0];
|
|
string ip = Encoding.UTF8.GetString(entry.Ip, 0, 16);
|
|
ip = ip.Replace("\0", " ").Split(' ')[0];
|
|
string sn = Encoding.UTF8.GetString(entry.Sn, 0, 10);
|
|
sn = sn.Replace("\0", " ").Split(' ')[0];
|
|
string location = Encoding.UTF8.GetString(entry.Location, 0, 10);
|
|
location = location.Replace("\0", " ").Split(' ')[0];
|
|
string version = Encoding.UTF8.GetString(entry.Version, 0, 5);
|
|
version = version.Replace("\0", " ").Split(' ')[0];
|
|
var s6 = new S6DBConnectedDevice(entry.Port, entry.Down, new PhysicalAddress(entry.Mac), ip, sn, location, version);
|
|
connectedDevices.Add(s6);
|
|
ips.Add(ip);
|
|
}
|
|
APILogger.Log($"{SerialNumber} has attached {string.Join(", ", ips.ToArray())}");
|
|
}
|
|
}
|
|
((ICommunication)this).DASInfo.SetConnectedDevices(connectedDevices.ToArray());
|
|
}
|
|
|
|
void IConfigurationActions.SetFirstUseDate(DateTime firstUseDate, ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Error("Not supported");
|
|
}
|
|
void ITriggerCheckActions.PreStartTriggerCheck(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
LaunchAsyncWorker("SliceDB.StartTriggerCheck", AsyncPreStartTriggerCheckSLICE6DB, info);
|
|
}
|
|
void ITriggerCheckActions.PostStartTriggerCheck(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
LaunchAsyncWorker("SliceDB.StartTriggerCheck", AsyncPostStartTriggerCheckSLICE6DB, info);
|
|
}
|
|
/// <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 true;
|
|
}
|
|
|
|
public override bool IsBattery()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public override bool IsTSRAIR()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public new bool IsSlice6Air()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public override bool IsScheduleEventCountSupported()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
private const int UNKNOWN_REVISION = -1; //unknown
|
|
private const int REVISION_WIAMAN1 = 0; //original WIAMan
|
|
private const int REVISION_WIAMAN2 = 2; //WIAMan RevB
|
|
private const int REVISION_AIR = 4; //SLICE 6 AIR DB
|
|
|
|
public enum S6DBModes
|
|
{
|
|
WIAMAN, //settings for WIAMAN implementation of S6DB
|
|
INDUMMY, //settings for THOR implementation of S6DB
|
|
AIR //settings for S6DB AIR
|
|
}
|
|
public S6DBModes S6DBMode { get; set; } = S6DBModes.INDUMMY;
|
|
|
|
/// <summary>
|
|
/// there is not a DAS, so no nominal ranges are returned
|
|
/// always throws an exception as there are no acceptable nominal ranges
|
|
/// </summary>
|
|
/// <param name="bridge"></param>
|
|
/// <returns></returns>
|
|
public override double[] GetNominalRanges(SensorConstants.BridgeType bridge) { throw new NotImplementedException(); }
|
|
|
|
/// <summary>
|
|
/// Distributors carry a single module with a single channel by old SLICEWare tradition
|
|
/// </summary>
|
|
public override int MaxModules
|
|
{
|
|
get => 1;
|
|
set {; }
|
|
}
|
|
/// <summary>
|
|
/// Distributors don't collect or filter data, so safe to say they don't introduce any phase shifts.
|
|
/// </summary>
|
|
/// <param name="ModuleIndex"></param>
|
|
/// <param name="ActualSampleRate"></param>
|
|
/// <param name="HardwareAAF"></param>
|
|
/// <returns></returns>
|
|
public override ulong GetPhaseShiftSamples(uint ModuleIndex, double ActualSampleRate, uint HardwareAAF, ulong originalT0) { return 0; }
|
|
|
|
/// <summary>
|
|
/// Distributor does not do flash erase, so returns success immediately
|
|
/// </summary>
|
|
/// <param name="callbck"></param>
|
|
/// <param name="userData"></param>
|
|
public void BeginBackgroundFlashErase(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
/// <summary>
|
|
/// Unit is not capable of flash erase or background flash erase
|
|
/// </summary>
|
|
public bool SupportsBackgroundFlashErase => false;
|
|
|
|
/// <summary>
|
|
/// returns whether unit has started background flash erase
|
|
/// </summary>
|
|
public bool BackgroundFlashEraseStarted => false;
|
|
|
|
/// <summary>
|
|
/// there's no background flash erase on Distributors
|
|
/// returns null
|
|
/// </summary>
|
|
public DateTime? BackgroundFlashEraseStartTime => null;
|
|
|
|
/// <summary>
|
|
/// there's no DAS display order currently for SLICE6 Distributors
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override int GetDASDisplayOrder() { return -1; }
|
|
/// <summary>
|
|
/// there's no channels for SLICE6 Distributors.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override int[] GetChannelDisplayOrder() { return new[] { -1 }; }
|
|
/// <summary>
|
|
/// can't set the DAS display order for SLICE6 distributors
|
|
/// throws not supported exception
|
|
/// </summary>
|
|
/// <param name="order"></param>
|
|
public override void SetDASDisplayOrder(int order) { throw new NotSupportedException("Not supported for Slice6DB"); }
|
|
/// <summary>
|
|
/// setting channel order is not supported on SLICE6 distributor,
|
|
/// throws not supported exception
|
|
/// </summary>
|
|
/// <param name="order"></param>
|
|
public override void SetChannelDisplayOrder(int[] order) { throw new NotSupportedException("Not supported for Slice6DB"); }
|
|
/// <summary>
|
|
/// does not have a diagnostic sample rate, so requirediagnosticsampleratematch isn't needed
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override bool RequireDiagnosticRateMatchSampleRate() { return false; }
|
|
/// <summary>
|
|
/// this might be useful for SLICE6 Db, but not known yet.
|
|
/// </summary>
|
|
public override DateTime SystemBaseTime => DateTime.MinValue;
|
|
/// <summary>
|
|
/// SLICE6 Distributor is not range limited by bandwidth
|
|
/// </summary>
|
|
public override bool RangeBandwidthLimited => false;
|
|
|
|
/// <summary>
|
|
/// readies unit for arming, currently nothing additional is done for SLICE6 DB
|
|
/// </summary>
|
|
/// <param name="callback"></param>
|
|
/// <param name="userData"></param>
|
|
/// <param name="eventGuid"></param>
|
|
/// <param name="armNowTimeout"></param>
|
|
/// <param name="testingMode"></param>
|
|
/// <param name="maxNumberEvents"></param>
|
|
/// <param name="DummyArm"></param>
|
|
/// <param name="SysMode"></param>
|
|
public void ReadyForArming(ServiceCallback callback, object userData, Guid eventGuid, int armNowTimeout, bool testingMode,
|
|
int maxNumberEvents, bool DummyArm, bool SysMode)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
|
|
info.Success();
|
|
}
|
|
public void CorrectT0s(ServiceCallback callback,
|
|
object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Error("Not supported");
|
|
return;
|
|
}
|
|
/// <summary>
|
|
/// SLICE6 doesn't store event info, so right now this just returns success right away, there's nothing to do
|
|
/// </summary>
|
|
/// <param name="eventIndex"></param>
|
|
/// <param name="id"></param>
|
|
/// <param name="guid"></param>
|
|
/// <param name="totalSamples"></param>
|
|
/// <param name="triggerSamples"></param>
|
|
/// <param name="startRecordSample"></param>
|
|
/// <param name="eventHasDownloaded"></param>
|
|
/// <param name="callback"></param>
|
|
/// <param name="userData"></param>
|
|
public void SetEventInfo(int eventIndex,
|
|
string id,
|
|
Guid guid,
|
|
ulong totalSamples,
|
|
ulong[] triggerSamples,
|
|
ulong startRecordSample,
|
|
UInt32 eventHasDownloaded,
|
|
ServiceCallback callback,
|
|
object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// SLICE6 DB doesn't store anything, so it's max memory is unlimited
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override long MaxMemory() { return long.MaxValue; }
|
|
/// <summary>
|
|
/// SLICE6 DB doesn't record anything, so it's max sample rate is unlimited
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override uint MaxSampleRate(int numberOfConfiguredChannels) { return uint.MaxValue; }
|
|
/// <summary>
|
|
/// SLICE6 doesn't record anything, so it's min sample rate is 0
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override uint MinSampleRate() { return uint.MinValue; }
|
|
|
|
public override uint MaxAAFilterRate()
|
|
{
|
|
return MaxAAFilterRateHz;
|
|
}
|
|
|
|
/// <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 SDBAsyncInfo
|
|
{
|
|
public ServiceCallback Callback { get; set; }
|
|
public object UserData { get; set; }
|
|
public object FunctionData { get; set; }
|
|
|
|
public SDBAsyncInfo(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", "SDB 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", "SDB 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", "SDB 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", "SDB ERROR", ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
void IConfigurationActions.CheckAAFilterRate(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SliceServiceAsyncInfo(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);
|
|
}
|
|
|
|
void IConfigurationActions.ResetHardwareLines(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SliceServiceAsyncInfo(callback, userData);
|
|
LaunchAsyncWorker("Slice6DB.ResetHardwareLines", AsyncResetHardwareLines, info);
|
|
}
|
|
|
|
protected virtual void AsyncResetHardwareLines(object asyncInfo)
|
|
{
|
|
if (!(asyncInfo is SliceServiceAsyncInfo info))
|
|
{
|
|
return;
|
|
}
|
|
if (!IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines))
|
|
{
|
|
info.Success();
|
|
return;
|
|
}
|
|
//performance improvement, don't set polarity when a system doesn't need to
|
|
//[reduce # of commands]
|
|
if (RunTestVariables.InRunTest && RunTestVariables.DontSetPolarityInRunTest)
|
|
{
|
|
//don't set
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
var ssaStart = new SetSystemAttribute(this);
|
|
var ssaTrigger = new SetSystemAttribute(this);
|
|
ssaStart.SetValue(AttributeTypes.SystemAttributes.StartRecordPolarity, (byte)(InvertStart ? 1 : 0),
|
|
true);
|
|
ssaTrigger.SetValue(AttributeTypes.SystemAttributes.TriggerPolarity, (byte)(InvertTrigger ? 1 : 0),
|
|
true);
|
|
ssaStart.SyncExecute();
|
|
ssaTrigger.SyncExecute();
|
|
|
|
var ssi = new SetSwitchImmediate(this)
|
|
{
|
|
DeviceID = 0x00,
|
|
Switch = (byte)Switches.BaseSwitches.TriggerOut,
|
|
SwitchText = Switches.BaseSwitches.TriggerOut.ToString(),
|
|
Setting = InvertTrigger ? Convert.ToByte(1) : Convert.ToByte(0)
|
|
};
|
|
ssi.SyncExecute();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
}
|
|
}
|
|
|
|
info.Success();
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// SLICE6 DB does not have a safety switch and is always in the right safety switch state, so
|
|
/// return sucess immediately
|
|
/// </summary>
|
|
/// <param name="bArmed"></param>
|
|
/// <param name="callback"></param>
|
|
/// <param name="userData"></param>
|
|
public void CheckSafetyState(bool bArmed, ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
/// <summary>
|
|
/// there is nothing to configure in SLICE6DB currently, so it just returns immediately
|
|
/// </summary>
|
|
/// <param name="callback"></param>
|
|
/// <param name="userData"></param>
|
|
/// <param name="EventConfig"></param>
|
|
/// <param name="DummyConfig"></param>
|
|
/// <param name="maxAAF"></param>
|
|
public void Configure(ServiceCallback callback, object userData, bool EventConfig, bool dummyConfig, double[] maxAAF, bool configureDigitalOutput, uint crc)
|
|
{
|
|
var info = new SliceConfigServiceAsyncInfo(callback, userData, EventConfig, crc, true)
|
|
{
|
|
DummyConfig = dummyConfig,
|
|
ConfigureDigitalOutput = configureDigitalOutput
|
|
};
|
|
|
|
LaunchAsyncWorker("Slice.Configure", AsyncConfigure, info);
|
|
}
|
|
|
|
void IConfigurationActions.ApplyLevelTriggers(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SliceServiceAsyncInfo(callback, userData);
|
|
LaunchAsyncWorker("Slice6DB.ApplyLevelTriggers", AsyncApplyLevelTriggers, info);
|
|
}
|
|
|
|
protected override void AsyncApplyLevelTriggers(object asyncInfo)
|
|
{
|
|
var info = (SliceServiceAsyncInfo)asyncInfo;
|
|
info.Success();
|
|
}
|
|
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();
|
|
|
|
var ssaV = new SetSystemAttributeSLICE6DB(this);
|
|
//input min, input max, battery min, battery max
|
|
var requirements = new[] { InputLowVoltage, InputHighVoltage, BatteryLowVoltage, BatteryHighVoltage };
|
|
ssaV.SetValue(AttributeTypes.SystemAttributesSLICE6DB.VoltageRequirements, requirements, true);
|
|
ssaV.SyncExecute();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log("failed to configure", SerialNumber, ex);
|
|
info.Error(ex.Message);
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
ConfigureHasBeenRun = true;
|
|
if (info.DiscardDiagnostics) { DiagnosticsHasBeenRun = false; }
|
|
info.Progress(100);
|
|
info.Success();
|
|
}
|
|
/// <summary>
|
|
/// retrieves information on Yuba/RTC and populates properties
|
|
/// </summary>
|
|
private void GetYubaInfo()
|
|
{
|
|
try
|
|
{
|
|
var rtcRamGet = new TiltSensorGet(this)
|
|
{
|
|
Tilt_id = 0xFF,
|
|
Sub_cmd = TiltSensorMif.RtcRam,
|
|
Data_Offset = 0,
|
|
Data_Length = 6
|
|
};
|
|
rtcRamGet.SyncExecute();
|
|
var inputData = rtcRamGet.Data;
|
|
if (null == inputData)
|
|
{
|
|
//no error, so Yuba present, however the bytes are null, so the battery lost power ...
|
|
RTCBatteryPresent = true;
|
|
RTCProductionDate = null;
|
|
RTCSerialNumber = null;
|
|
RTCBatteryInstallationDate = null;
|
|
return;
|
|
}
|
|
RTCSerialNumber = rtcRamGet.RTCSerialNumber;
|
|
if (0 < rtcRamGet.RTCProductionDaysSince1970)
|
|
{
|
|
RTCProductionDate = (new DateTime(1970, 1, 1)).AddDays(rtcRamGet.RTCProductionDaysSince1970);
|
|
}
|
|
else
|
|
{
|
|
//yuba present, but attribute has a value of 0, which is invalid
|
|
RTCProductionDate = null;
|
|
}
|
|
if (0 < rtcRamGet.RTCBatteryInstallationDaysSince1970)
|
|
{
|
|
RTCBatteryInstallationDate = (new DateTime(1970, 1, 1)).AddDays(rtcRamGet.RTCBatteryInstallationDaysSince1970);
|
|
}
|
|
else
|
|
{
|
|
//yuba present, but attribute has a value of 0, which is invalid
|
|
RTCBatteryInstallationDate = null;
|
|
}
|
|
RTCBatteryPresent = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//Yuba not present
|
|
RTCBatteryPresent = false;
|
|
RTCProductionDate = null;
|
|
RTCSerialNumber = null;
|
|
RTCBatteryInstallationDate = null;
|
|
APILogger.Log("failed to retrieve RTC information", ex);
|
|
}
|
|
}
|
|
protected override void AsyncQueryConfiguration(object configAsyncInfo)
|
|
{
|
|
if (RunTestVariables.InRunTest && RunTestVariables.Assumed_S6DB_ProtocolVersion > 0)
|
|
{
|
|
S6DBMode = S6DBModes.WIAMAN;
|
|
}
|
|
else
|
|
{
|
|
//26821 Add query of BaseFirmwareBuildID for SLICE PRO/ 1.5/ S6/S6A/PowerPRO/S6DB/S6DB3/ TSR AIR for Logs
|
|
QueryBaseFirmwareBuildId();
|
|
switch (QueryHardwareRevision())
|
|
{
|
|
case REVISION_WIAMAN1:
|
|
case REVISION_WIAMAN2:
|
|
S6DBMode = S6DBModes.WIAMAN;
|
|
break;
|
|
case REVISION_AIR:
|
|
S6DBMode = S6DBModes.AIR;
|
|
break;
|
|
default: //includes THOR types and fallback to unknown
|
|
S6DBMode = S6DBModes.INDUMMY;
|
|
break;
|
|
}
|
|
}
|
|
|
|
GetYubaInfo();
|
|
|
|
// get attached tilt sensor I2C ids
|
|
var activeTilts = new List<Common.Classes.Hardware.ExternalTilt>();
|
|
try
|
|
{
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.QueryExternalTiltInfo))
|
|
{
|
|
List<byte> tiltIds = new List<byte>();
|
|
ushort numTilt;
|
|
byte[] tiltAddr;
|
|
var tiltSensorGet = new TiltSensorGet(this)
|
|
{
|
|
Sub_cmd = TiltSensorMif.TiltSenosrList
|
|
};
|
|
tiltSensorGet.SyncExecute();
|
|
numTilt = tiltSensorGet.NumberOfTilt;
|
|
tiltAddr = tiltSensorGet.Tilt_Address;
|
|
for (int i = 0; i < numTilt; i++)
|
|
{
|
|
tiltIds.Add(tiltAddr[i]);
|
|
}
|
|
foreach (var tID in tiltIds)
|
|
{
|
|
tiltSensorGet = new TiltSensorGet(this, 600000)
|
|
{
|
|
Tilt_id = tID,
|
|
Sub_cmd = TiltSensorMif.TiltSensorEEPROM,
|
|
Data_Offset = 0,
|
|
Data_Length = 256
|
|
};
|
|
tiltSensorGet.SyncExecute();
|
|
var tiltMif = new Tilt_MIF(tiltSensorGet.Data);
|
|
if (tiltMif.ArmChecklist)
|
|
{
|
|
activeTilts.Add(new Common.Classes.Hardware.ExternalTilt()
|
|
{
|
|
SerialNumber = tiltMif.SerialNumber,
|
|
TiltID = tID,
|
|
SystemLocation = tiltMif.Location,
|
|
SystemID = tiltMif.SystemID,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex) { APILogger.Log(ex); }
|
|
|
|
DASInfo.ActiveExternalTilts = activeTilts;
|
|
|
|
base.AsyncQueryConfiguration(configAsyncInfo);
|
|
}
|
|
/// <summary>
|
|
/// Retrieve configuration from DAS and store it in the ConfigData property
|
|
/// SLICE6 DB doesn't have a configuration or storage, so it returns immediately
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
public void QueryConfiguration(ServiceCallback callback, object userData)
|
|
{
|
|
if (RunTestVariables.InRunTest && RunTestVariables.Assumed_S6DB_ProtocolVersion > 0)
|
|
{
|
|
S6DBMode = S6DBModes.WIAMAN;
|
|
}
|
|
else
|
|
{
|
|
|
|
switch (QueryHardwareRevision())
|
|
{
|
|
case REVISION_WIAMAN1:
|
|
case REVISION_WIAMAN2:
|
|
S6DBMode = S6DBModes.WIAMAN;
|
|
break;
|
|
case REVISION_AIR:
|
|
S6DBMode = S6DBModes.AIR;
|
|
break;
|
|
default: //includes THOR types and fallback to unknown
|
|
S6DBMode = S6DBModes.INDUMMY;
|
|
break;
|
|
}
|
|
}
|
|
GetYubaInfo();
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
ConfigData = new ConfigurationData { Modules = new DASModule[] { new DASModule(0, this) } };
|
|
ConfigData.Modules[0].Channels = new DASChannel[] { new AnalogInputDASChannel((DASModule)ConfigData.Modules[0], 0) };
|
|
ConfigData.IDs = new EID[0];
|
|
ConfigData.TestID = "";
|
|
ConfigData.Description = "";
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve hardware revision from DAS
|
|
/// </summary>
|
|
protected new int QueryHardwareRevision()
|
|
{
|
|
if (!IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision)) { return UNKNOWN_REVISION; }
|
|
else
|
|
{
|
|
try
|
|
{
|
|
var qsa = new QuerySystemAttributeSLICE6DB(this);
|
|
qsa.Key = AttributeTypes.SystemAttributesSLICE6DB.BaseHardwareRevision;
|
|
qsa.SyncExecute();
|
|
return Convert.ToInt32(qsa.Value);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log("failed to get hardware revision", ex);
|
|
}
|
|
return UNKNOWN_REVISION;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve the EID's and store it in the ConfigData property
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
public void UpdateIDs(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// not sure the purpose of this function, but there are no ids on a distributor, so return immediately
|
|
/// </summary>
|
|
/// <param name="callback"></param>
|
|
/// <param name="userData"></param>
|
|
/// <param name="module"></param>
|
|
/// <param name="channel"></param>
|
|
public void UpdateId(ServiceCallback callback, object userData, DASModule module, DASChannel channel)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// If any of the units to run diagnostics are in
|
|
/// <see cref="DTS.DASLib.Service.ArmingService">
|
|
/// DTS.DASLib.Service.ArmingService.EnterLowPowerMode</see> then the analog circuits must be "warmed up" before accurate
|
|
/// diagnostics can be performed. If the units have not been placed into
|
|
/// <see cref="DTS.DASLib.Service.ArmingService">DTS.DASLib.Service.ArmingService.EnterLowPowerMode</see> then there is no need to call
|
|
/// this but since it is quite important habitually calling it everytime
|
|
/// diagnostics are performed would be beneficial.
|
|
/// </summary>
|
|
/// <param name="DiagnosticsSampleRateHz">The firmware will use this sample rate when
|
|
/// collecting diagnostics data from the channel.</param>
|
|
/// <param name="DiagnosticsAAFilterFrequencyHz">The firmware will use this Anti-Aliasing
|
|
/// filter when collectin diagnostics data from the channel.</param>
|
|
/// <param name="callback">The function to call with information.</param>
|
|
/// <param name="userData">Whatever you want to pass along.</param>
|
|
public void PrepareForBridgeResistanceMeasurement(UInt32 DiagnosticsSampleRateHz,
|
|
float DiagnosticsAAFilterFrequencyHz,
|
|
ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
public void GetBridgeMeasurement(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
void IDiagnosticsActions.MeasureTransferSpeed(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
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="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
public void PrepareForDiagnostics(UInt32 DiagnosticsSampleRateHz,
|
|
float DiagnosticsAAFilterFrequencyHz,
|
|
PrePostResults WhichResult,
|
|
ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
public void PerformArmChecks(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
LaunchAsyncWorker("Slice6DB.PerformArmChecks", new WaitCallback(AsyncPerformArmChecks), info);
|
|
}
|
|
|
|
protected virtual bool SupportsTemperatureCheck => true;
|
|
protected virtual bool SupportsTiltCheck => true;
|
|
protected virtual bool SupportsClockSyncCheck => true;
|
|
private void AsyncPerformArmChecks(object o)
|
|
{
|
|
var info = o as SDBAsyncInfo;
|
|
var dasResults = new ArmCheckResults();
|
|
info.Progress(25);
|
|
if (null != ArmCheckActions)
|
|
{
|
|
GetBaseInputs();
|
|
if (ArmCheckActions.PerformBatteryVoltageCheck)
|
|
{
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics))
|
|
{
|
|
if (dasResults.BatteryVoltage != null)
|
|
{
|
|
if (dasResults.BatteryVoltage != null)
|
|
{
|
|
try
|
|
{
|
|
dasResults.BatteryVoltage[0] = BaseInput.BatteryMilliVolts / 1000D;
|
|
}
|
|
catch (Exception ex) { APILogger.Log("Failed to get Battery voltage", ex); }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
info.Progress(50);
|
|
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); }
|
|
}
|
|
}
|
|
if (ArmCheckActions.PerformSquibResistanceCheck)
|
|
{
|
|
// No Squibs in SDB or ECM
|
|
}
|
|
if (ArmCheckActions.PerformEventLineCheck)
|
|
{
|
|
((ITriggerCheckActions)this).DoTriggerCheckSync();
|
|
}
|
|
if (ArmCheckActions.PerformSensorIdCheck)
|
|
{
|
|
//not needed
|
|
}
|
|
if (ArmCheckActions.PerformTemperatureCheck && SupportsTemperatureCheck)
|
|
{
|
|
// Temperature
|
|
var keys = Enum.GetValues(typeof(DFConstantsAndEnums.TempLogChannelBits)).Cast<DFConstantsAndEnums.TempLogChannelBits>().ToArray();
|
|
dasResults.TemperaturesPre = new float[keys.Length];
|
|
for (var i = 0; i < keys.Length; i++)
|
|
{
|
|
dasResults.TemperaturesPre[i] = float.NaN;
|
|
}
|
|
|
|
var qsa = new QuerySystemAttributeSLICE6DB(this) { Key = AttributeTypes.SystemAttributesSLICE6DB.S6DBbaseEnvTempLoggingConfig, };
|
|
qsa.SyncExecute();
|
|
|
|
|
|
if (qsa.Value is ushort[] config)
|
|
{
|
|
var tempConfig = new TemperatureConfig(config);
|
|
var s6DBDiagChannels = tempConfig.GetMeasurementChannels();
|
|
foreach (var diagChan in s6DBDiagChannels)
|
|
{
|
|
var measure = new MeasureS6DBDiagnosticChannel(this);
|
|
measure.Channel = diagChan;
|
|
measure.SyncExecute();
|
|
dasResults.TemperaturesPre[(int)tempConfig.GetChannelBitForDiagChannel(diagChan)] = measure.Measurement;
|
|
}
|
|
}
|
|
}
|
|
if (ArmCheckActions.PerformClockSyncCheck &&
|
|
IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.PTPSyncStatus) &&
|
|
SupportsClockSyncCheck)
|
|
{
|
|
//SLICE 6, S6DB, etc.
|
|
var query = new Ptp1588GetSyncStatus(this);
|
|
try
|
|
{
|
|
query.SyncExecute();
|
|
var syncStatus = new Dictionary<DTS.Common.InputClockSource, bool>();
|
|
List<DTS.Common.InputClockSource> sources =
|
|
Enum.GetValues(typeof(DTS.Common.InputClockSource)).Cast<DTS.Common.InputClockSource>().ToList();
|
|
|
|
for (int i = 1; i < sources.Count; i++)
|
|
{
|
|
// init all sources not synced
|
|
syncStatus.Add(sources[i], false);
|
|
}
|
|
syncStatus[DTS.Common.InputClockSource.PTP] = (Ptp1588Commands.PtpSyncStatus.Synced == query.SyncStatus);
|
|
dasResults.InputClockLocks = syncStatus;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
info.Error(ex.Message, ex);
|
|
}
|
|
}
|
|
if (ArmCheckActions.PerformTiltSensorCheck && SupportsTiltCheck)
|
|
{
|
|
GetTiltResults(dasResults);
|
|
}
|
|
}
|
|
info.Progress(100);
|
|
dasResults.SensorIds = null;
|
|
dasResults.SquibResistances = null;
|
|
ArmCheckResults = dasResults;
|
|
info.Success();
|
|
}
|
|
|
|
public void SaveTiltSensorDataPre(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
LaunchAsyncWorker("SliceDB.SaveTiltSensorData", AsyncSaveTiltSensorDataPre, info);
|
|
}
|
|
|
|
private void AsyncSaveTiltSensorDataPre(object o)
|
|
{
|
|
if (!(o is SDBAsyncInfo info)) { return; }
|
|
|
|
if (DASInfo.ActiveExternalTilts.Count > 0)
|
|
{
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.QueryTiltSensorData) && SupportsTiltCheck)
|
|
{
|
|
try
|
|
{
|
|
// Get Tilt Cals
|
|
TiltSensorGet tiltSensorGet;
|
|
foreach (var tiltInfo in DASInfo.ActiveExternalTilts)
|
|
{
|
|
tiltSensorGet = new TiltSensorGet(this, 600000)
|
|
{
|
|
Tilt_id = tiltInfo.TiltID,
|
|
Sub_cmd = TiltSensorMif.TiltSensorEEPROM,
|
|
Data_Offset = 0,
|
|
Data_Length = 256
|
|
};
|
|
tiltSensorGet.SyncExecute();
|
|
var curMif = new Tilt_MIF(tiltSensorGet.Data);
|
|
|
|
|
|
curMif.PreEventADCAxis1 = ArmCheckResults.IndexedTiltSensorDataPre[tiltInfo.TiltID][0];
|
|
curMif.PreEventADCAxis2 = ArmCheckResults.IndexedTiltSensorDataPre[tiltInfo.TiltID][1];
|
|
curMif.PreEventADCAxis3 = ArmCheckResults.IndexedTiltSensorDataPre[tiltInfo.TiltID][2];
|
|
|
|
var tiltSensorSet = new TiltSensorSet(this, 600000);
|
|
var payload = curMif.GetBytes();
|
|
tiltSensorSet.SetEEPROM(tiltInfo.TiltID, 0, payload);
|
|
tiltSensorSet.SyncExecute();
|
|
}
|
|
|
|
}
|
|
catch (CanceledException)
|
|
{
|
|
info.Cancel();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
info.Error(ex.Message, ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
info.Success();
|
|
}
|
|
|
|
public void SaveTemperaturesPre(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
LaunchAsyncWorker("SliceDB.SaveTiltSensorData", AsyncSaveTemperaturesPre, info);
|
|
}
|
|
|
|
private void AsyncSaveTemperaturesPre(object asyncInfo)
|
|
{
|
|
var info = asyncInfo as SDBAsyncInfo;
|
|
Debug.Assert(info != null, "info != null");
|
|
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InSliceTemperatureCPre)
|
|
&& SupportsTemperatureCheck)
|
|
{
|
|
var setTS = new SetArmAttribute(this);
|
|
setTS.SetValue(AttributeTypes.ArmAndEventAttributes.preEventTempHumidity1234, ArmCheckResults.TemperaturesPre, true);
|
|
setTS.SyncExecute();
|
|
}
|
|
|
|
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 SDBAsyncInfo(callback, userData);
|
|
DiagnosticsHasBeenRun = true;
|
|
BaseInput = new BaseInputValues();
|
|
GetBaseInputs();
|
|
ClearChannelDiagnosticsResults(false);
|
|
info.Success();
|
|
}
|
|
|
|
private class EventDiagnosticsAsyncPacket
|
|
{
|
|
public SliceServiceAsyncInfo 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 SliceServiceAsyncInfo(callback, userData);
|
|
packet.EventNumber = EventNumber;
|
|
packet.WhichResult = WhichResult;
|
|
|
|
LaunchAsyncWorker("Slice6DB.GetEventDiagnosticsResults", new WaitCallback(AsyncGetEventDiagnosticsResults), packet);
|
|
}
|
|
private void AsyncGetEventDiagnosticsResults(object asyncInfo)
|
|
{
|
|
var packet = (EventDiagnosticsAsyncPacket)asyncInfo;
|
|
|
|
ModuleDiagnosticsResult[] resultArray = null;
|
|
|
|
#region Temperature
|
|
var temperatureDataPre = new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN };
|
|
var temperatureDataPost = new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN };
|
|
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InSliceTemperatureCPre) && SupportsTemperatureCheck)
|
|
{
|
|
//Get the saved values from the Arm Checklist query (if any)
|
|
try
|
|
{
|
|
var query = new QueryArmAttribute(this)
|
|
{
|
|
Key = AttributeTypes.ArmAndEventAttributes.preEventTempHumidity1234
|
|
};
|
|
query.SyncExecute();
|
|
temperatureDataPre = query.Value as float[];
|
|
}
|
|
catch (Exception ex) { APILogger.Log(ex); }
|
|
}
|
|
resultArray = new ModuleDiagnosticsResult[1] { new ModuleDiagnosticsResult() };
|
|
resultArray[0].TemperatureLocation1Pre = temperatureDataPre[0];
|
|
resultArray[0].TemperatureLocation2Pre = temperatureDataPre[1];
|
|
resultArray[0].TemperatureLocation3Pre = temperatureDataPre[2];
|
|
resultArray[0].TemperatureLocation4Pre = temperatureDataPre[3];
|
|
//temperatureDataPre[4-7] can contain humidity readings in the future
|
|
resultArray[0].TemperatureLocation1Post = temperatureDataPost[0];
|
|
resultArray[0].TemperatureLocation2Post = temperatureDataPost[1];
|
|
resultArray[0].TemperatureLocation3Post = temperatureDataPost[2];
|
|
resultArray[0].TemperatureLocation4Post = temperatureDataPost[3];
|
|
//temperatureDataPost[4-7] can contain humidity readings in the future
|
|
#endregion
|
|
|
|
ModuleDiagnosticsResults = resultArray;
|
|
|
|
packet.Info.Success();
|
|
}
|
|
public void SquibFireCheckArm(double delay, double duration, ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
public void TriggerCheckTrigger(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
public void TriggerCheckDownload(double delay, double duration, float dummyAAFilterFrequencyHz, uint dummySampleRateHz, ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
/// <summary>
|
|
/// This flag is used to tell if arm attributes should be defaulted when arming
|
|
/// or not. It also serves to let the user know that this DAS has not been
|
|
/// diagnosed.
|
|
/// </summary>
|
|
public override bool DiagnosticsHasBeenRun
|
|
{
|
|
get => true;
|
|
set {; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// this flag is used to tell if configure has been run
|
|
/// this is used prior to when diagnostic results are needed, like the
|
|
/// diagnostics tab or the acquire tab [when running acquire]
|
|
/// </summary>
|
|
public override bool ConfigureHasBeenRun
|
|
{
|
|
get => true;
|
|
set {; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count how many channels are configured.
|
|
/// </summary>
|
|
/// <returns>Number of configured channels.</returns>
|
|
public override int NumberOfConfiguredChannels() { return 0; }
|
|
|
|
/// <summary>
|
|
/// Count how many channels we have (regardless if they are configured or not).
|
|
/// </summary>
|
|
/// <returns>Total number of channels</returns>
|
|
public override int NumberOfChannels() { return 0; }
|
|
|
|
public override bool SupportsAutoArm() { return true; }
|
|
public override bool SupportsLevelTrigger() { return false; }
|
|
|
|
public override bool SupportsMultipleEvents() { return true; }
|
|
|
|
public override bool SupportsRealtime() { return false; }
|
|
|
|
/// <summary>
|
|
/// whether the DASbase actually controls the DAQ for modules
|
|
/// in the case of TDAS, the modules actually are responsible for the DAQ and the
|
|
/// rack is just a middleman
|
|
/// this is relevant because if the DAQ is controlled by the base then the sample numbers
|
|
/// should match for all modules.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override bool ControlsDAQ() { return false; }
|
|
|
|
/// <summary>
|
|
/// tell DAS to start sending data at specific rate
|
|
/// </summary>
|
|
/// <param name="samplesPerSec">How many samples per second to receive</param>
|
|
/// <param name="msBetweenSamples">the amount of time to sleep between samples
|
|
/// 0 is ok</param>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
/// <param name="channels">
|
|
/// channels to operate on, added for
|
|
/// 10572 implement SW side for single command streaming realtime
|
|
/// </param>
|
|
void IRealTimeActions.RealTime(int samplesPerSec,
|
|
int msBetweenSamples,
|
|
ServiceCallback callback,
|
|
object userData,
|
|
bool allowMultipleSampleRealtime,
|
|
int moduleIndex,
|
|
ManualResetEvent stopEvent,
|
|
byte[] channels,
|
|
double aaf,
|
|
int minCallbackUpdateTimeMs,
|
|
bool UseUDPStreaming,
|
|
string hostIPAddress)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
void IRealTimeActions.RealTimePolling(ServiceCallback callback,
|
|
object userData,
|
|
ManualResetEvent mre,
|
|
byte[] channels)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stop sending real time data
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
void IRealTimeActions.ExitRealTimeMode(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
void IRealTimeActions.RealTimeTiltPolling(ServiceCallback callback, object userData, ManualResetEvent stopEvent)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Start an asynchronous flash erase on a single DAS.
|
|
/// </summary>
|
|
/// <param name="callback"></param>
|
|
/// <param name="userData"></param>
|
|
public void BeginFlashErase(ServiceCallback callback, object userData, bool DummyArm)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query a single DAS for flash erase progress and an errors that have occurred.
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with update information</param>
|
|
/// <param name="userData"></param>
|
|
public void QueryFlashEraseStatus(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
/// <summary>
|
|
/// Arm a single DAS now
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
/// <param name="eventGuid">A unique GUID that this event will be tagged
|
|
/// with</param>
|
|
public void ArmNow(ServiceCallback callback, object userData, Guid eventGuid, int
|
|
armNowTimeout, bool testingMode,
|
|
int maxNumberEvents, bool SysMode)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
|
|
if (null != ConfigData && ConfigData.Modules.Any())
|
|
{
|
|
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 ||
|
|
ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.a16_CircularBufferAndStreamSubSampleMode ||
|
|
ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.RAMActive ||
|
|
ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.MultipleEventRAMActive)
|
|
{
|
|
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 ex)
|
|
{
|
|
info.Error(ex.Message, ex);
|
|
return;
|
|
}
|
|
|
|
info.Success();
|
|
}
|
|
|
|
public void PrepareForArmNow(ServiceCallback callback, object userData, Guid eventGuid, int
|
|
armNowTimeout, bool testingMode,
|
|
int maxNumberEvents, bool SysMode)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
void IArmActions.ReArm(ServiceCallback callback, object userData, bool autoArm, bool arm, bool repeatEnable)
|
|
{
|
|
var info = new SDBAsyncInfo(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 SDBAsyncInfo(callback, userData);
|
|
|
|
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 ||
|
|
ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.a16_CircularBufferAndStreamSubSampleMode ||
|
|
ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.RAMActive ||
|
|
ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.MultipleEventRAMActive)
|
|
{
|
|
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
|
|
{
|
|
SetRTCBaseTime();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
}
|
|
try
|
|
{
|
|
var arm = new Arm(this);
|
|
arm.SyncExecute();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
info.Error(ex.Message, ex);
|
|
return;
|
|
}
|
|
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Arm multiple chained DAS now
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
public void EnableFaultChecking(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
try
|
|
{
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.EnableFaultChecking)
|
|
&& DFConstantsAndEnums.AllowEnableFaultCheckingOnS6DB)
|
|
{
|
|
var efc = new EnableFaultChecking(this);
|
|
efc.SyncExecute();
|
|
}
|
|
info.Success();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log("failed to enable fault checking, ", ex);
|
|
info.Error(ex.Message);
|
|
}
|
|
}
|
|
|
|
public void CheckAlreadyLevelTriggered(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
LaunchAsyncWorker("SliceDB.CheckAlreadyLevelTriggered", AsyncCheckAlreadyLevelTriggered, info);
|
|
}
|
|
private void AsyncCheckAlreadyLevelTriggered(object asyncInfo)
|
|
{
|
|
var info = asyncInfo as SDBAsyncInfo;
|
|
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);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Disarm the DAS
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
public void Disarm(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Arm))
|
|
{
|
|
try
|
|
{
|
|
//14731 - Dont issue a Disarm to a S6DB that isn't armed
|
|
var quats = new QueryArmAndTriggerStatus(this);
|
|
quats.SyncExecute();
|
|
if (quats.IsArmed)
|
|
{
|
|
var disarm = new Disarm(this);
|
|
disarm.SyncExecute();
|
|
}
|
|
}
|
|
catch (Exception) { }
|
|
}
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// DisAutoArm the DAS
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
public void DisAutoArm(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Download the data specified in the WhatToDownload property
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
public void Download(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cancel the current operation
|
|
/// </summary>
|
|
public void Cancel()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clear the cancel flag
|
|
/// </summary>
|
|
public void ClearCancel()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve 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 IDownloadActions.QueryDownload(ServiceCallback callback, object userData, int eventIndex, TDASServiceSetupInfo setupInfo)
|
|
{
|
|
|
|
var info = new QueryDownloadAsyncInfo(callback, userData, eventIndex);
|
|
LaunchAsyncWorker("Slice.QueryDownload", new WaitCallback(AsyncQueryDownload), info);
|
|
|
|
}
|
|
|
|
protected override void AsyncQueryDownload(object asyncInfo)
|
|
{
|
|
var info = asyncInfo as QueryDownloadAsyncInfo;
|
|
|
|
// since we don't know exact how many XML attributes, modules or channels that's in the
|
|
// configuration, we guess on the high end.
|
|
// (44 per stored config + 4 + 3 per module + 3 per channel) * number of events
|
|
// equals 44 + 4 + 30 + 90 = 168 per event
|
|
const int StepsPerEvent = 168;
|
|
|
|
try
|
|
{
|
|
var EventCount = new QueryTotalEventCount(this);
|
|
EventCount.SyncExecute();
|
|
|
|
// 6 * modules + 44
|
|
var progress = new QueryDownloadProgress(info, StepsPerEvent * EventCount.Count, 1);
|
|
|
|
// we'll also freshen up the cached event GUIDs
|
|
// NOT IF WE ARE QUERYING A SPECIFIC GUID
|
|
var eventGuids = new Guid[EventCount.Count];
|
|
var faultFlags = new ushort[EventCount.Count];
|
|
var armAttempts = new byte[EventCount.Count];
|
|
var extendedFaultIds = new List<uint[]>();
|
|
|
|
var dlReport = new DownloadReport();
|
|
var eventIdx = 0;
|
|
if (0 > info.EventIndex)
|
|
{
|
|
dlReport.Events = new DownloadReport.EventInfo[1];
|
|
}
|
|
|
|
//S6DB only can handle 1 event ...
|
|
extendedFaultIds.Add(GetExtendedFaultFlags(0));
|
|
|
|
// the object to store it all in
|
|
var eventInfo = new DownloadReport.EventInfo();
|
|
eventInfo.TestID = DFConstantsAndEnums.MADEUPEVENT_TESTID;
|
|
eventInfo.Description = Constants.DUMMY_MOD_DESCRIP_S6DB;
|
|
|
|
// Make a list for new modules and create module for on board temp readings
|
|
var eventModules = new List<DASModule>() { CreateDummyModule() };
|
|
|
|
#region Slice6TiltSensor
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.QueryTiltSensorData)
|
|
&& DASInfo.ActiveExternalTilts.Count > 0)
|
|
{
|
|
// Get Tilt Cals
|
|
TiltSensorGet tiltSensorGet;
|
|
int modArrayIndex = 1;
|
|
foreach (var tiltInfo in DASInfo.ActiveExternalTilts)
|
|
{
|
|
tiltSensorGet = new TiltSensorGet(this, 600000)
|
|
{
|
|
Tilt_id = tiltInfo.TiltID,
|
|
Sub_cmd = TiltSensorMif.TiltSensorEEPROM,
|
|
Data_Offset = 0,
|
|
Data_Length = 256
|
|
};
|
|
tiltSensorGet.SyncExecute();
|
|
var curMif = new Tilt_MIF(tiltSensorGet.Data);
|
|
|
|
var tiltSensorDataPre = new short[] { curMif.PreEventADCAxis1, curMif.PreEventADCAxis2, curMif.PreEventADCAxis3 };
|
|
var mountOffsets = Test.Module.GetMountOffsetsOrTargetsFromAxisInfo(
|
|
new float[] { curMif.MountOffsetAxis1, curMif.MountOffsetAxis2, curMif.MountOffsetAxis3 },
|
|
curMif.AxisToIgnore);
|
|
var targetAxis = Test.Module.GetMountOffsetsOrTargetsFromAxisInfo(
|
|
new float[] { curMif.TargetAngleAxis1, curMif.TargetAngleAxis2, curMif.TargetAngleAxis3 },
|
|
curMif.AxisToIgnore);
|
|
var tiltAxes = Test.Module.GetTiltAxesFromAxisInfo(
|
|
new string[] { curMif.AxisLabel1.ToString(), curMif.AxisLabel2.ToString(), curMif.AxisLabel3.ToString() },
|
|
new bool[] { curMif.InvertAxis1, curMif.InvertAxis2, curMif.InvertAxis3 });
|
|
var tiltDataEU = Test.Module.GetTiltDegreesEU(
|
|
tiltSensorDataPre,
|
|
curMif.GetTiltCalibrations(),
|
|
tiltAxes,
|
|
curMif.AxisToIgnore,
|
|
mountOffsets
|
|
);
|
|
|
|
var module = CreateDummyModule();
|
|
module.ModuleArrayIndex = modArrayIndex++;
|
|
module.TiltSensorAxisXDegreesPre = tiltDataEU[0];
|
|
module.TiltSensorAxisYDegreesPre = tiltDataEU[1];
|
|
module.TiltSensorAxisZDegreesPre = tiltDataEU[2];
|
|
module.SystemID = curMif.SystemID;
|
|
module.SystemLocation = curMif.Location;
|
|
module.MountOffsetAxisOne = mountOffsets[0];
|
|
module.MountOffsetAxisTwo = mountOffsets[1];
|
|
module.TargetAxisOne = targetAxis[0];
|
|
module.TargetAxisTwo = targetAxis[1];
|
|
module.TargetAngleAxisX = curMif.TargetAngleAxis1;
|
|
module.TargetAngleAxisY = curMif.TargetAngleAxis2;
|
|
module.TargetAngleAxisZ = curMif.TargetAngleAxis3;
|
|
module.AxisIgnored = curMif.AxisToIgnore;
|
|
module.TiltAxes = tiltAxes;
|
|
module.TiltID = tiltInfo.TiltID;
|
|
module.TiltSerialNumber = curMif.SerialNumber;
|
|
eventModules.Add(module);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
progress.Step();
|
|
eventInfo.Modules = eventModules.ToArray();
|
|
|
|
if (0 > info.EventIndex)
|
|
{
|
|
// store it in the object
|
|
dlReport.Events[eventIdx] = eventInfo;
|
|
}
|
|
else { EventInfo.Events[eventIdx] = eventInfo; }
|
|
|
|
|
|
if (info.EventIndex >= 0)
|
|
{
|
|
//only download if we are downloading a specific event, if index <0 we aren't downloading
|
|
DownloadTemperatureCSV(info);
|
|
}
|
|
|
|
// now assigned the data to the public property
|
|
if (0 > info.EventIndex)
|
|
{
|
|
SetEventInfo(dlReport);
|
|
}
|
|
|
|
SetEventFaultFlags(faultFlags);
|
|
((IDownload)this)?.SetExtendedFaultFlags(extendedFaultIds.ToArray());
|
|
SetEventGuids(eventGuids);
|
|
SetEventArmAttemps(armAttempts);
|
|
info.Success();
|
|
}
|
|
catch (CanceledException)
|
|
{
|
|
info.Cancel();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
info.Error(ex.Message, ex);
|
|
}
|
|
}
|
|
//private const int TEMPERATURE_CONFIG_CHANNEL_FIELD = 2;
|
|
//private DFConstantsAndEnums.TempLogChannelBits GetFirstMatch(DFConstantsAndEnums.TempLogChannelBits config, DFConstantsAndEnums.TempLogChannelBits? bitToSkip)
|
|
//{
|
|
// var flags = Enum.GetValues(typeof(DFConstantsAndEnums.TempLogChannelBits)).Cast<DFConstantsAndEnums.TempLogChannelBits>().ToArray();
|
|
// foreach (var flag in flags)
|
|
// {
|
|
// if (null != bitToSkip && flag == (DFConstantsAndEnums.TempLogChannelBits)bitToSkip) { continue; }
|
|
// if (config.HasFlag(flag)) { return flag; }
|
|
// }
|
|
|
|
// return 0;
|
|
//}
|
|
/// <summary>
|
|
/// retrieves any Temp Log information and returns it to caller
|
|
/// </summary>
|
|
private void DownloadTemperatureCSV(object o)
|
|
{
|
|
var info = (QueryDownloadAsyncInfo)o;
|
|
try
|
|
{
|
|
var qsa = new QuerySystemAttributeSLICE6DB(this) { Key = AttributeTypes.SystemAttributesSLICE6DB.S6DBbaseEnvTempLoggingConfig, };
|
|
|
|
qsa.SyncExecute();
|
|
|
|
|
|
if (!(qsa.Value is ushort[] config)) { return; }
|
|
|
|
var tempConfig = new TemperatureConfig(config);
|
|
var channels = tempConfig.GetChannelsArray();
|
|
|
|
var channel1 = channels.Length > 0 ? channels[0] : -1;
|
|
var channel2 = channels.Length > 1 ? channels[1] : -1;
|
|
|
|
var query = new QueryTempLogFile(this);
|
|
query.SyncExecute();
|
|
var timeStamps = new List<DateTime>();
|
|
var sensor1 = new List<double>();
|
|
var sensor2 = new List<double>();
|
|
|
|
foreach (var tuple in query.TempData)
|
|
{
|
|
timeStamps.Add(tuple.Item1);
|
|
sensor1.Add(tuple.Item2);
|
|
sensor2.Add(tuple.Item3);
|
|
}
|
|
var data = new ServiceCallbackData() { Status = ServiceCallbackData.CallbackStatus.NewData };
|
|
data.UserData = info.userData;
|
|
data.SetNewTemperatureData(new ServiceCallbackData.TemperatureData()
|
|
{
|
|
Sensor1 = sensor1.ToArray(),
|
|
Sensor2 = sensor2.ToArray(),
|
|
Timestamps = timeStamps.ToArray(),
|
|
Channel1 = channel1,
|
|
Channel2 = channel2
|
|
});
|
|
info.callback.Invoke(data);
|
|
info.Success();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
info.Error(ex.Message, ex);
|
|
}
|
|
}
|
|
private DASModule CreateDummyModule()
|
|
{
|
|
// take the module from the stored config
|
|
return new DASModule()
|
|
{
|
|
Description = DTS.Common.Constants.DUMMY_MOD_DESCRIP_S6DB,
|
|
NumberOfSamples = 0,
|
|
RequestedPostTriggerSeconds = 0,
|
|
RequestedPreTriggerSeconds = 0,
|
|
PostTriggerSeconds = 0,
|
|
PreTriggerSeconds = 0,
|
|
RecordingMode = 0,
|
|
SampleRateHz = 0,
|
|
StartRecordSampleNumber = 0,
|
|
TriggerSampleNumbers = new ulong[] { 0 },
|
|
OwningDAS = this,
|
|
StartRecordTimestampSec = 0,
|
|
StartRecordTimestampNanoSec = 0,
|
|
TriggerTimestampSec = 0,
|
|
TriggerTimestampNanoSec = 0,
|
|
PTPMasterSync = false,
|
|
SystemID = string.Empty,
|
|
SystemLocation = string.Empty,
|
|
TiltSensorAxisXDegreesPre = double.NaN,
|
|
TiltSensorAxisYDegreesPre = double.NaN,
|
|
TiltSensorAxisZDegreesPre = double.NaN,
|
|
TiltSensorAxisXDegreesPost = double.NaN,
|
|
TiltSensorAxisYDegreesPost = double.NaN,
|
|
TiltSensorAxisZDegreesPost = double.NaN,
|
|
TemperatureLocation1Pre = float.NaN,
|
|
TemperatureLocation2Pre = float.NaN,
|
|
TemperatureLocation3Pre = float.NaN,
|
|
TemperatureLocation4Pre = float.NaN,
|
|
TemperatureLocation1Post = float.NaN,
|
|
TemperatureLocation2Post = float.NaN,
|
|
TemperatureLocation3Post = float.NaN,
|
|
TemperatureLocation4Post = float.NaN,
|
|
InputVoltage = float.NaN,
|
|
BatteryVoltage = float.NaN,
|
|
Channels = new AnalogInputDASChannel[0],
|
|
};
|
|
}
|
|
|
|
/// <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 SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update the recorded trigger sample numbers in HW
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
public void SetTriggerSampleNumbers(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
#region Trigger check
|
|
//13820 With the S6 ATD and a SLICE PRO system in the setup, consistently see Trigger Check Fail
|
|
private void AsyncPreStartTriggerCheckSLICE6DB(object o)
|
|
{
|
|
var info = (SDBAsyncInfo)o;
|
|
try
|
|
{
|
|
//11012 fix trigger check in "status line check", "arm checklist", and "arm" for slice6 db
|
|
//handle a non latched trigger that has already pulsed on a SLICE6DB
|
|
//by setting to triggered, if we read the trigger and it's not triggered presumably the hardware is shorted
|
|
var ssi = new SetSwitchImmediate(this);
|
|
ssi.DeviceID = 0x00;
|
|
ssi.Switch = (byte)Switches.BaseSwitches.TriggerOut;
|
|
ssi.SwitchText = Switches.BaseSwitches.TriggerOut.ToString();
|
|
ssi.Setting = 0x01;
|
|
ssi.SyncExecute();
|
|
|
|
ssi.Setting = 0x00;
|
|
ssi.SyncExecute();
|
|
// wait for one shot
|
|
//Per LP and MS, the max of the cap on SP DB is 2.4, so we should be using 3s for safety reasons on one shot
|
|
//this had previously been 1.7 for S6DB only
|
|
Thread.Sleep(DFConstantsAndEnums.OneShotWaitTimeMs);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
info.Error(ex.Message);
|
|
return;
|
|
}
|
|
info.Success();
|
|
}
|
|
//13820 With the S6 ATD and a SLICE PRO system in the setup, consistently see Trigger Check Fail
|
|
protected virtual void AsyncPostStartTriggerCheckSLICE6DB(object o)
|
|
{
|
|
var info = (SDBAsyncInfo)o;
|
|
var query = new InitializeHardwareLines(this);
|
|
try
|
|
{
|
|
|
|
//with the SLICE6DB, it will pulse high the trigger out when it recongizes a trigger, however this is a one time pulse
|
|
//so if this has already happened, the trigger will remain low (not shorted) when we manually force it to shorted
|
|
//per issue 11012
|
|
try
|
|
{
|
|
query.SyncExecute();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//apparently IHL throws an exception if it's shorted, so handle this silently as a known thing
|
|
//log if it's another exception
|
|
if (ex.Message.ToLower().Contains("shorted"))
|
|
{
|
|
SetDASArmStatus(new ArmStatus() { IsArmed = true, IsTriggered = true }, true);
|
|
info.Error("TriggerInputShorted");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
InitializeHardwareLines.Log(ex, query);
|
|
info.Error(ex.Message);
|
|
return;
|
|
}
|
|
|
|
SetDASArmStatus(new ArmStatus() { IsArmed = true, IsTriggered = false }, true);
|
|
info.Success();
|
|
}
|
|
private void AsyncStartTriggerCheckSLICE6DB(object o)
|
|
{
|
|
var info = (SDBAsyncInfo)o;
|
|
//13820 With the S6 ATD and a SLICE PRO system in the setup, consistently see Trigger Check Fail
|
|
//S6DB waits until PostStartTriggerCheck to check status
|
|
SetDASArmStatus(new ArmStatus() { IsArmed = true, IsTriggered = false }, true);
|
|
info.Success();
|
|
}
|
|
public void StartTriggerCheck(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
LaunchAsyncWorker("SliceDB.StartTriggerCheck", AsyncStartTriggerCheckSLICE6DB, info);
|
|
}
|
|
|
|
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
|
|
SDBAsyncInfo info = null;
|
|
if (null != callback)
|
|
{
|
|
info = new SDBAsyncInfo(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 };
|
|
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
|
|
};
|
|
|
|
//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.IsTriggerShorted = status.IsTriggered;
|
|
status.IsStartShorted = status.IsArmed;
|
|
SetDASArmStatus(status, true);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log("Failed to get trigger state", ex);
|
|
InitializeHardwareLines.Log(ex, query);
|
|
}
|
|
}
|
|
}
|
|
public void DoStartCheck(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines))
|
|
{
|
|
var query = new InitializeHardwareLines(this);
|
|
try
|
|
{
|
|
|
|
query.SyncExecute();
|
|
|
|
var status = new ArmStatus
|
|
{
|
|
IsArmed = true,
|
|
IsRecording = query.StartRecordShorted || query.TriggerInputShorted
|
|
};
|
|
|
|
SetDASArmStatus(status, true);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
InitializeHardwareLines.Log(ex, query);
|
|
}
|
|
}
|
|
info.Success();
|
|
}
|
|
|
|
public void CancelTriggerCheck(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
info.Success();
|
|
}
|
|
public override bool CheckAAF(float rate)
|
|
{
|
|
return true;
|
|
}
|
|
/// <summary>
|
|
/// the UDP settings to broadcast auto arm status to on auto arm boot
|
|
/// 17583 Monitor Test UI
|
|
/// </summary>
|
|
public string AutoArmUDPSetting { get; set; } = "239.1.2.3:8504";
|
|
/// <inheritdoc />
|
|
/// <summary>
|
|
/// Auto Arm a single DAS now
|
|
/// </summary>
|
|
/// <param name="callback">The function to call with information</param>
|
|
/// <param name="userData">Whatever you want to pass along</param>
|
|
/// <param name="eventGuid">A unique GUID that this event will be tagged
|
|
/// with</param>
|
|
/// <param name="armNowTimeout"></param>
|
|
/// <param name="testingMode"></param>
|
|
/// <param name="diagnosticsDelayMs"></param>
|
|
/// <param name="maxNumberEvents"></param>
|
|
void IArmActions.AutoArmNow(ServiceCallback callback,
|
|
object userData,
|
|
Guid eventGuid, int
|
|
armNowTimeout,
|
|
bool testingMode,
|
|
uint diagnosticsDelayMs,
|
|
int maxNumberEvents,
|
|
bool repeatEnable,
|
|
bool preserveDiagnostics)
|
|
{
|
|
var info = new SDBAsyncInfo(callback, userData);
|
|
|
|
try
|
|
{
|
|
SetRTCBaseTime();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
}
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmUDPSetting))
|
|
{
|
|
try
|
|
{
|
|
var set = new SetSystemAttributeSLICE6DB(this);
|
|
set.SetValue(AttributeTypes.SystemAttributesSLICE6DB.AUTOARMUDP_ADDRESS, AutoArmUDPSetting, true);
|
|
set.SyncExecute();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
}
|
|
}
|
|
info.Success();
|
|
}
|
|
public override bool SupportsTimeSynchronization => true;
|
|
|
|
|
|
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> SLICE6DB_MinimumProtocols =
|
|
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
|
|
|
public override void InitMinProto()
|
|
{
|
|
// SLICE 6 DB Protocol Limitations
|
|
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MeasureBaseDiagnosticChannel] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InSliceTemperatureCPre] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPSyncStatus] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetClockSyncConfig] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
|
|
// SLICE_DB Protocol Limitations
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.Arm] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EnableFaultChecking] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.OnOverride] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.OMAP_GPIO] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryBatteryVoltage] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRealtimeStream] = SLICE6DB.MIN_PROTOCOL_VER;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryEthernetMacTable] = SLICE6DB.MIN_PROTOCOL_QUERYMACTABLE;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryTempLogFile] = SLICE6DB.MIN_PROTOCOL_QUERYTEMPLOGFILE;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryTiltSensorData] = SLICE6DB.MIN_PROTOCOL_TILT;
|
|
SLICE6DB_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryExternalTiltInfo] = SLICE6DB.MIN_PROTOCOL_TILT;
|
|
MinimumProtocols = SLICE6DB_MinimumProtocols;
|
|
}
|
|
#endregion
|
|
|
|
#region IClockSyncActions
|
|
public virtual void SetClockSyncConfig(ServiceCallback callback, object userData, ClockSyncProfile profile)
|
|
{
|
|
var info = new SliceServiceAsyncInfo(callback, userData) { functionData = profile };
|
|
|
|
var packet = new SetClockSyncConfigPacket(info);
|
|
LaunchAsyncWorker("Slice.SetClockSyncConfig", AsyncSetClockSyncConfig, packet);
|
|
}
|
|
|
|
public virtual void GetClockSyncStatus(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SliceServiceAsyncInfo(callback, userData);
|
|
|
|
var packet = new GetClockSyncStatusPacket(info);
|
|
LaunchAsyncWorker("Slice.GetClockSyncStatus", AsyncGetClockSyncStatus, packet);
|
|
}
|
|
|
|
public virtual void GetPTPDomainID(ServiceCallback callback, object userData)
|
|
{
|
|
var info = new SliceServiceAsyncInfo(callback, userData);
|
|
|
|
var packet = new GetPTPDomainIDPacket(info);
|
|
LaunchAsyncWorker("Slice.GetPTPDomainID", AsyncGetPTPDomainID, packet);
|
|
}
|
|
|
|
public virtual void SetPTPDomainID(ServiceCallback callback, object userData, byte domainID)
|
|
{
|
|
var info = new SliceServiceAsyncInfo(callback, userData) { functionData = domainID };
|
|
|
|
var packet = new SetPTPDomainIDPacket(info);
|
|
LaunchAsyncWorker("Slice.SetPTPDomainID", AsyncSetPTPDomainID, packet);
|
|
}
|
|
#endregion
|
|
|
|
protected override void GetTiltResults(ArmCheckResults dasResults)
|
|
{
|
|
|
|
dasResults.TiltSensorDataPre = null;
|
|
dasResults.TiltDegrees = null;
|
|
dasResults.IndexedTiltDegrees = new Dictionary<byte, double[]>();
|
|
dasResults.IndexedTiltSensorDataPre = new Dictionary<byte, short[]>();
|
|
if (DASInfo.ActiveExternalTilts.Count > 0)
|
|
{
|
|
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.QueryTiltSensorData))
|
|
{
|
|
// Get Tilt Cals
|
|
//var tiltMifs = new Dictionary<byte, Tilt_MIF>();
|
|
TiltSensorGet tiltSensorGet;
|
|
foreach (var tiltInfo in DASInfo.ActiveExternalTilts)
|
|
{
|
|
tiltSensorGet = new TiltSensorGet(this, 600000)
|
|
{
|
|
Tilt_id = tiltInfo.TiltID,
|
|
Sub_cmd = TiltSensorMif.TiltSensorEEPROM,
|
|
Data_Offset = 0,
|
|
Data_Length = 256
|
|
};
|
|
tiltSensorGet.SyncExecute();
|
|
var curMif = new Tilt_MIF(tiltSensorGet.Data);
|
|
tiltSensorGet = new TiltSensorGet(this, 600000)
|
|
{
|
|
Sub_cmd = TiltSensorMif.TiltSensorData,
|
|
Tilt_id = tiltInfo.TiltID
|
|
};
|
|
|
|
tiltSensorGet.SyncExecute();
|
|
short[] axisADCData = new short[3];
|
|
axisADCData[0] = tiltSensorGet.Channel1ValueAdc;
|
|
axisADCData[1] = tiltSensorGet.Channel2ValueAdc;
|
|
axisADCData[2] = tiltSensorGet.Channel3ValueAdc;
|
|
|
|
dasResults.IndexedTiltSensorDataPre[tiltInfo.TiltID] = axisADCData;
|
|
dasResults.IndexedTiltDegrees[tiltInfo.TiltID] = Test.Module.GetTiltDegreesEU(axisADCData,
|
|
curMif.GetTiltCalibrations(),
|
|
Test.Module.GetTiltAxesFromAxisInfo(
|
|
new string[] { curMif.AxisLabel1.ToString(), curMif.AxisLabel2.ToString(), curMif.AxisLabel3.ToString() },
|
|
new bool[] { curMif.InvertAxis1, curMif.InvertAxis2, curMif.InvertAxis3 }),
|
|
curMif.AxisToIgnore,
|
|
Test.Module.GetMountOffsetsOrTargetsFromAxisInfo(
|
|
new float[] { curMif.MountOffsetAxis1, curMif.MountOffsetAxis2, curMif.MountOffsetAxis3 },
|
|
curMif.AxisToIgnore)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|