Files
DP44/DataPRO/IService/Classes/SLICE/SLICE6DB.cs
2026-04-17 14:55:32 -04:00

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