Files
DP44/DataPRO/SLICECommands/ArmCommands.cs
2026-04-17 14:55:32 -04:00

644 lines
25 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using DTS.Common.Enums.DASFactory;
using DTS.Common.Utilities.Logging;
namespace DTS.DASLib.Command.SLICE
{
public abstract class ArmCommands : CommandBase
{
protected enum Commands
{
Reserved = 0x00,
Arm = 0x01,
Disarm = 0x02,
EnableFaultChecking = 0x03,
DisableFaultChecking = 0x04,
QueryArmAndTriggerStatus = 0x05,
PrepareForDiagnostics = 0x06,
PrepareForDataCollection = 0x07,
BeginFlashErase = 0x08,
QueryFlashEraseStatus = 0x09,
InitializeHardwareLines = 0x0a,
};
protected abstract Commands _Command { get; }
protected ArmCommands(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
command.Type = CommandPacket.CommandType.Arm;
command.SetCommand((byte)_Command, _Command.ToString());
}
protected ArmCommands(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
command.Type = CommandPacket.CommandType.Arm;
command.SetCommand((byte)_Command, _Command.ToString());
}
}
public class Arm : ArmCommands
{
protected override Commands _Command => Commands.Arm;
public Arm(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
}
public Arm(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
}
public DFConstantsAndEnums.CommandStatus ArmStatus { get; private set; } = DFConstantsAndEnums.CommandStatus.StatusNoError;
protected override CommandReceiveAction WholePackage()
{
switch (response.Status)
{
case DFConstantsAndEnums.CommandStatus.StatusNoError:
break;
default:
ArmStatus = response.Status;
break;
}
return CommandReceiveAction.StopReceiving;
}
}
public class EnableFaultChecking : ArmCommands
{
protected override Commands _Command => Commands.EnableFaultChecking;
public EnableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
}
public EnableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
}
}
public class DisableFaultChecking : ArmCommands
{
protected override Commands _Command => Commands.DisableFaultChecking;
public DisableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
}
public DisableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
}
}
public class QueryArmAndTriggerStatus : ArmCommands
{
protected override Commands _Command => Commands.QueryArmAndTriggerStatus;
public enum FaultFlags
{
IncomingStatusLineDropped = (1 << 0),
ADCBufferOverrun = (1 << 1),
FlashCRCError = (1 << 2),
TriggerBeforeStart = (1 << 3),
InputVoltageLow = (1 << 4),
InputVoltageHigh = (1 << 5),
BackupVoltageLow = (1 << 6),
BackupVoltageHigh = (1 << 7),
OutOfMemory = (1 << 8),
SquibResistanceOutOfRange = (1 << 9),
SafeSwitchUnplugged = (1 << 10),
SquibPowerOutOfRange = (1 << 11),
AutoSquibDisableActivated = (1 << 12)
}
private float _inputVoltage = 0;
public float InputVoltage => _inputVoltage;
private float _backupVoltage = 0;
public float BackupVoltage => _backupVoltage;
private byte _armstate;
private byte _armmode;
private byte _startrecordstatus;
private byte _triggerstatus;
private byte _faultstatus;
private uint _eventsamplerate;
private ulong _totalsamples;
private ulong _currentsample;
private ushort _currenteventnumber;
private ulong _faultsamplenumber;
private ushort _faultbits;
private float _batterySoc;
private float _systemTempC;
private ulong _actualCurrentSample;
private ulong _maxSampleAvailable;
private short _tsChannel1;
private short _tsChannel2;
private short _tsChannel3;
private short _sensorChannelA;
private short _sensorChannelB;
private short _sensorChannelC;
private short _sensorChannelD;
private short _sensorChannelE;
private short _sensorChannelF;
// for TOM
private float _squib1;
private float _squib2;
private float _squib3;
private float _squib4;
private float _squibP17V;
private float _squibP5V;
private float _squibP3p3V;
private float _squibN5V;
private bool _ptpEnable;
private bool _adcPtpClkEnable;
private bool _ptpSyncStatus;
private bool _adcClkSyncStatus;
private uint _extFaultId;
public ArmStates ArmState => (ArmStates)_armstate;
public enum ArmStates { Disarmed, Armed, Realtime, Diagnostics, FlashClear, Arming };
public byte ArmMode => _armmode;
public bool IsDiagnostics => (ArmStates)_armstate == ArmStates.Diagnostics;
public bool IsFlashClear => (ArmStates)_armstate == ArmStates.FlashClear;
public bool IsArming => (ArmStates)_armstate == ArmStates.Arming;
public bool IsArmed => (ArmStates)_armstate == ArmStates.Armed;
public bool IsInRealtime => (ArmStates)_armstate == ArmStates.Realtime;
public bool IsRecording => _startrecordstatus == 0x01;
public bool IsTriggered => _triggerstatus == 0x01;
public bool IsFaulted => _faultstatus == 0x01;
public uint EventSampleRate => _eventsamplerate;
public ulong TotalSamples => _totalsamples;
public ulong CurrentSample => _currentsample;
public ushort EventNumber => _currenteventnumber;
public ulong FaultSampleNumber => _faultsamplenumber;
public List<FaultFlags> CurrentFaultFlags { get; } = new List<FaultFlags>();
public int BatterySoc => (int)_batterySoc;
public float SystemTempC => _systemTempC;
public ulong ActualCurrentSample => _actualCurrentSample;
public ulong MaxSampleAvailable => _maxSampleAvailable;
public short TiltSensorChannel1 => _tsChannel1;
public short TiltSensorChannel2 => _tsChannel2;
public short TiltSensorChannel3 => _tsChannel3;
public short SensorChannelA => _sensorChannelA;
public short SensorChannelB => _sensorChannelB;
public short SensorChannelC => _sensorChannelC;
public short SensorChannelD => _sensorChannelD;
public short SensorChannelE => _sensorChannelE;
public short SensorChannelF => _sensorChannelF;
public float SquibResistance1 { get { return _squib1; } }
public float SquibResistance2 { get { return _squib2; } }
public float SquibResistance3 { get { return _squib3; } }
public float SquibResistance4 { get { return _squib4; } }
public float SquibPowerP17V { get { return _squibP17V; } }
public float SquibPowerP5V { get { return _squibP5V; } }
public float SquibPowerP3p3V { get { return _squibP3p3V; } }
public float SquibPowerN5V { get { return _squibN5V; } }
public bool PtpFunctionEnable { get { return _ptpEnable; } }
public bool AdcPtpClkEnable { get { return _adcPtpClkEnable; } }
public bool PtpClkSyncStatus { get { return _ptpSyncStatus; } }
public bool AdcClkSyncStatus { get { return _adcClkSyncStatus; } }
private List<QATSExtendedFault> _extendedFaultFlags = new List<QATSExtendedFault>();
public List<QATSExtendedFault> ExtendedFaultFlags { get { return _extendedFaultFlags; } }
public uint ExtendedFaultId { get { return _extFaultId; } }
public QueryArmAndTriggerStatus(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
}
public QueryArmAndTriggerStatus(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
}
private const int QUATS_MIN_LENGTH_INPUTVOLTAGE = 38;
private const int QUATS_MIN_LENGTH_BACKUPVOLTAGE = 42;
private const int QUATS_MIN_LENGTH_BATTERYSOC = 49;
private const int QUATS_MIN_LENGTH_ACTUALCURRENTSAMPLE = 57;
private const int QUATS_MIN_LENGTH_MAXSAMPLEAVAILABLE = 65;
private const int QUATS_MIN_LENGTH_TILTCHANNELDATA = 71;
private const int QUATS_MIN_LENGTH_SYSTEMTEMP = 75;
private const int QUATS_MIN_LENGTH_CHANNELADC = 87;
private const int QUATS_MIN_LENGTH_TOMSTATUS = 119;
private const int QUATS_MIN_LENGTH_CLKSTATUS = 123;
private const int QUATS_MIN_LENGTH_EXTFAULTID = 127;
protected override CommandReceiveAction WholePackage()
{
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
{
if (response.ParameterLength > 1)
{
response.GetParameter(0, out _armstate);
response.GetParameter(1, out _armmode);
response.GetParameter(2, out _startrecordstatus);
response.GetParameter(3, out _triggerstatus);
response.GetParameter(4, out _faultstatus);
response.GetParameter(5, out _eventsamplerate);
response.GetParameter(9, out _totalsamples);
response.GetParameter(17, out _currentsample);
response.GetParameter(25, out _currenteventnumber);
response.GetParameter(27, out _faultsamplenumber);
//this is only valid for > 00E7, but that's long retired, so I'm enforcing it now
response.GetParameter(35, out _faultbits);
for (int i = 0; i < 16; i++)
{
if (0 != (_faultbits & (1 << i)))
{
CurrentFaultFlags.Add((FaultFlags)(1 << i));
}
}
if (response.ParameterLength >= QUATS_MIN_LENGTH_INPUTVOLTAGE)
{
response.GetParameter(37, out _inputVoltage);
}
else
{
_inputVoltage = 0;
}
if (response.ParameterLength >= QUATS_MIN_LENGTH_BACKUPVOLTAGE)
{
response.GetParameter(41, out _backupVoltage);
}
else
{
_backupVoltage = 0;
}
if (recorder.IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.QueryBatterySOC)
&& response.ParameterLength >= QUATS_MIN_LENGTH_BATTERYSOC)
{
response.GetParameter(45, out _batterySoc);
}
else
{
_batterySoc = 0;
}
if (response.ParameterLength >= QUATS_MIN_LENGTH_ACTUALCURRENTSAMPLE)
{
response.GetParameter(49, out _actualCurrentSample);
}
else
{
_actualCurrentSample = 0;
}
if (response.ParameterLength >= QUATS_MIN_LENGTH_MAXSAMPLEAVAILABLE)
{
response.GetParameter(57, out _maxSampleAvailable);
}
else
{
_maxSampleAvailable = 0;
}
if (response.ParameterLength >= QUATS_MIN_LENGTH_TILTCHANNELDATA)
{
response.GetParameter(65, out _tsChannel1);
response.GetParameter(67, out _tsChannel2);
response.GetParameter(69, out _tsChannel3);
}
else
{
_tsChannel1 = 0;
_tsChannel2 = 0;
_tsChannel3 = 0;
}
if (response.ParameterLength >= QUATS_MIN_LENGTH_SYSTEMTEMP)
{
response.GetParameter(71, out _systemTempC);
}
else
{
_systemTempC = 0;
}
if (response.ParameterLength >= QUATS_MIN_LENGTH_CHANNELADC)
{
response.GetParameter(75, out _sensorChannelA);
response.GetParameter(77, out _sensorChannelB);
response.GetParameter(79, out _sensorChannelC);
response.GetParameter(81, out _sensorChannelD);
response.GetParameter(83, out _sensorChannelE);
response.GetParameter(85, out _sensorChannelF);
}
else
{
_sensorChannelA = 0;
_sensorChannelB = 0;
_sensorChannelC = 0;
_sensorChannelD = 0;
_sensorChannelE = 0;
_sensorChannelF = 0;
}
// hack for TOM
if (response.ParameterLength >= QUATS_MIN_LENGTH_TOMSTATUS)
{
response.GetParameter(87, out _squib1);
response.GetParameter(91, out _squib2);
response.GetParameter(95, out _squib3);
response.GetParameter(99, out _squib4);
response.GetParameter(103, out _squibP17V);
response.GetParameter(107, out _squibP5V);
response.GetParameter(111, out _squibP3p3V);
response.GetParameter(115, out _squibN5V);
}
if (response.ParameterLength >= QUATS_MIN_LENGTH_CLKSTATUS)
{
response.GetParameter(119, out _ptpEnable);
response.GetParameter(120, out _adcPtpClkEnable);
response.GetParameter(121, out _ptpSyncStatus);
response.GetParameter(122, out _adcClkSyncStatus);
}
if (response.ParameterLength >= QUATS_MIN_LENGTH_EXTFAULTID)
{
response.GetParameter(123, out _extFaultId);
}
for (int i = 0; i < 32; i++)
{
if (0 != (_extFaultId & (1 << i)))
{
_extendedFaultFlags.Add((QATSExtendedFault)(1 << i));
}
}
}
}
return CommandReceiveAction.StopReceiving;
}
public override void ResponseToString(ref List<List<string>> lines)
{
base.ResponseToString(ref lines);
lines.Add(new List<string>() { $"Event number: {EventNumber}, Arm Mode: {ArmMode}" });
lines.Add(new List<string>() { $"Armed: {IsArmed}, Started: {IsRecording}, Triggered: {IsTriggered}, Faulted: {IsFaulted}, Diagnostics: {IsDiagnostics}, FlashClear: {IsFlashClear}, Arming: {IsArming}, ArmState: {_armstate}" });
lines.Add(new List<string>() { $"Samplerate: {EventSampleRate}, Current Sample: {CurrentSample}, Total Samples: {TotalSamples}, Fault Sample Number: {FaultSampleNumber}" });
lines.Add(new List<string>() { $"Input Voltage: {InputVoltage.ToString("N3")}V, Backup Voltage: {BackupVoltage.ToString("N3")}V, Backup Percentage Remaining: {BatterySoc}%" });
lines.Add(new List<string>() { $"System Temp: {SystemTempC}C, Actual Current Sample: {ActualCurrentSample}, Max Sample Available: {MaxSampleAvailable}" });
lines.Add(new List<string>() { $"Tilt Ch1: {TiltSensorChannel1}, Tilt Ch2: {TiltSensorChannel2}, Tilt Ch3: {TiltSensorChannel3}" });
lines.Add(new List<string>() { $"Squib Ch1: {SquibResistance1}, Squib Ch2: { SquibResistance2}, Squib Ch3: { SquibResistance3}, Squib Ch4: { SquibResistance4}" });
lines.Add(new List<string>() { $"Squib P17V: {SquibPowerP17V}, Squib PV5: { SquibPowerP5V}, Squib P3p3V: { SquibPowerP3p3V}, Squib N5V: { SquibPowerN5V}" });
lines.Add(new List<string>() { $"PTP Enabled: {PtpFunctionEnable}, PTP Clk Enable: {AdcPtpClkEnable}, PTP Clk Sync Status: {PtpClkSyncStatus}, ADC Clk Sync Status: {AdcClkSyncStatus}" });
var sb = new StringBuilder(50);
sb.AppendFormat("Fault Flags: ");
if (null != CurrentFaultFlags && CurrentFaultFlags.Count > 0)
{
var addcomma = false;
for (int i = 0; i < CurrentFaultFlags.Count; i++)
{
if (addcomma) sb.AppendFormat(", ");
addcomma = true;
sb.AppendFormat("{0}", CurrentFaultFlags[i].ToString());
}
}
else
{
sb.AppendFormat("none");
}
lines.Add(new List<string>() { sb.ToString() });
sb = new StringBuilder();
sb.AppendFormat("Extended Fault Flags: ");
if (null != ExtendedFaultFlags && ExtendedFaultFlags.Count > 0)
{
var addcomma = false;
for (int i = 0; i < ExtendedFaultFlags.Count; i++)
{
if (addcomma) sb.AppendFormat(", ");
addcomma = true;
sb.AppendFormat("{0}", ExtendedFaultFlags[i].ToString());
}
}
else
{
sb.AppendFormat("none");
}
lines.Add(new List<string>() { sb.ToString() });
}
}
public class Disarm : ArmCommands
{
protected override Commands _Command => Commands.Disarm;
public Disarm(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
}
public Disarm(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
}
}
public class PrepareForDiagnostics : ArmCommands
{
protected override Commands _Command => Commands.PrepareForDiagnostics;
public PrepareForDiagnostics(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
}
public PrepareForDiagnostics(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
}
}
public class PrepareForDataCollection : ArmCommands
{
protected override Commands _Command => Commands.PrepareForDataCollection;
public PrepareForDataCollection(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
}
public PrepareForDataCollection(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
}
}
public class BeginFlashErase : ArmCommands
{
protected override Commands _Command => Commands.BeginFlashErase;
public BeginFlashErase(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
}
public BeginFlashErase(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
}
}
public class QueryFlashEraseStatus : ArmCommands
{
protected override Commands _Command => Commands.QueryFlashEraseStatus;
public QueryFlashEraseStatus(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
}
public QueryFlashEraseStatus(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
}
private float _percentcomplete;
public float PercentComplete => _percentcomplete;
private byte _lasterror;
public DFConstantsAndEnums.CommandStatus LastError => (DFConstantsAndEnums.CommandStatus)_lasterror;
protected override CommandReceiveAction WholePackage()
{
const int LastErrorPosition = 0;
const int PercentCompletePosition = 1;
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
{
response.GetParameter(LastErrorPosition, out _lasterror);
response.GetParameter(PercentCompletePosition, out _percentcomplete);
}
return CommandReceiveAction.StopReceiving;
}
public override void ResponseToString(ref List<List<string>> lines)
{
base.ResponseToString(ref lines);
lines.Add(new List<string>() { $"Erase status: {LastError.ToString()}, Percent complete: {PercentComplete.ToString()}" });
}
}
public class InitializeHardwareLines : ArmCommands
{
protected override Commands _Command => Commands.InitializeHardwareLines;
public bool CheckTriggerForShort
{
get => Convert.ToBoolean(command.Parameter[0]);
set => command.Parameter[0] = Convert.ToByte(value);
}
public bool CheckStartForShort
{
get => Convert.ToBoolean(command.Parameter[1]);
set => command.Parameter[1] = Convert.ToByte(value);
}
public InitializeHardwareLines(DTS.Common.Interface.DASFactory.ICommunication sock)
: base(sock)
{
command.Parameter = new byte[] { 0x01, 0x01 };
LogCommands = false;
}
public InitializeHardwareLines(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
: base(sock, TimeoutMillisec)
{
command.Parameter = new byte[] { 0x01, 0x01 };
LogCommands = false;
}
public bool StartRecordShorted { get; private set; } = false;
public bool TriggerInputShorted { get; private set; } = false;
protected override CommandReceiveAction WholePackage()
{
switch (response.Status)
{
case DFConstantsAndEnums.CommandStatus.StatusNoError:
break;
case DFConstantsAndEnums.CommandStatus.StatusArmShortedStartRecordInput:
StartRecordShorted = true;
break;
case DFConstantsAndEnums.CommandStatus.StatusArmShortedTriggerInput:
TriggerInputShorted = true;
break;
case DFConstantsAndEnums.CommandStatus.StatusArmShortedStartAndTrigger:
StartRecordShorted = true;
TriggerInputShorted = true;
break;
default:
APILogger.Log("Unexpected return from InitializeHardwareLines ", response.Status.ToString());
break;
}
return CommandReceiveAction.StopReceiving;
}
public override void ResponseToString(ref List<List<string>> lines)
{
base.ResponseToString(ref lines);
lines.Add(new List<string>(new[] { $"StartRecord: {StartRecordShorted}, Trigger: {TriggerInputShorted}" }));
}
public static void Log(Exception exception, InitializeHardwareLines ihl)
{
var bShortStart = exception.Message.Contains(DFConstantsAndEnums.CommandStatus.StatusArmShortedStartRecordInput.ToString());
var bShortTrig = exception.Message.Contains(DFConstantsAndEnums.CommandStatus.StatusArmShortedTriggerInput.ToString());
if (exception.Message.Contains(DFConstantsAndEnums.CommandStatus.StatusArmShortedStartAndTrigger.ToString()))
{
bShortStart = true;
bShortTrig = true;
}
APILogger.Log($"InitializeHardwareLines: Start shorted: {bShortStart} Trigger shorted: {bShortTrig}");
}
}
}