using System; using System.Collections.Generic; using DTS.Common.DASResource; using DTS.Common.Enums.DASFactory; using DTS.Common.ICommunication; using DTS.Common.Utilities.Logging; namespace DTS.DASLib.Command.SLICE.DownloadCommands { public class QueryEventDataBase : EventDataCommands { protected override Commands Command => Commands.QueryEventData; private const ushort ADC_OFFSET = 0x8000; public const byte ALL_CHANNELS = 0xFF; protected UInt16 _eventNumber; protected UInt64 _firstSample; protected UInt64 _lastSample; protected UInt64 _samplesDownloaded; protected byte _channel; protected int _channelsDownloaded; protected ushort[] _data; public UInt16 EventNumber { get => _eventNumber; set { _eventNumber = value; command.SetParameter(0, _eventNumber); } } public virtual UInt64 FirstSample { get => _firstSample; set { _firstSample = value; command.SetParameter(2, _firstSample); } } public virtual UInt64 LastSample { get => _lastSample; set { _lastSample = value; command.SetParameter(10, _lastSample); } } public byte Channel { get => _channel; set { _channel = value; command.SetParameter(18, _channel); ChannelsDownloaded = 0xFF == _channel ? 3 : 1; } } public int ChannelsDownloaded { get => _channelsDownloaded; set => _channelsDownloaded = value; } public int Count => (int)_samplesDownloaded; public QueryEventDataBase(DTS.Common.Interface.DASFactory.ICommunication sock) : base(sock) { command.Parameter = new byte[19]; _data = null; _eventNumber = 0; _firstSample = 0; _lastSample = 0; _channel = 0; command.ShouldLog = false; } public QueryEventDataBase(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec) : base(sock, timeoutMillisec) { command.Parameter = new byte[19]; _data = null; _eventNumber = 0; _firstSample = 0; _lastSample = 0; _channel = 0; command.ShouldLog = false; } public override void Execute(CommandCallback cb, object cbData) { // Do a little parameter checking if (_firstSample > _lastSample) { // "QueryEventData.Execute: First Sample cannot be greater than Last Sample" throw new ApplicationException(Strings.QueryEventData_Execute_Err1); } base.Execute(cb, cbData); } protected override CommandReceiveAction WholePackagePost() { // now send the data to the user var stat = CommandStatus.Success; if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError) { var s = (int)response.Status; APILogger.LogString("QueryEventData.WholePackagePost: reporting failure, status==" + CommandPacketBase.StatusLabels[s] + " (0x" + s.ToString("X") + ")"); stat = CommandStatus.Failure; } var cbReport = new QueryEventDataReport(stat, UserCallbackData); cbReport.Data = new short[_channelsDownloaded][]; for (var i = 0; i < _channelsDownloaded; i++) GetChannelData(i, out cbReport.Data[i]); return UserCallback(cbReport); } protected override CommandReceiveAction WholePackage() { if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError) { return CommandReceiveAction.StopReceiving; } _samplesDownloaded = (ulong)(response.Parameter.Length / 2) / (ulong)_channelsDownloaded; _data = new ushort[_samplesDownloaded * (ulong)_channelsDownloaded]; for (var i = 0; (ulong)i < _samplesDownloaded * (ulong)_channelsDownloaded; i++) { response.GetParameter(2 * i, out _data[i]); } return CommandReceiveAction.StopReceiving; } public override void SyncExecute() { // Do a little parameter checking if (_firstSample > _lastSample) { // "QueryEventData.SyncExecute: First Sample cannot be greater than Last Sample" throw new ApplicationException(Strings.QueryEventData_SyncExecute_Err1); } base.SyncExecute(); } public virtual void GetChannelData(int channel, out short[] signedADC) { if (channel < 0 || channel > _channelsDownloaded) { // "QueryEventData.GetChannelData: Data requested on a channel that wasn't downloaded." throw new ApplicationException(Strings.QueryEventData_GetChannelData_Err1); } // Data order for a 9 channel stack // 7 8 9 4 5 6 1 2 3 7 8 9 4 5 6 1 2 3 etc. var rv = new short[_samplesDownloaded]; var sliceNumber = channel / 3; var sliceOffset = (_channelsDownloaded / 3 - sliceNumber - 1) * 3; if (sliceOffset < 0) sliceOffset = 0; var channelInSlice = channel % 3; for (var i = 0; i < rv.Length; i++) { rv[i] = (short)(_data[i * _channelsDownloaded + sliceOffset + channelInSlice] - ADC_OFFSET); } signedADC = rv; } public virtual void GetRawIndexedData(int index, out ushort[] data) { data = new ushort[_samplesDownloaded]; for (var i = 0; i < data.Length; i++) { data[i] = _data[i * _channelsDownloaded + index]; } } public override void CommandToString(ref List> lines) { lines.Add(new List { $"Event number: {EventNumber}, First sample: {FirstSample}, Last sample: {LastSample}" }); } public override void ResponseToString(ref List> lines) { lines.Add(new List { $"ChannelsDownloaded: {ChannelsDownloaded}, Count: {Count}" }); } public void LogResponse() { LogCommand(false); } } }