init
This commit is contained in:
1
DataPRO/IService/.svn/entries
Normal file
1
DataPRO/IService/.svn/entries
Normal file
@@ -0,0 +1 @@
|
||||
12
|
||||
1
DataPRO/IService/.svn/format
Normal file
1
DataPRO/IService/.svn/format
Normal file
@@ -0,0 +1 @@
|
||||
12
|
||||
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static DTS.Common.Enums.DASFactory.DFConstantsAndEnums;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// the base class for our internal callbacks (specific service callback to generic service)
|
||||
/// </summary>
|
||||
public class ServiceCallbackData
|
||||
{
|
||||
public class DiagnosticNewData
|
||||
{
|
||||
public int DasChannelNumber { get; set; }
|
||||
public enum Actions
|
||||
{
|
||||
MeasureBridgeMv, MeasureShunt, ScaleFactorMv, FactoryExcitation, MeasureExcitation,
|
||||
MeasureOffset, CalSignalCheck, FinalOffset, MeasureNoise, RemoveOffset, ShuntCheck, QueryModules, MeasureVoltages,
|
||||
TestChannelRun, TestChannelRead, MeasureInternalOffset, MeasureFinalInternalOffset
|
||||
};
|
||||
public Actions Action { get; set; }
|
||||
public object Result { get; set; }
|
||||
}
|
||||
|
||||
public class TiltNewData
|
||||
{
|
||||
public double[] TiltData { get; set; }
|
||||
|
||||
public double[] AccelData { get; set; }
|
||||
}
|
||||
|
||||
public class TemperatureData
|
||||
{
|
||||
public int Channel1 { get; set; }
|
||||
public int Channel2 { get; set; }
|
||||
public DateTime[] Timestamps { get; set; }
|
||||
public double[] Sensor1 { get; set; }
|
||||
public double[] Sensor2 { get; set; }
|
||||
}
|
||||
public class UARTNewData
|
||||
{
|
||||
public ulong DataOffset { get; set; }
|
||||
public byte[] UARTData { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The different types of callbacks
|
||||
/// </summary>
|
||||
public enum CallbackStatus
|
||||
{
|
||||
ProgressReport,
|
||||
NewData,
|
||||
Timeout,
|
||||
Success,
|
||||
Failure,
|
||||
Canceled,
|
||||
InvalidParameters // and others
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// What kind of message is this
|
||||
/// </summary>
|
||||
public CallbackStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If it was an error (Status==Failure), the message is here
|
||||
/// </summary>
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If it was an exception (Status==Failure), it's here otherwise null
|
||||
/// </summary>
|
||||
public System.Exception ErrorException { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If it was ProgressReport, this is the percentage done
|
||||
/// </summary>
|
||||
public int ProgressValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user supplied data is here
|
||||
/// </summary>
|
||||
public object UserData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// callback could contain multiple non contiguous samples
|
||||
/// if so, we will need to know a separate sample number and short [][]
|
||||
/// for each break
|
||||
/// this is mostly for nicer realtime handling so data can be obtained from the
|
||||
/// h/w at a different rate then the UI is updated at
|
||||
/// </summary>
|
||||
private IList<SampleData> _Data = new List<SampleData>();
|
||||
/// <summary>
|
||||
/// returns a collection of <see cref="SampleData">SampleData</see>
|
||||
/// objects which contain sequences of channel data and a number indicating
|
||||
/// which samle number in the h/w each sequence begins at
|
||||
/// </summary>
|
||||
public SampleData[] DataSamples
|
||||
{
|
||||
get => _Data.ToArray();
|
||||
set => _Data = new List<SampleData>(value);
|
||||
}
|
||||
|
||||
private DiagnosticNewData _newDiagnosticData = null;
|
||||
|
||||
private TiltNewData _newTiltData = null;
|
||||
|
||||
private UARTNewData _newUartData = null;
|
||||
private TemperatureData _newTemperatureData = null;
|
||||
public DiagnosticNewData NewDiagnosticData => _newDiagnosticData;
|
||||
public void SetNewDiagnosticData(DiagnosticNewData data) { _newDiagnosticData = data; }
|
||||
|
||||
public void SetNewTiltData(TiltNewData data) { _newTiltData = data; }
|
||||
|
||||
public void SetNewTemperatureData(TemperatureData data) { _newTemperatureData = data; }
|
||||
public void SetNewUARTData(UARTNewData data) { _newUartData = data; }
|
||||
|
||||
private byte[] _byteData = null;
|
||||
public void SetNewByteData(byte[] data) { _byteData = data; }
|
||||
public byte[] ByteData { get => _byteData; }
|
||||
public TiltNewData NewTiltData => _newTiltData;
|
||||
|
||||
public UARTNewData NewUARTData => _newUartData;
|
||||
|
||||
public TemperatureData NewTemperatureData => _newTemperatureData;
|
||||
/// <summary>
|
||||
/// adds a new sample (composed of multiple channels of short [] data and
|
||||
/// a sample number indicating the start of the data
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="sampleNumber"></param>
|
||||
public void AddSampleData(short[][] data, ulong sampleNumber, ulong timeStamp, ulong sequenceNumber)
|
||||
{
|
||||
_Data.Add(new SampleData(data, sampleNumber, timeStamp, sequenceNumber));
|
||||
}
|
||||
/// <summary>
|
||||
/// returns the <see cref="SampleData">SampleData</see> struct
|
||||
/// at a given index among a collection of samples
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public SampleData GetSampleData(int index) { return _Data[index]; }
|
||||
/// <summary>
|
||||
/// the total number of different non contiguous samples in the data
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int GetNumberOfSamples() { return _Data.Count; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a simple serializable dictionary
|
||||
/// I'm using it for storing user attributes on slicepro/1.5 right now, but it's probably suitable for any dictionary
|
||||
/// that needs to be serialized
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
[XmlRoot("SerializedDictionary")]
|
||||
public class SerializableDictionary<TKey, TValue>
|
||||
: Dictionary<TKey, TValue>, IXmlSerializable
|
||||
{
|
||||
#region IXmlSerializable Members
|
||||
public System.Xml.Schema.XmlSchema GetSchema()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ReadXml(System.Xml.XmlReader reader)
|
||||
{
|
||||
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
|
||||
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
|
||||
|
||||
bool wasEmpty = reader.IsEmptyElement;
|
||||
if (wasEmpty)
|
||||
return;
|
||||
|
||||
reader.Read();//document
|
||||
reader.ReadStartElement();//serializeddictionary
|
||||
|
||||
while (reader.NodeType != System.Xml.XmlNodeType.EndElement && reader.NodeType != System.Xml.XmlNodeType.None)
|
||||
{
|
||||
reader.ReadStartElement("Item");
|
||||
|
||||
reader.ReadStartElement("Key");
|
||||
TKey key = (TKey)keySerializer.Deserialize(reader);
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("Value");
|
||||
TValue value = (TValue)valueSerializer.Deserialize(reader);
|
||||
reader.ReadEndElement();
|
||||
|
||||
this.Add(key, value);
|
||||
|
||||
reader.ReadEndElement();
|
||||
reader.MoveToContent();
|
||||
}
|
||||
if (reader.NodeType != System.Xml.XmlNodeType.None)
|
||||
{
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteXml(System.Xml.XmlWriter writer)
|
||||
{
|
||||
writer.WriteStartDocument();
|
||||
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
|
||||
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
|
||||
writer.WriteStartElement("SerializedDictionary");
|
||||
foreach (TKey key in this.Keys)
|
||||
{
|
||||
writer.WriteStartElement("Item");
|
||||
|
||||
writer.WriteStartElement("Key");
|
||||
keySerializer.Serialize(writer, key);
|
||||
writer.WriteEndElement();//key
|
||||
|
||||
writer.WriteStartElement("Value");
|
||||
TValue value = this[key];
|
||||
valueSerializer.Serialize(writer, value);
|
||||
writer.WriteEndElement();//value
|
||||
|
||||
writer.WriteEndElement();//item
|
||||
writer.Flush();
|
||||
}
|
||||
writer.WriteEndElement();//SerializedDictionary
|
||||
writer.WriteEndDocument();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("IService")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("IService")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("7085ea4c-93ee-4ba6-b42d-4776598554e1")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.06.0081")]
|
||||
[assembly: AssemblyFileVersion("1.06.0081")]
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// this attribute allows us to associate a max input range in mV for a gain
|
||||
/// note that this can be computed using the gain itself and the input range
|
||||
/// but this allows us to more tightly control things (say by using 2450 instead of 2500 for full range or something similar)
|
||||
/// http://fogbugz/fogbugz/default.asp?10080
|
||||
/// </summary>
|
||||
public class MaxInputRangeAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// returns the max input range in mV for gain
|
||||
/// http://fogbugz/fogbugz/default.asp?10080
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
/// <returns></returns>
|
||||
public static double GetMaxInputRangemV(object o)
|
||||
{
|
||||
if (o == null) return 0D;
|
||||
var mi = o.GetType().GetMember(o.ToString());
|
||||
if (mi.Length <= 0) return 0D;
|
||||
return GetCustomAttribute(mi[0], typeof(MaxInputRangeAttribute)) is MaxInputRangeAttribute attr ? attr._maximumInputRangemV : 0D;
|
||||
}
|
||||
|
||||
private readonly double _maximumInputRangemV;
|
||||
public MaxInputRangeAttribute(double maxInputRangemV)
|
||||
{
|
||||
_maximumInputRangemV = maxInputRangemV;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.StatusAndProgressBar;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static DTS.DASLib.Service.ServiceBase;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class RealtimeStatusInformation : IStatusInfo
|
||||
{
|
||||
private readonly ManualResetEvent stopRealtimeEvent = new ManualResetEvent(true);
|
||||
|
||||
//this is a wait handle that is set when we get a callback from realtime service saying it's done
|
||||
private readonly ManualResetEvent realtimeDoneFromService = new ManualResetEvent(false);
|
||||
|
||||
/// <summary>
|
||||
/// action to take on completion of Realtime start
|
||||
/// </summary>
|
||||
public Action CompleteAction { get; set; }
|
||||
public void Reset()
|
||||
{
|
||||
CompleteAction = null;
|
||||
realtimeDoneFromService.Reset();
|
||||
stopRealtimeEvent.Set();
|
||||
CouldNotStartRealtime = false;
|
||||
}
|
||||
|
||||
public Action<double, double> SetRealtimeSampleRateAAF { get; set; }
|
||||
public bool CouldNotStartRealtime { get; set; }
|
||||
public Callback StartRealtimeCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// returns the Anti-Alias Filter (AAF) for the DAS in question
|
||||
/// this is dependent on the sample rate for the hardware and a ratio in the config file
|
||||
/// (RealtimeSampleRateAAFilterRatio)
|
||||
/// </summary>
|
||||
/// <param name="das"></param>
|
||||
/// <returns></returns>
|
||||
private float GetRealtimeAAFForHardware(IDASCommunication idas, double samplerate)
|
||||
{
|
||||
var param = States.Instance.Realtime.Status.RealtimeParams;
|
||||
if (param.SliceTurnOffAAFRealtime && DFConstantsAndEnums.SupportsTurnOffAAFRealtime(idas))
|
||||
{
|
||||
return Common.Constants.SLICE2_NO_AAF_REALTIME_RATE;
|
||||
}
|
||||
//for now there is no additional work done
|
||||
if (0 == param.RealtimeSampleRateAAFilterRatio) { return Convert.ToSingle(samplerate); }
|
||||
return (float)samplerate / param.RealtimeSampleRateAAFilterRatio;
|
||||
}
|
||||
|
||||
public bool IsInRealtime
|
||||
{
|
||||
get { return !stopRealtimeEvent.WaitOne(2, false); }
|
||||
}
|
||||
|
||||
public void StopRealtime()
|
||||
{
|
||||
stopRealtimeEvent.Set();
|
||||
}
|
||||
|
||||
Task _realtimeTask;
|
||||
public void StartRealtime()
|
||||
{
|
||||
_realtimeTask = Task.Run(() =>
|
||||
{
|
||||
var param = States.Instance.Realtime.Status.RealtimeParams;
|
||||
var status = States.Instance.Realtime.Status.RealtimeStatus;
|
||||
var global = States.Instance.Realtime.Status.GlobalStatusParameters;
|
||||
StartRealtime(param.UnitsToStartRealtime, param.ModuleIndices, param.UseSingleSampleMode,
|
||||
param.RealtimeSampleRate, param.RealtimeDelayBetweenPollsInMilliSecond, param.AllowMultipleSampleRealtime, status.SetRealtimeSampleRateAAF, status.CompleteAction,
|
||||
param.IdasToActiveChannels, status.StartRealtimeCallback);
|
||||
});
|
||||
}
|
||||
|
||||
public void StartRealtime(List<IDASCommunication> ldas, List<int> moduleArrayIndicies, bool useSingleSampleMode,
|
||||
double realtimeSampleRate, int realtimeDelayBetweenPolls, bool allowMultipleSampleRealtime, Action<double, double> SetRealtimeSampleRateAAF, Action CompleteAction,
|
||||
Dictionary<IDASCommunication, byte[]> idasToActiveChannels, Callback StartRealtimeCallback
|
||||
)
|
||||
{
|
||||
var startRealtimeCallback = new Callback(StartRealtimeCallback);
|
||||
startRealtimeCallback += (data) =>
|
||||
{
|
||||
if (data.Status == CallbackData.CallbackStatus.AllFinished)
|
||||
{
|
||||
//service is done, mark it
|
||||
realtimeDoneFromService.Set();
|
||||
}
|
||||
if (data.Status == CallbackData.CallbackStatus.Failure)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
stopRealtimeEvent.Reset();
|
||||
using (var realtimeService = new RealtimeService())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ldas.Count > 0)
|
||||
{
|
||||
|
||||
if (useSingleSampleMode)
|
||||
{
|
||||
realtimeDoneFromService.Reset();
|
||||
realtimeService.StartActivePolling(ldas, startRealtimeCallback, ldas,
|
||||
stopRealtimeEvent, idasToActiveChannels);
|
||||
SetRealtimeSampleRateAAF(double.NaN, double.NaN);
|
||||
}
|
||||
else
|
||||
{
|
||||
realtimeDoneFromService.Reset();
|
||||
realtimeService.Start(ldas,
|
||||
Convert.ToInt32(realtimeSampleRate),
|
||||
realtimeDelayBetweenPolls,
|
||||
startRealtimeCallback,
|
||||
ldas,
|
||||
allowMultipleSampleRealtime,
|
||||
moduleArrayIndicies.ToArray(),
|
||||
stopRealtimeEvent,
|
||||
idasToActiveChannels,
|
||||
GetRealtimeAAFForHardware);
|
||||
if (ldas.Any())
|
||||
{
|
||||
SetRealtimeSampleRateAAF(realtimeSampleRate,
|
||||
GetRealtimeAAFForHardware(ldas[0], realtimeSampleRate));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRealtimeSampleRateAAF(double.NaN, double.NaN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
CouldNotStartRealtime = true;
|
||||
//there was an exception , stop the realtime and service
|
||||
stopRealtimeEvent.Set();
|
||||
realtimeDoneFromService.Set();
|
||||
}
|
||||
finally
|
||||
{
|
||||
CompleteAction();
|
||||
}
|
||||
|
||||
var mr = new ManualResetEvent(false);
|
||||
realtimeService.ServiceAvailable += delegate
|
||||
{
|
||||
realtimeService.ServiceAvailable -= delegate { };
|
||||
mr.Set();
|
||||
};
|
||||
|
||||
while (!stopRealtimeEvent.WaitOne(30, false) && !mr.WaitOne(1, false))
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
//either realtime event was signalled to stop (datapro) or the service actually did already stop
|
||||
//go and set the event handle to stopped to notify service in case it's running
|
||||
stopRealtimeEvent.Set();
|
||||
//now wait for the event from the service saying it's stopped
|
||||
realtimeDoneFromService.WaitOne();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
enum Trigger
|
||||
{
|
||||
PingAndConnect,
|
||||
Reset,
|
||||
ResolveChannelsAuto,
|
||||
ResolveChannelsManual,
|
||||
ApplyConfiguration,
|
||||
TurnOffExcitation,
|
||||
Cancel,
|
||||
Finish,
|
||||
Arm,
|
||||
StartRealtime,
|
||||
RequeryDevice,
|
||||
Download
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,153 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ArmFailtureDisconnect" xml:space="preserve">
|
||||
<value>There was a send or receive communication error while arming {0}. The unit may complete arming on it's own, but will not be reconnected until the unit or the software is powered down and restarted.</value>
|
||||
</data>
|
||||
<data name="NotCharging" xml:space="preserve">
|
||||
<value>(Not charging)</value>
|
||||
</data>
|
||||
<data name="Charging" xml:space="preserve">
|
||||
<value>(Charging)</value>
|
||||
</data>
|
||||
<data name="Discharging" xml:space="preserve">
|
||||
<value>(Discharging)</value>
|
||||
</data>
|
||||
<data name="Unknown" xml:space="preserve">
|
||||
<value>(Unknown)</value>
|
||||
</data>
|
||||
<data name="ArmFailureCommandException" xml:space="preserve">
|
||||
<value>There was a command exception while arming {0}. </value>
|
||||
</data>
|
||||
<data name="ArmFailureGeneralException" xml:space="preserve">
|
||||
<value>There was a general fault arming {0}.</value>
|
||||
</data>
|
||||
<data name="ArmInvalidSampleRate" xml:space="preserve">
|
||||
<value>Invalid sample rate for {0}.</value>
|
||||
</data>
|
||||
<data name="ArmSquibResistanceFault" xml:space="preserve">
|
||||
<value>{0} reported a squib resistance fault while arming.</value>
|
||||
</data>
|
||||
<data name="ArmTriggerShorted" xml:space="preserve">
|
||||
<value>{0} reported a shorted trigger while arming.</value>
|
||||
</data>
|
||||
<data name="UploadData_Files_Exist" xml:space="preserve">
|
||||
<value>Files in the following directory will be overwritten if you continue. Use OK to continue or cancel to abort.{1}{0}</value>
|
||||
</data>
|
||||
</root>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Analog output channel.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AnalogOutputDASChannel : OutputDASChannel
|
||||
{
|
||||
public AnalogOutputDASChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
}
|
||||
|
||||
public AnalogOutputDASChannel()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class TDASServiceSetupInfo
|
||||
{
|
||||
public string SetupDescription { get; set; }
|
||||
public double? SamplesPerSecond { get; set; }
|
||||
public float HardwareFilterRateHz { get; set; }
|
||||
public DFConstantsAndEnums.RecordingMode RecordingMode { get; set; }
|
||||
public bool? CheckoutMode { get; set; }
|
||||
|
||||
public TDASServiceSetupInfo(string setupDescription, double? samplesPerSecond, float hardwareFilterRateHz, DFConstantsAndEnums.RecordingMode recordingMode, bool? checkoutMode)
|
||||
{
|
||||
SetupDescription = setupDescription;
|
||||
SamplesPerSecond = samplesPerSecond;
|
||||
HardwareFilterRateHz = hardwareFilterRateHz;
|
||||
RecordingMode = recordingMode;
|
||||
CheckoutMode = checkoutMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
using DTS.Common.Constant.DASSpecific;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.DASLib.Command.SLICE.RealtimeCommands;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using static DTS.Common.Enums.DASFactory.DFConstantsAndEnums;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
#pragma warning disable S101 // Types should be named in PascalCase
|
||||
public class SLICE6AIRTC<T> : SLICE6_Base<T>, IAlignUDPToPPSAware, IDASReconfigure where T : IConnection, new()
|
||||
#pragma warning restore S101 // Types should be named in PascalCase
|
||||
{
|
||||
private const int MAX_TMATS_FILE_LENGTH = 32000;
|
||||
public override bool IsSlice6AirTc()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override int GetMaxFileLengthTMATS()
|
||||
{
|
||||
return MAX_TMATS_FILE_LENGTH;
|
||||
}
|
||||
public bool AlignUDPToPPS { get; set; }
|
||||
public override bool SupportsRemoveLeapSeconds => true;
|
||||
public override bool SupportsADCSamplesPerPacket => true;
|
||||
protected override bool RequiresNon0QualificationSamples => true;
|
||||
protected override byte[] GetRTChannelIndices(RealTimeAsyncPacket packet)
|
||||
{
|
||||
switch(_maxModuleCount)
|
||||
{
|
||||
case 0:
|
||||
return new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
|
||||
case 1:
|
||||
return new byte[] { 0, 1, 2, 3, 4, 5 ,6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||
case 2:
|
||||
default:
|
||||
return new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
|
||||
|
||||
}
|
||||
}
|
||||
protected override IGetRealtimeSamples GetRealtimeSamplesClass(DTS.Common.Interface.DASFactory.ICommunication iCommunication, bool bPolling = false)
|
||||
{
|
||||
if (IsCommandSupported(ProtocolLimitedCommands.StartRealtimeStream) && !bPolling)
|
||||
{
|
||||
return new RealtimeStreamingNextSamples(iCommunication) { SignedData = true };
|
||||
}
|
||||
return base.GetRealtimeSamplesClass(this, bPolling);
|
||||
}
|
||||
public override void SetIsStreamingSupported(bool supported = false)
|
||||
{
|
||||
IsStreamingSupported = true;
|
||||
}
|
||||
///// <summary>
|
||||
///// the order of this DAS among multiple das
|
||||
///// </summary>
|
||||
//public int DASIndex { get; set; } = -1;
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 6.0 Protocol Limitations
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArm] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmRepeatEnable] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDefaultMIF] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackSensors] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.TestCommunication] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackLowPowerMode] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetRealtimeSampleRate] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AttributeStoreBlocks] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MaxEvents] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmDiagnosticDelay] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackChannelAutoArmDiagLevel] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FlashClear] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleSamplesRealtime] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPTimestamp] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRecDelayInSecond] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRealtimeStream] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.UDPRealtimeStream] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.GenerateEvent] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPSyncStatus] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetClockSyncConfig] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDSPFilterSettings] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPDomainID] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.RemoveLeapSeconds] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.UDPAlignOnPPS] = SLICE6AIRTC.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ADCSamplesPerPacket] = SLICE6AIRTC.ADC_SAMPLES_PER_PACKET_VER;
|
||||
|
||||
MinimumProtocols = SLICE6AIR_TC_MinimumProtocols;
|
||||
}
|
||||
protected class S6ATCConfigAttributes : SLICE6ConfigAttributes
|
||||
{
|
||||
public override void ConfigureCoupling(bool[] IsACCoupledArray)
|
||||
{
|
||||
//not supported in S6ATC - so NOOP
|
||||
}
|
||||
public override void ConfigureBridge(byte[] bridgeModeArray)
|
||||
{
|
||||
//not supported in S6A-TC - so NOOP
|
||||
}
|
||||
public override void ConfigureBridgeResistance(ushort[] BridgeResistanceArray)
|
||||
{
|
||||
//not supported in S6A-TC - so NOOP
|
||||
}
|
||||
|
||||
public S6ATCConfigAttributes(ICommunication _com) : base(_com) { }
|
||||
}
|
||||
|
||||
protected override ConfigAttributes GetConfigAttributes(ICommunication com)
|
||||
{
|
||||
return new S6ATCConfigAttributes(this);
|
||||
}
|
||||
#region protocol settings/overrides
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> SLICE6AIR_TC_MinimumProtocols =
|
||||
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
protected override int MIN_PROTOCOL_TMATS_INTERVAL => SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
private uint maxSampleRateHz = 0;
|
||||
protected override uint MaxSampleRateHz
|
||||
{
|
||||
get
|
||||
{
|
||||
if (0 == maxSampleRateHz)
|
||||
{
|
||||
try
|
||||
{
|
||||
var qsa = new QuerySystemAttributeSLICE6(this)
|
||||
{
|
||||
Key = AttributeTypes.SystemAttributesSLICE6.MaximumSampleRate
|
||||
};
|
||||
qsa.SyncExecute();
|
||||
maxSampleRateHz = (uint)qsa.Value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Error getting S6A-BR max sample rate, returning 50K");
|
||||
APILogger.LogException(ex);
|
||||
return 50000;
|
||||
}
|
||||
}
|
||||
return maxSampleRateHz;
|
||||
}
|
||||
}
|
||||
void IDASReconfigure.SetMaxModuleCount(int count)
|
||||
{
|
||||
SetMaxModuleCount(count, false);
|
||||
_maxModuleCount = count;
|
||||
}
|
||||
private int _maxModuleCount = -1;
|
||||
/// <summary>
|
||||
/// gets the physical max number of modules.
|
||||
/// this value is cached
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
int IDASReconfigure.GetMaxModuleCount()
|
||||
{
|
||||
_maxModuleCount = GetMaxModuleCount(_maxModuleCount);
|
||||
return _maxModuleCount;
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected override DASModule MakeConfigModuleFromInfoModule(InfoResult.Module infoModule)
|
||||
{
|
||||
var configModule = new DASModule(infoModule.ModuleArrayIndex, this);
|
||||
configModule.Channels = new DASChannel[infoModule.NumberOfChannels];
|
||||
|
||||
for (var i = 0; i < infoModule.NumberOfChannels; i++)
|
||||
{
|
||||
if (DFConstantsAndEnums.ModuleType.StreamOut == configModule.ModuleType())
|
||||
{
|
||||
var streamOutChannel = new StreamOutputDASChannel(configModule, i);
|
||||
configModule.Channels[i] = streamOutChannel;
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = new AnalogInputDASChannel(configModule, i);
|
||||
|
||||
channel.SupportedBridges = new SensorConstants.BridgeType[]
|
||||
{
|
||||
SensorConstants.BridgeType.FullBridge,
|
||||
SensorConstants.BridgeType.HalfBridge,
|
||||
};
|
||||
configModule.Channels[i] = channel;
|
||||
}
|
||||
}
|
||||
|
||||
return configModule;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// we can probably simplify and take common items (slice6+slice1) out of this function, but for now
|
||||
/// it's mostly a copy of SLICE1.AsyncConfigure
|
||||
/// </summary>
|
||||
/// <param name="configAsyncInfo"></param>
|
||||
protected override void AsyncConfigure(object configAsyncInfo)
|
||||
{
|
||||
var info = configAsyncInfo as SliceConfigServiceAsyncInfo;
|
||||
SetUDPAlignOnPPS();
|
||||
SetRemoveSeconds();
|
||||
SetADCSamplesPerPacket(info.StreamADCPerPacket[this]);
|
||||
|
||||
//12638 DAS does not record data in recorder mode during calibration ~ 40% of time.
|
||||
//for SLICE6 we call reseteventlist here, prior to configuring and NOT before arming
|
||||
ResetEventListPriorToConfigure();
|
||||
|
||||
int progressValue = 0;
|
||||
bool bReleased = true;
|
||||
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.ProgramStackChannels))
|
||||
{
|
||||
ReconfigureAccordingToConfig();
|
||||
}
|
||||
|
||||
PresetSampleRate();
|
||||
|
||||
SetVoltageRequirements();
|
||||
|
||||
SetPolarity();
|
||||
|
||||
SetArmDisableShortCheck();
|
||||
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
bReleased = false;
|
||||
// loop thru the modules (slices) and configure the non-UART channels
|
||||
var numChannels = DASInfo.Modules.Sum(mod => mod.NumberOfChannels);
|
||||
var numStreamingChannels = DASInfo.Modules.Sum(mod => DFConstantsAndEnums.ModuleType.StreamOut == mod.TypeOfModule ? mod.NumberOfChannels : 0);
|
||||
var rangeArray = new float[numChannels];
|
||||
//var IsHalfBridgeArray = new bool[numChannels];
|
||||
var bridgeModeArray = new byte[numChannels];
|
||||
var BridgeResistanceArray = new ushort[numChannels];
|
||||
var IsACCoupledArray = new bool[numChannels];
|
||||
//18294 Implement Bridge AC / DC coupling(fw update dependent)
|
||||
var bridgeACCouplingArray = new bool[numChannels];
|
||||
// level trigger values
|
||||
var enableLowerLevelTriggerThreshold = new bool[numChannels];
|
||||
var enableUpperLevelTriggerThreshold = new bool[numChannels];
|
||||
var lowerLevelTriggerThreshold = new float[numChannels];
|
||||
var upperLevelTriggerThreshold = new float[numChannels];
|
||||
var qualificationSamples = new int[numChannels];
|
||||
|
||||
var diagnosticChannels = new List<byte>();
|
||||
|
||||
var bModified = false;
|
||||
CommonConfigureWork(diagnosticChannels, qualificationSamples, ref bReleased,
|
||||
info, bridgeModeArray, IsACCoupledArray, BridgeResistanceArray,
|
||||
ref bModified, rangeArray, enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold,
|
||||
enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold, bridgeACCouplingArray);
|
||||
if (bReleased) { return; }
|
||||
// report progress
|
||||
progressValue = 5;
|
||||
info.Progress(progressValue);
|
||||
|
||||
StoreConfigAttributes(info, rangeArray, ref bReleased, ref progressValue, bridgeModeArray,
|
||||
IsACCoupledArray, BridgeResistanceArray, enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold,
|
||||
enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold, qualificationSamples, numChannels,
|
||||
out var config, bridgeACCouplingArray, 0, numStreamingChannels);
|
||||
|
||||
progressValue = 20;
|
||||
info.Progress(progressValue);
|
||||
|
||||
RemainingConfigWork(ref progressValue, info, diagnosticChannels, config, ref bReleased, null, null, null);
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Cancel();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Error(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
info.Progress(100);
|
||||
info.Success();
|
||||
}
|
||||
/// <summary>
|
||||
/// returns true if the device is known to be streaming
|
||||
/// does not query device, just returns a flag if it has been set
|
||||
/// </summary>
|
||||
public override bool GetIsStreaming()
|
||||
{
|
||||
if (null == DASArmStatus) { return false; }
|
||||
//18852 Cannot use Stop streaming / (Dis)Auto Arm button if one or more DAS is idle
|
||||
//can't rely on just having received invalid mode, QATS will still have a status of realtime
|
||||
//when streaming, so we'll use either for now.
|
||||
return DASArmStatus.ReceivedInvalidModeDuringSetup || DASArmStatus.IsInRealtime;
|
||||
}
|
||||
public override int[] GetStackChannelConfigTypes()
|
||||
{
|
||||
try
|
||||
{
|
||||
var queryChannelTypes = new QueryArmAttribute(this) { Key = AttributeTypes.ArmAndEventAttributes.StackChannelConfigType };
|
||||
queryChannelTypes.SyncExecute();
|
||||
|
||||
var list = new List<int>();
|
||||
if (queryChannelTypes.Value is byte[] bytes)
|
||||
{
|
||||
foreach (var channelType in bytes)
|
||||
{
|
||||
list.Add(channelType);
|
||||
}
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
return new int[] { 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// SLICE6DB3 is a limited version of SLICE6DB, it notably does not have ie1588/ptp support
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class SLICE6DB3<T> : SLICE6DB<T>
|
||||
where T : IConnection,
|
||||
new()
|
||||
{
|
||||
|
||||
|
||||
#region IClockSyncActions
|
||||
public override void SetClockSyncConfig(ServiceCallback callback, object userData, ClockSyncProfile profile)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData) { functionData = profile };
|
||||
info.Success();
|
||||
}
|
||||
|
||||
public override void GetClockSyncStatus(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
public override void SetPTPDomainID(ServiceCallback callback, object userData, byte domainID)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData) { functionData = domainID };
|
||||
info.Success();
|
||||
}
|
||||
|
||||
public override void GetPTPDomainID(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// represents a single poll of the h/w for data
|
||||
/// in G8 and older firmware there will probably be only one data point per channel
|
||||
/// per poll. Newer firmware should be capable of multiple datapoints per channel per request
|
||||
/// </summary>
|
||||
public class SampleData
|
||||
{
|
||||
public short[][] Data { get; set; }
|
||||
public ulong SampleNumber { get; set; }
|
||||
|
||||
public ulong TimeStamp { get; set; }
|
||||
|
||||
public ulong SequenceNumber { get; set; }
|
||||
|
||||
public SampleData(short[][] data, ulong sampleNumber, ulong timeStamp, ulong sequenceNumber)
|
||||
{
|
||||
Data = data;
|
||||
SampleNumber = sampleNumber;
|
||||
TimeStamp = timeStamp;
|
||||
SequenceNumber = sequenceNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Threading;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class SLICEPowerProInputReader : SLICEBaseInputReader
|
||||
{
|
||||
private readonly ICommunication _comm;
|
||||
|
||||
public SLICEPowerProInputReader(ICommunication comm) : base(comm)
|
||||
{
|
||||
_comm = comm;
|
||||
}
|
||||
|
||||
public override double InputMilliVolts
|
||||
{
|
||||
get
|
||||
{
|
||||
var measure = new MeasurePowerProDiagnosticChannel(_comm);
|
||||
measure.Channel = MeasurePowerProDiagnosticChannel.PowerProDiagnosticChannelList.InputVoltage_A;
|
||||
measure.DeviceGroup = 0;
|
||||
measure.DeviceID = 0;
|
||||
measure.SyncExecute();
|
||||
return measure.Measurement * 1000.0;
|
||||
}
|
||||
}
|
||||
|
||||
public override double TemperatureC
|
||||
{
|
||||
get
|
||||
{
|
||||
var measure = new MeasurePowerProDiagnosticChannel(_comm);
|
||||
measure.Channel = MeasurePowerProDiagnosticChannel.PowerProDiagnosticChannelList.TemperatureC;
|
||||
measure.DeviceGroup = 0;
|
||||
measure.DeviceID = 0;
|
||||
measure.SyncExecute();
|
||||
return measure.Measurement;
|
||||
}
|
||||
}
|
||||
|
||||
public override double DirectBackupMilliVolts
|
||||
{
|
||||
get
|
||||
{
|
||||
var measure = new MeasurePowerProDiagnosticChannel(_comm);
|
||||
measure.Channel = MeasurePowerProDiagnosticChannel.PowerProDiagnosticChannelList.BatteryVoltage;
|
||||
measure.DeviceGroup = 0;
|
||||
measure.DeviceID = 0;
|
||||
measure.SyncExecute();
|
||||
return measure.Measurement * 1000.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class ArmCheckActions : IArmCheckActions
|
||||
{
|
||||
public bool PerformBatteryVoltageCheck { get; set; }
|
||||
public bool PerformInputVoltageCheck { get; set; }
|
||||
public bool PerformSensorIdCheck { get; set; }
|
||||
public bool PerformEventLineCheck { get; set; }
|
||||
public bool PerformSquibResistanceCheck { get; set; }
|
||||
public bool PerformTiltSensorCheck { get; set; }
|
||||
public bool PerformTemperatureCheck { get; set; }
|
||||
public bool PerformClockSyncCheck { get; set; }
|
||||
|
||||
public ArmCheckActions()
|
||||
{
|
||||
PerformBatteryVoltageCheck = false;
|
||||
PerformInputVoltageCheck = false;
|
||||
PerformSensorIdCheck = false;
|
||||
PerformEventLineCheck = false;
|
||||
PerformSquibResistanceCheck = false;
|
||||
PerformTiltSensorCheck = false;
|
||||
PerformTemperatureCheck = false;
|
||||
PerformClockSyncCheck = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using DTS.Common.Enums;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
internal interface IRealTimeActions
|
||||
{
|
||||
/// <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 realtime on, added for
|
||||
/// 10572 implement SW side for single command streaming realtime
|
||||
/// </param>
|
||||
void RealTime(int samplesPerSec,
|
||||
int msBetweenSamples,
|
||||
ServiceCallback callback,
|
||||
object userData,
|
||||
bool allowMultipleSampleRealtime,
|
||||
int moduleIndex,
|
||||
ManualResetEvent stopEvent,
|
||||
byte[] channels,
|
||||
double aaf,
|
||||
int minCallbackUpdateTimeMs = 100,
|
||||
bool UseUDPStreaming = false,
|
||||
string HostIPAddress = "");
|
||||
|
||||
/// <summary>
|
||||
/// conduct realtime by actively polling them for sample averages
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
/// <param name="userData"></param>
|
||||
/// <param name="stopEvent"></param>
|
||||
/// <param name="channels">
|
||||
/// channels to operate realtime on, added for
|
||||
/// 10572 implement SW side for single command streaming realtime
|
||||
/// </param>
|
||||
void RealTimePolling(ServiceCallback callback,
|
||||
object userData,
|
||||
ManualResetEvent stopEvent,
|
||||
byte[] channels);
|
||||
|
||||
/// <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 ExitRealTimeMode(ServiceCallback callback, object userData);
|
||||
|
||||
void RealTimeTiltPolling(ServiceCallback callback,
|
||||
object userData,
|
||||
ManualResetEvent stopEvent);
|
||||
|
||||
/// <summary>
|
||||
/// FB15313 Configure S6A udp streaming
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
/// <param name="streamProfile">The profile to set</param>
|
||||
/// <param name="udpAddress">UDP streaming address</param>
|
||||
/// <param name="timeChannelId">The time channel id to set</param>
|
||||
/// <param name="dataChannelId">The data channel id to set</param>
|
||||
/// <param name="tmnsConfig">TMNS format information</param>
|
||||
void SetUDPStreamProfile(ServiceCallback callback,
|
||||
object userData,
|
||||
UDPStreamProfile streamProfile,
|
||||
string udpAddress,
|
||||
ushort timeChannelId,
|
||||
ushort dataChannelId,
|
||||
uint[] tmnsConfig,
|
||||
ushort irigTimeDataPacketIntervalMs);
|
||||
|
||||
void GetUDPStreamProfile(ServiceCallback callback, object userData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Base class for SQUIB channels.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class OutputSquibChannel : AnalogOutputDASChannel, IComparable
|
||||
{
|
||||
public SquibFireMode[] SupportedSquibFireModes { get; set; } = { SquibFireMode.AC, SquibFireMode.CAP, SquibFireMode.CONSTANT, SquibFireMode.NONE };
|
||||
public IDiagnosticResult Diagnostics
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
IDiagnosticResult[] allChannelDiagnostics;
|
||||
IEnumerable<IDiagnosticResult> theseChannelDiagnostics;
|
||||
if (null == (allChannelDiagnostics = OwningModule.OwningDAS.ChannelDiagnosticsResults))
|
||||
throw new InvalidDataException("No diagnostics available (for any channel)");
|
||||
if (null == (theseChannelDiagnostics = (allChannelDiagnostics.Where(r => r.DASChannelNumber == Number))))
|
||||
throw new NullReferenceException("No diagnostics available (for this channel)");
|
||||
if (theseChannelDiagnostics.Count() > 1)
|
||||
throw new InvalidDataException("Several diagnostics results were found for the specified channel; only one was expected");
|
||||
if (theseChannelDiagnostics.Count() < 1)
|
||||
{
|
||||
throw new NullReferenceException("No diagnostics available (for this channel)");
|
||||
}
|
||||
return theseChannelDiagnostics.First();
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ApplicationException("encountered problem getting diagnostics for channel ", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SquibDescription.Trim()))
|
||||
return SquibDescription.Trim();
|
||||
return base.ToString();
|
||||
}
|
||||
int IComparable.CompareTo(object o)
|
||||
{
|
||||
if (null == o) { return 1; }
|
||||
if (o is OutputSquibChannel)
|
||||
{
|
||||
return SquibDescription.CompareTo((o as OutputSquibChannel).SquibDescription);
|
||||
}
|
||||
return SquibDescription.CompareTo(o.ToString());
|
||||
}
|
||||
|
||||
public SquibFireMode FireMode { get; set; } = SquibFireMode.NONE;
|
||||
|
||||
public SquibMeasurementType MeasurementType { get; set; } = SquibMeasurementType.NONE;
|
||||
|
||||
public bool BypassCurrentFilter { get; set; } = false;
|
||||
|
||||
public bool BypassVoltageFilter { get; set; } = false;
|
||||
|
||||
public double SquibToleranceLow { get; set; } = 0D;
|
||||
|
||||
public double SquibToleranceHigh { get; set; } = 0D;
|
||||
|
||||
public double SquibOutputCurrent { get; set; } = 0D;
|
||||
|
||||
public double SquibMeasuredOhms { get; set; } = 0D;
|
||||
|
||||
public bool SquibFiredValid { get; set; } = false;
|
||||
|
||||
public bool SquibFiredPassed { get; set; } = false;
|
||||
|
||||
public double DelayMS { get; set; } = 0D;
|
||||
|
||||
public double DurationMS { get; set; } = 0D;
|
||||
|
||||
public string SquibDescription { get; set; } = "";
|
||||
|
||||
public string ISOCode { get; set; } = "";
|
||||
|
||||
public string ChannelId { get; set; }
|
||||
|
||||
public string ChannelName2 { get; set; }
|
||||
|
||||
public string HardwareChannelName { get; set; }
|
||||
|
||||
public bool LimitDuration { get; set; }
|
||||
|
||||
public short PreTestDataZeroLevelADC { get; set; }
|
||||
|
||||
public double ScaleFactorMv { get; set; } = 0D;
|
||||
|
||||
public bool LocalOnly { get; set; } = false;
|
||||
|
||||
public string LastModifiedBy { get; set; }
|
||||
public string Sensor { get; set; }
|
||||
|
||||
public string SerialNumber { get; set; } = "";
|
||||
/// <summary>
|
||||
/// controls the frequency of software filters for squib channels
|
||||
/// 8747 - TDC by default will filter at 1650hz
|
||||
/// </summary>
|
||||
public double SoftwareFilterFrequency { get; set; }
|
||||
public OutputSquibChannel(XmlReader reader)
|
||||
{
|
||||
SupportedSquibFireModes = new[] { SquibFireMode.AC, SquibFireMode.CAP, SquibFireMode.CONSTANT, SquibFireMode.NONE };
|
||||
IDs = new[] { new EID() };
|
||||
ReadXml(reader);
|
||||
}
|
||||
public OutputSquibChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
SupportedSquibFireModes = new[] { SquibFireMode.AC, SquibFireMode.CAP, SquibFireMode.CONSTANT, SquibFireMode.NONE };
|
||||
IDs = new[] { new EID() };
|
||||
}
|
||||
|
||||
public OutputSquibChannel()
|
||||
{
|
||||
SupportedSquibFireModes = new[] { SquibFireMode.AC, SquibFireMode.CAP, SquibFireMode.CONSTANT, SquibFireMode.NONE };
|
||||
IDs = new[] { new EID() };
|
||||
}
|
||||
public override void WriteXmlCRC32(XmlWriter writer)
|
||||
{
|
||||
base.WriteXmlCRC32(writer);
|
||||
|
||||
XMLHelper.PutBool(writer, "BypassCurrentFilter", BypassCurrentFilter);
|
||||
XMLHelper.PutBool(writer, "BypassVoltageFilter", BypassVoltageFilter);
|
||||
XMLHelper.PutDouble(writer, "DelayMS", DelayMS);
|
||||
XMLHelper.PutDouble(writer, "DurationMS", DurationMS);
|
||||
XMLHelper.PutString(writer, "FireMode", FireMode.ToString());
|
||||
XMLHelper.PutString(writer, "ISOCode", ISOCode);
|
||||
XMLHelper.PutString(writer, "MeasurementType", MeasurementType.ToString());
|
||||
XMLHelper.PutString(writer, "SquibDescription", SquibDescription);
|
||||
XMLHelper.PutString(writer, "ChannelName2", ChannelName2);
|
||||
XMLHelper.PutString(writer, "ChannelId", ChannelId);
|
||||
XMLHelper.PutString(writer, "ChannelGroupName", ChannelGroupName);
|
||||
XMLHelper.PutString(writer, "HardwareChannelName", HardwareChannelName);
|
||||
XMLHelper.PutDouble(writer, "SquibOutputCurrent", SquibOutputCurrent);
|
||||
XMLHelper.PutDouble(writer, "SquibToleranceHigh", SquibToleranceHigh);
|
||||
XMLHelper.PutDouble(writer, "SquibToleranceLow", SquibToleranceLow);
|
||||
XMLHelper.PutBool(writer, "LimitDuration", LimitDuration);
|
||||
XMLHelper.PutString(writer, "ArticleId", "");
|
||||
|
||||
XMLHelper.PutString(writer, "SupportedSquibFireModes", GetSerializedSupportedSquibFireModes());
|
||||
XMLHelper.PutDouble(writer, "SoftwareFilterFrequency", SoftwareFilterFrequency);
|
||||
XMLHelper.PutString(writer, "Sensor", Sensor);
|
||||
}
|
||||
private readonly string _SEPARATOR = "@";
|
||||
public override void WriteXml(XmlWriter writer)
|
||||
{
|
||||
base.WriteXml(writer);
|
||||
|
||||
XMLHelper.PutBool(writer, "BypassCurrentFilter", BypassCurrentFilter);
|
||||
XMLHelper.PutBool(writer, "BypassVoltageFilter", BypassVoltageFilter);
|
||||
XMLHelper.PutDouble(writer, "DelayMS", DelayMS);
|
||||
XMLHelper.PutDouble(writer, "DurationMS", DurationMS);
|
||||
XMLHelper.PutString(writer, "FireMode", FireMode.ToString());
|
||||
XMLHelper.PutString(writer, "ISOCode", ISOCode);
|
||||
XMLHelper.PutString(writer, "MeasurementType", MeasurementType.ToString());
|
||||
XMLHelper.PutString(writer, "SquibDescription", SquibDescription);
|
||||
XMLHelper.PutString(writer, "ChannelName2", ChannelName2);
|
||||
XMLHelper.PutString(writer, "ChannelId", ChannelId);
|
||||
XMLHelper.PutString(writer, "ChannelGroupName", ChannelGroupName);
|
||||
XMLHelper.PutString(writer, "HardwareChannelName", HardwareChannelName);
|
||||
XMLHelper.PutBool(writer, "SquibFirePassed", SquibFiredPassed);
|
||||
XMLHelper.PutBool(writer, "SquibFireValid", SquibFiredValid);
|
||||
XMLHelper.PutDouble(writer, "SquibOhms", SquibMeasuredOhms);
|
||||
XMLHelper.PutDouble(writer, "SquibOutputCurrent", SquibOutputCurrent);
|
||||
XMLHelper.PutDouble(writer, "SquibToleranceHigh", SquibToleranceHigh);
|
||||
XMLHelper.PutDouble(writer, "SquibToleranceLow", SquibToleranceLow);
|
||||
XMLHelper.PutBool(writer, "LimitDuration", LimitDuration);
|
||||
XMLHelper.PutDouble(writer, "ScaleFactorMv", ScaleFactorMv);
|
||||
XMLHelper.PutInt(writer, "PreTestDataZeroLevelADC", PreTestDataZeroLevelADC);
|
||||
XMLHelper.PutString(writer, "ArticleId", "");
|
||||
XMLHelper.PutString(writer, "SupportedSquibFireModes", GetSerializedSupportedSquibFireModes());
|
||||
XMLHelper.PutDouble(writer, "SoftwareFilterFrequency", SoftwareFilterFrequency);
|
||||
XMLHelper.PutString(writer, "Sensor", Sensor);
|
||||
XMLHelper.PutString(writer, "SerialNumber", SerialNumber);
|
||||
}
|
||||
|
||||
public int Version { get; set; }
|
||||
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
public string GetSerializedSupportedSquibFireModes()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var s in SupportedSquibFireModes)
|
||||
{
|
||||
if (sb.Length > 0) { sb.Append(_SEPARATOR); }
|
||||
sb.Append(s);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private SquibFireMode[] DeserializeSquibFireModes(string s)
|
||||
{
|
||||
var modes = new List<SquibFireMode>();
|
||||
var tokens = s.Split(new[] { _SEPARATOR }, StringSplitOptions.None);
|
||||
foreach (var token in tokens)
|
||||
{
|
||||
if (Enum.TryParse(token, out SquibFireMode mode)) { modes.Add(mode); }
|
||||
}
|
||||
return modes.ToArray();
|
||||
}
|
||||
|
||||
private const string BYPASSCURRENTFILTER_TAG = "BypassCurrentFilter";
|
||||
private const string BYPASSVOLTAGEFILTER_TAG = "BypassVoltageFilter";
|
||||
private const string DELAYMS_TAG = "DelayMS";
|
||||
private const string DURATIONMS_TAG = "DurationMS";
|
||||
private const string FIREMODE_TAG = "FireMode";
|
||||
private const string ISOCODE_TAG = "ISOCode";
|
||||
private const string MEASUREMENTTYPE_TAG = "MeasurementType";
|
||||
private const string SQUIBDESCRIPTION_TAG = "SquibDescription";
|
||||
private const string CHANNELID_TAG = "ChannelId";
|
||||
private const string CHANNELGROUPNAME_TAG = "ChannelGroupName";
|
||||
private const string CHANNELNAME2_TAG = "ChannelName2";
|
||||
private const string HARDWARECHANNELNAME_TAG = "HardwareChannelName";
|
||||
private const string SQUIBFIREPASSED_TAG = "SquibFirePassed";
|
||||
private const string SQUIBFIREVALID_TAG = "SquibFireValid";
|
||||
private const string SQUIBOHMS_TAG = "SquibOhms";
|
||||
private const string SQUIBOUTPUTCURRENT_TAG = "SquibOutputCurrent";
|
||||
private const string SQUIBTOLERANCEHIGH_TAG = "SquibToleranceHigh";
|
||||
private const string SQUIBTOLERANCELOW_TAG = "SquibToleranceLow";
|
||||
private const string LIMITDURATION_TAG = "LimitDuration";
|
||||
private const string SCALEFACTORMV_TAG = "ScaleFactorMv";
|
||||
private const string PRETESTDATAZEROLEVELADC_TAG = "PreTestDataZeroLevelADC";
|
||||
private const string ARTICLEID_TAG = "ArticleId";
|
||||
private const string SUPPORTEDSQUIBFIREMODES_TAG = "SupportedSquibFireModes";
|
||||
private const string SOFTWAREFILTERHZ_TAG = "SoftwareFilterFrequency";
|
||||
private const string SENSOR_TAG = "Sensor";
|
||||
private const string SERIALNUMBER_TAG = "SerialNumber";
|
||||
protected override void HandleElement(XmlReader reader)
|
||||
{
|
||||
base.HandleElement(reader);
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case BYPASSCURRENTFILTER_TAG:
|
||||
BypassCurrentFilter = XMLHelper.GetBool(reader);
|
||||
break;
|
||||
case BYPASSVOLTAGEFILTER_TAG:
|
||||
BypassVoltageFilter = XMLHelper.GetBool(reader);
|
||||
break;
|
||||
case DELAYMS_TAG:
|
||||
DelayMS = XMLHelper.GetDouble(reader);
|
||||
break;
|
||||
case DURATIONMS_TAG:
|
||||
DurationMS = XMLHelper.GetDouble(reader);
|
||||
break;
|
||||
case FIREMODE_TAG:
|
||||
String mode = XMLHelper.GetString(reader);
|
||||
try
|
||||
{
|
||||
FireMode = (SquibFireMode)Enum.Parse(typeof(SquibFireMode), mode);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to load firemode ", mode, ex); }
|
||||
break;
|
||||
case ISOCODE_TAG:
|
||||
ISOCode = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case MEASUREMENTTYPE_TAG:
|
||||
string measurementType = XMLHelper.GetString(reader);
|
||||
try
|
||||
{
|
||||
MeasurementType = (SquibMeasurementType)Enum.Parse(typeof(SquibMeasurementType), measurementType);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to load MeasurementType ", measurementType, ex); }
|
||||
break;
|
||||
case SQUIBDESCRIPTION_TAG:
|
||||
SquibDescription = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case CHANNELID_TAG:
|
||||
ChannelId = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case SENSOR_TAG:
|
||||
Sensor = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case SERIALNUMBER_TAG:
|
||||
SerialNumber = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case CHANNELGROUPNAME_TAG:
|
||||
ChannelGroupName = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case CHANNELNAME2_TAG:
|
||||
ChannelName2 = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case HARDWARECHANNELNAME_TAG:
|
||||
HardwareChannelName = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case SQUIBFIREPASSED_TAG:
|
||||
SquibFiredPassed = XMLHelper.GetBool(reader);
|
||||
break;
|
||||
case SQUIBFIREVALID_TAG:
|
||||
SquibFiredValid = XMLHelper.GetBool(reader);
|
||||
break;
|
||||
case SQUIBOHMS_TAG:
|
||||
SquibMeasuredOhms = XMLHelper.GetDouble(reader);
|
||||
break;
|
||||
case SQUIBOUTPUTCURRENT_TAG:
|
||||
SquibOutputCurrent = XMLHelper.GetDouble(reader);
|
||||
break;
|
||||
case SQUIBTOLERANCEHIGH_TAG:
|
||||
SquibToleranceHigh = XMLHelper.GetDouble(reader);
|
||||
break;
|
||||
case SQUIBTOLERANCELOW_TAG:
|
||||
SquibToleranceLow = XMLHelper.GetDouble(reader);
|
||||
break;
|
||||
case LIMITDURATION_TAG:
|
||||
LimitDuration = XMLHelper.GetBool(reader);
|
||||
break;
|
||||
case SCALEFACTORMV_TAG:
|
||||
ScaleFactorMv = XMLHelper.GetDouble(reader);
|
||||
break;
|
||||
case PRETESTDATAZEROLEVELADC_TAG:
|
||||
PreTestDataZeroLevelADC = Convert.ToInt16(XMLHelper.GetInt(reader));
|
||||
break;
|
||||
case ARTICLEID_TAG:
|
||||
//2021-05-21 - why aren't we using this id? -DTM
|
||||
_ = XMLHelper.GetString(reader);
|
||||
IDs = new EID[] { new EID() };
|
||||
break;
|
||||
case SUPPORTEDSQUIBFIREMODES_TAG:
|
||||
string s = XMLHelper.GetString(reader);
|
||||
SupportedSquibFireModes = DeserializeSquibFireModes(s);
|
||||
break;
|
||||
case SOFTWAREFILTERHZ_TAG:
|
||||
var freq = XMLHelper.GetOptionalDouble(reader);
|
||||
if (null != freq) { SoftwareFilterFrequency = (double)freq; }
|
||||
break;
|
||||
default:
|
||||
// let child handle it
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public override bool IsConfigured()
|
||||
{
|
||||
return FireMode != SquibFireMode.NONE && !string.IsNullOrEmpty(SquibDescription);
|
||||
}
|
||||
|
||||
public const double DEFAULT_MIN_FIRE_DURATION_MS = 0.20; // FB 5439; don't allow user to set below min duration
|
||||
public const double DEFAULT_MIN_FIRE_DELAY_MS = 0.0D; // FB 5827 Saving squibs with invalid delay settings
|
||||
public const double DEFAULT_DEFINEINTEST_FIRE_DELAY_FLAG = -1; // FB 14623 A flag which specifies the Delay has to be defined in the test setup, also when updating please update the -1 check for SquibDelay in EditSquibControl
|
||||
public const double DEFAULT_MAX_FIRE_DURATION_MS = 25.5D; //stole it out of the UI in datapro
|
||||
public const double DEFAULT_MAX_FIRE_DELAY_MS = 99000D; //also stolen
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.Communication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.DASLib.Service.Interfaces;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class SLICEPRODB<T> : SLICE6DB<T>,
|
||||
IDownloadActions
|
||||
where T : IConnection,
|
||||
new()
|
||||
{
|
||||
/// <summary>
|
||||
/// populates the connected devices field
|
||||
/// </summary>
|
||||
public override void QueryConnectedDevices()
|
||||
{
|
||||
//no functionality for this with SLICEPRO DB
|
||||
var connectedDevices = new List<IDASConnectedDevice>();
|
||||
((ICommunication)this).DASInfo.SetConnectedDevices(connectedDevices.ToArray());
|
||||
}
|
||||
|
||||
public override bool IsSlice6Distributor()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsBattery()
|
||||
{
|
||||
//um maybe?
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void AsyncQueryConfiguration(object configAsyncInfo)
|
||||
{
|
||||
var info = (SliceServiceAsyncInfo)configAsyncInfo;
|
||||
|
||||
InitMinProto(); _haveInited = true;
|
||||
ConfigData = MakeDefaultConfigFromInfo();
|
||||
info.Success();
|
||||
}
|
||||
|
||||
protected override bool SupportsTemperatureCheck => true;
|
||||
protected override bool SupportsTiltCheck => true;
|
||||
protected override bool SupportsClockSyncCheck => true;
|
||||
public override bool SupportsTimeSynchronization => false;
|
||||
|
||||
private const int MIN_PROTOCOL_VER = 1;
|
||||
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> SLICEPRODB_MinProtocols =
|
||||
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 6 DB Protocol Limitations
|
||||
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MeasureBaseDiagnosticChannel] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InSliceTemperatureCPre] = byte.MaxValue;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = MIN_PROTOCOL_VER;
|
||||
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPSyncStatus] = byte.MaxValue;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetClockSyncConfig] = byte.MaxValue;
|
||||
|
||||
// SLICE_DB Protocol Limitations
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.Arm] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EnableFaultChecking] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.OnOverride] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.OMAP_GPIO] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryBatteryVoltage] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRealtimeStream] = MIN_PROTOCOL_VER;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryEthernetMacTable] = byte.MaxValue;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryTempLogFile] = byte.MaxValue;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryTiltSensorData] = byte.MaxValue;
|
||||
SLICEPRODB_MinProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryExternalTiltInfo] = byte.MaxValue;
|
||||
MinimumProtocols = SLICEPRODB_MinProtocols;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,325 @@
|
||||
|
||||
using DASFactoryDb.Download;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Interface.DASFactory.Download;
|
||||
using DTS.Common.Interface.DownloadEvent;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Data.SqlTypes;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This class represent all events stored on the DAS. It is populated during
|
||||
/// <see cref="DownloadService.QueryDownload" />.
|
||||
/// </summary>
|
||||
public class DownloadReport : IDownloadReport
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represent one event/test.
|
||||
/// </summary>
|
||||
public class EventInfo : IEventInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Information about each module that was part of the event. Addressable by
|
||||
/// ModuleArrayIndex of the corresponding module.
|
||||
/// </summary>
|
||||
public IDASModule[] Modules { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The event number this information is regarding.
|
||||
/// </summary>
|
||||
public int EventNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The GUID of the corresponding event.
|
||||
/// </summary>
|
||||
public Guid TestGUID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fault flags (if any)
|
||||
/// </summary>
|
||||
public ushort FaultFlags { get; set; }
|
||||
/// <summary>
|
||||
/// fault flags extended (if any)
|
||||
/// </summary>
|
||||
public ushort FaultFlagsEx { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Arm Attempts (if any)
|
||||
/// </summary>
|
||||
public byte ArmAttempts { get; set; }
|
||||
/// <summary>
|
||||
/// The timestamp of this event.
|
||||
/// </summary>
|
||||
public DateTime TestTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of this event.
|
||||
/// </summary>
|
||||
public string TestID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A text description that was stored.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if this event has already been downloaded.
|
||||
/// </summary>
|
||||
public bool HasBeenDownloaded { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if this event received a trigger.
|
||||
/// </summary>
|
||||
public bool WasTriggered { get; set; }
|
||||
/// <summary>
|
||||
/// clears any fault flags
|
||||
/// </summary>
|
||||
public void ClearFaults()
|
||||
{
|
||||
FaultFlags = 0;
|
||||
FaultFlagsEx = 0;
|
||||
}
|
||||
public EventInfo() { }
|
||||
public EventInfo(EventInfo copy)
|
||||
{
|
||||
Modules = copy.Modules;
|
||||
|
||||
EventNumber = copy.EventNumber;
|
||||
|
||||
TestGUID = copy.TestGUID;
|
||||
|
||||
FaultFlags = copy.FaultFlags;
|
||||
FaultFlagsEx = copy.FaultFlagsEx;
|
||||
|
||||
ArmAttempts = copy.ArmAttempts;
|
||||
TestTime = copy.TestTime;
|
||||
|
||||
TestID = copy.TestID;
|
||||
|
||||
Description = copy.Description;
|
||||
|
||||
HasBeenDownloaded = copy.HasBeenDownloaded;
|
||||
|
||||
WasTriggered = copy.WasTriggered;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class represent one event/test.
|
||||
/// </summary>
|
||||
public class UARTEventInfo : IUARTEventInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// From which event do we want to download data?
|
||||
/// </summary>
|
||||
public ushort EventNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is data present?
|
||||
/// </summary>
|
||||
public bool DataPresent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Has data already been downloaded?
|
||||
/// </summary>
|
||||
public bool DataDownloaded { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How much data is there?
|
||||
/// </summary>
|
||||
public ulong TotalByteCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Where in the data did the trigger occur?
|
||||
/// </summary>
|
||||
public ulong TriggerByteCount { get; set; }
|
||||
/// <summary>
|
||||
/// Where are the faults?
|
||||
/// </summary>
|
||||
public ulong FaultByteCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When did the UART stream start?
|
||||
/// </summary>
|
||||
public ulong StartTimestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When did the UART stream end?
|
||||
/// </summary>
|
||||
public ulong EndTimestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What was the baud rate during UART recording?
|
||||
/// </summary>
|
||||
public uint BaudRate { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An array of all events stored on this DAS.
|
||||
/// </summary>
|
||||
public IEventInfo[] Events { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An array of all UART events stored on this DAS.
|
||||
/// </summary>
|
||||
public IUARTEventInfo[] UARTEvents { get; set; }
|
||||
|
||||
public static void SetEventDownloadStatus(IDASCommunication das, bool[] status, bool bStoreInDb)
|
||||
{
|
||||
if (null == das) { return; }
|
||||
das.EventDownloadedStatus = status;
|
||||
if (!bStoreInDb || !DASFactoryDb.DbWrapper.Connected) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
Download.ClearExistingEventDownloadStatus(das.RecordId);
|
||||
if (null == status) { return; }
|
||||
foreach (var statum in status)
|
||||
{
|
||||
Download.InsertEventDownloadStatus(das.RecordId, statum);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
public static void SetEventArmAttempts(IDASCommunication das, byte[] armAttempts, bool storeInDb)
|
||||
{
|
||||
if (null == das) { return; }
|
||||
das.ArmAttempts = armAttempts;
|
||||
|
||||
if (!storeInDb || !DASFactoryDb.DbWrapper.Connected) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
Download.ClearExistingEventArmAttempts(das.RecordId);
|
||||
if (null == armAttempts) { return; }
|
||||
foreach (byte armAttempt in armAttempts)
|
||||
{
|
||||
Download.InsertEventArmAttempts(das.RecordId, armAttempt);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
public static void SetEventFaultFlags(IDASCommunication das, ushort[] faultFlags, bool storeInDb)
|
||||
{
|
||||
if (null == das) { return; }
|
||||
das.FaultFlags = faultFlags;
|
||||
if (!storeInDb || !DASFactoryDb.DbWrapper.Connected) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
Download.ClearExistingFaultFlags(das.RecordId);
|
||||
if (null == faultFlags) { return; }
|
||||
foreach (var flag in faultFlags)
|
||||
{
|
||||
Download.InsertEventFaultFlags(das.RecordId, flag);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetEventInfo(IDASCommunication das, IDownloadReport eventInfo, bool storeInDB)
|
||||
{
|
||||
if (null == das) { return; }
|
||||
das.EventInfo = eventInfo;
|
||||
if (!storeInDB || !DASFactoryDb.DbWrapper.Connected) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
Download.ClearExistingDownloadReports(das.RecordId);
|
||||
if (null == eventInfo || null == eventInfo.Events) { return; }
|
||||
foreach (var eventData in eventInfo.Events)
|
||||
{
|
||||
InsertEventInfo(das, eventData);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InsertEventInfo(IDASCommunication das, IEventInfo eventInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (null == eventInfo || null == das)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var xml = string.Empty;
|
||||
using (var sw = new StringWriter())
|
||||
{
|
||||
using (var xw = XmlWriter.Create(sw,
|
||||
new XmlWriterSettings() { ConformanceLevel = ConformanceLevel.Document }))
|
||||
{
|
||||
xw.WriteStartDocument();
|
||||
xw.WriteStartElement("Modules");
|
||||
foreach (var mod in eventInfo.Modules)
|
||||
{
|
||||
mod.WriteXml(xw);
|
||||
}
|
||||
|
||||
xw.WriteEndElement();
|
||||
xw.WriteEndDocument();
|
||||
}
|
||||
sw.Flush();
|
||||
xml = sw.ToString();
|
||||
}
|
||||
|
||||
Download.InsertEventInfo(das.RecordId,
|
||||
eventInfo.EventNumber,
|
||||
eventInfo.TestGUID,
|
||||
eventInfo.FaultFlags,
|
||||
eventInfo.ArmAttempts,
|
||||
eventInfo.TestTime,
|
||||
eventInfo.TestID,
|
||||
eventInfo.Description,
|
||||
eventInfo.HasBeenDownloaded,
|
||||
eventInfo.WasTriggered,
|
||||
xml
|
||||
);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
public static void SetEventGuids(IDASCommunication das, Guid[] guids, bool storeInDb)
|
||||
{
|
||||
if (null == das) { return; }
|
||||
das.EventGuids = guids;
|
||||
if (!storeInDb || !DASFactoryDb.DbWrapper.Connected) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
Download.ClearExistingEventGuids(das.RecordId);
|
||||
if (null == guids) { return; }
|
||||
foreach (var guid in guids)
|
||||
{
|
||||
Download.EventGuidInsert(das.RecordId, guid);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// allows a input range in mV to send to firmware based on a gain
|
||||
/// this is a right now just the middle between the given gain and the next gain, however
|
||||
/// we can control this a bit more in the future if we wish.
|
||||
/// we don't send directly the input range based on the gain because calibration factors could affect
|
||||
/// what range is actually achieved at each gain step
|
||||
/// but we want to make sure we don't change gain steps [so we can avoid certain gains]
|
||||
/// http://fogbugz/fogbugz/default.asp?10080
|
||||
/// </summary>
|
||||
public class FirmwareInputRangeAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// input range to send to firmware for the given gain
|
||||
/// http://fogbugz/fogbugz/default.asp?10080
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
/// <returns></returns>
|
||||
public static double GetFirmwareInputRangemV(object o)
|
||||
{
|
||||
if (o == null) return 0D;
|
||||
var mi = o.GetType().GetMember(o.ToString());
|
||||
if (mi.Length <= 0) return 0D;
|
||||
var attr = GetCustomAttribute(mi[0], typeof(FirmwareInputRangeAttribute)) as FirmwareInputRangeAttribute;
|
||||
return attr?._firmwareInputRangeAttribute ?? 0D;
|
||||
}
|
||||
|
||||
private readonly double _firmwareInputRangeAttribute;
|
||||
public FirmwareInputRangeAttribute(double firmwareInputRangemV)
|
||||
{
|
||||
_firmwareInputRangeAttribute = firmwareInputRangemV;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
internal interface ITimeActions
|
||||
{
|
||||
void Synchronize(ServiceCallback callback, object userData, DateTime time);
|
||||
void QueryTime(ServiceCallback callback, object userData);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,506 @@
|
||||
using DTS.Common;
|
||||
using DTS.Common.Behaviors;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Classes.TMAT;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace DTS.DASLib.Service.Classes
|
||||
{
|
||||
public interface ITmtFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes the TMT file to the device
|
||||
/// </summary>
|
||||
void WriteTmtFile(IDASCommunication das, Dictionary<IDASCommunication, ushort> dataChannelIds, Dictionary<IDASCommunication, ushort> timeChannelIds, Dictionary<IDASCommunication, ushort> uartChannelIds, int dasIndex, ICommunication communication, float[] scaleFactors = null, float[] ranges = null, float[] measuredOffset = null);
|
||||
}
|
||||
//FB 25526 This class encapsulates the methods used in SLICE6AIR.cs before to intract with TMT files, the subclasses can support multiple types need like SLICE6AIR & TSRAIR
|
||||
public abstract class TmtFile : ITmtFile
|
||||
{
|
||||
protected TmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults)
|
||||
{
|
||||
SerialNumber = serialNumber;
|
||||
DASInfo = dasInfo;
|
||||
ConfigData = configData;
|
||||
ChannelDiagnosticsResults = channelDiagnosticsResults;
|
||||
}
|
||||
|
||||
protected static ITMTTemplate GetTMTTemplate(TMAT_TEMPLATES tmat_TEMPLATES)
|
||||
{
|
||||
var tmtFileName = StringMetaDataAttr.GetStringMetaData(tmat_TEMPLATES);
|
||||
|
||||
var tokens = tmtFileName.Split(';');
|
||||
if ( tokens.Length == 2) { return GetSplitFile(tokens[0], tokens[1]); }
|
||||
|
||||
if (string.IsNullOrWhiteSpace(tmtFileName))
|
||||
{
|
||||
tmtFileName = "S6ATMTTemplate_PCM.tmt";
|
||||
}
|
||||
return GetTMTSingleFile(tmtFileName);
|
||||
}
|
||||
/// <summary>
|
||||
/// returns a single file template
|
||||
/// </summary>
|
||||
private static ITMTTemplate GetTMTSingleFile(string tmtFileName)
|
||||
{
|
||||
return new TmtSingleFile($"TMTTemplates/{tmtFileName}");
|
||||
}
|
||||
/// <summary>
|
||||
/// returns split file template
|
||||
/// </summary>
|
||||
private static ITMTTemplate GetSplitFile(string dasTemplate, string channelTemplate)
|
||||
{
|
||||
return new TmtSplitFile($"TMTTemplates/{dasTemplate}", $"TMTTemplates/{channelTemplate}");
|
||||
}
|
||||
|
||||
protected TMAT_TEMPLATES Template { get; set; }
|
||||
protected int MaxChannels { get; set; }
|
||||
protected string SerialNumber { get; set; }
|
||||
protected IInfoResult DASInfo { get; set; }
|
||||
protected IConfigurationData ConfigData { get; set; }
|
||||
protected IDiagnosticResult[] ChannelDiagnosticsResults { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// writes tmats file to the DASConfigs log directory, file is serial_TMT.txt
|
||||
/// </summary>
|
||||
protected static void WriteTMTFilePC(byte[] data, string testDirectory, string serialNumber)
|
||||
{
|
||||
const string dasConfigs = "DASConfigs";
|
||||
try
|
||||
{
|
||||
var fileName = Path.Combine(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), dasConfigs),
|
||||
$"{serialNumber}_TMT.txt");
|
||||
if (File.Exists(fileName)) { File.Delete(fileName); }
|
||||
File.WriteAllBytes(fileName, data);
|
||||
|
||||
//43789 Now, also write the file to the Data folder because the copy in the current directory gets overwritten every test
|
||||
fileName = Path.Combine(testDirectory);
|
||||
if (!Directory.Exists(fileName))
|
||||
{
|
||||
Directory.CreateDirectory(fileName);
|
||||
}
|
||||
fileName = Path.Combine(fileName, $"{serialNumber}_TMT.txt");
|
||||
File.WriteAllBytes(fileName, data);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
try
|
||||
{
|
||||
var fileName = Path.Combine(testDirectory, dasConfigs);
|
||||
if (!Directory.Exists(fileName))
|
||||
{
|
||||
Directory.CreateDirectory(fileName);
|
||||
}
|
||||
fileName = Path.Combine(fileName, $"{serialNumber}_TMT.txt");
|
||||
File.WriteAllBytes(fileName, data);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
}
|
||||
|
||||
private static bool DoesChannelStreamUnsigned(AnalogInputDASChannel aic)
|
||||
{
|
||||
if (null == aic) { return true; }
|
||||
if (null == aic.OwningModule) { return true; }
|
||||
if (null == aic.OwningModule.OwningDAS) { return true; }
|
||||
switch (aic.OwningModule.OwningDAS.GetHardwareType())
|
||||
{
|
||||
case Common.Enums.Hardware.HardwareTypes.TSR_AIR_RevB:
|
||||
case Common.Enums.Hardware.HardwareTypes.SLICE6_AIR_TC: return false;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
private static HashSet<HardwareTypes> _signedDAS = new HashSet<HardwareTypes>() { HardwareTypes.TSR_AIR, HardwareTypes.TSR_AIR_RevB, HardwareTypes.SLICE6_AIR_TC };
|
||||
private static bool GetIsSignedData(AnalogInputDASChannel aic)
|
||||
{
|
||||
if ( null == aic || null == aic.OwningModule || aic == aic.OwningModule.OwningDAS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var type = aic.OwningModule.OwningDAS.GetHardwareType();
|
||||
if (_signedDAS.Contains(type)) { return true; }
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// writes a channel to the template in memory
|
||||
/// </summary>
|
||||
protected void UpdateTMTChannel(ITMTTemplate template, int channelIndex, float[] scaleFactors = null, float[] ranges = null, float[] measuredOffset = null)
|
||||
{
|
||||
var channelKeys = Enum.GetValues(typeof(TMTChannelKeys)).Cast<TMTChannelKeys>()
|
||||
.ToArray();
|
||||
|
||||
var number = (1 + channelIndex).ToString();
|
||||
var moduleArrayIndex = DASInfo.MapDASChannelNumber2ModuleArrayIndex(channelIndex);
|
||||
var moduleChannelIndex = DASInfo.MapDASChannelNumber2ModuleChannelNumber(channelIndex);
|
||||
var aidc = ConfigData.Modules[moduleArrayIndex].Channels[moduleChannelIndex] as AnalogInputDASChannel;
|
||||
var diagnosticResult =
|
||||
(from dr in ChannelDiagnosticsResults where dr.DASChannelNumber == channelIndex select dr)
|
||||
.FirstOrDefault();
|
||||
//this was throwing an exception for SLICE-TC, but it doesn't really need a datascaler
|
||||
//as the scale factor is always 1, so just create a new default scaler
|
||||
//note that I fixed diagnostics which may have fixed the lack of scaler with thermo channels too
|
||||
DataScaler scaler = new DataScaler();
|
||||
try
|
||||
{
|
||||
scaler = aidc.GetDataScaler();
|
||||
}
|
||||
catch( Exception ex) { APILogger.Log(ex); }
|
||||
|
||||
var tempEU = scaler.GetEU(short.MinValue);
|
||||
var tempEU2 = scaler.GetEU(short.MaxValue);
|
||||
var minEU = Math.Min(tempEU, tempEU2);
|
||||
var maxEU = Math.Max(tempEU, tempEU2);
|
||||
var channelName2 = TmtBase.TMT_LimitString(aidc.ChannelName2);
|
||||
var eu = RunTestVariables.MaskEUMetaData ? "---" : aidc.EngineeringUnits?.Trim() ?? "";
|
||||
var offsetEU = GetOffsetEUString(aidc, scaler, measuredOffset, channelIndex, diagnosticResult);
|
||||
var keys2 = Enum.GetValues(typeof(TMTChannelKeysEx)).Cast<TMTChannelKeysEx>();
|
||||
var adcToEUScalingFactor = 1D;
|
||||
if (scaleFactors != null && !RunTestVariables.MaskEUMetaData)
|
||||
{
|
||||
adcToEUScalingFactor = scaleFactors[channelIndex];
|
||||
}
|
||||
else if (!RunTestVariables.MaskEUMetaData)
|
||||
{
|
||||
adcToEUScalingFactor = scaler.GetAdcToEuScalingFactor();
|
||||
}
|
||||
|
||||
var isSigned = GetIsSignedData(aidc);
|
||||
foreach ( var key2 in keys2)
|
||||
{
|
||||
TmtBase.UpdateChannelField(key2, template, channelIndex, ranges, minEU, maxEU,
|
||||
eu, scaleFactors, adcToEUScalingFactor, channelName2, offsetEU, isSigned);
|
||||
}
|
||||
|
||||
foreach (var key in channelKeys)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case TMTChannelKeys.HardwareChannelNumber:
|
||||
template.UpdateValue(key, number, 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.ChannelName:
|
||||
template.UpdateValue(key, channelName2, 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.CouplingMode:
|
||||
var couplingMode = "D";
|
||||
if (aidc.CouplingMode == SensorConstants.CouplingModes.AC && aidc.IEPEChannel)
|
||||
{
|
||||
couplingMode = "A";
|
||||
}
|
||||
template.UpdateValue(key, couplingMode, 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.BridgeResistance:
|
||||
if (null != diagnosticResult.BridgeResistance)
|
||||
{
|
||||
template.UpdateValue(key, ((double)diagnosticResult.BridgeResistance).ToString("F0"),
|
||||
1 + channelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.UpdateValue(key, "0", 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
case TMTChannelKeys.AAF:
|
||||
template.UpdateValue(key, ConfigData.Modules[0].AAFilterRateHz.ToString("F0"),
|
||||
1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.OffsetMV:
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ?
|
||||
"0" : ((short)diagnosticResult.FinalOffsetADC * diagnosticResult.ScalefactorMilliVoltsPerADC)
|
||||
.ToString("F2"),
|
||||
1 + channelIndex);
|
||||
|
||||
break;
|
||||
case TMTChannelKeys.InputRangeMV:
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" : (diagnosticResult.ScalefactorMilliVoltsPerADC * ushort.MaxValue).ToString("F0"),
|
||||
1 + channelIndex);
|
||||
break;
|
||||
// Additional Max Range EU needed for C-1/MOT1 entry for Max input range EU
|
||||
case TMTChannelKeys.MaxRangeEU:
|
||||
if (ranges != null)
|
||||
{
|
||||
template.UpdateValue(key, ranges[channelIndex].ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" :
|
||||
maxEU.ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
case TMTChannelKeys.MinRangeEU:
|
||||
|
||||
if (ranges != null)
|
||||
{
|
||||
template.UpdateValue(key, (-1 * ranges[channelIndex]).ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" :
|
||||
minEU.ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
case TMTChannelKeys.EU:
|
||||
template.UpdateValue(key,
|
||||
eu,
|
||||
1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.ScaleFactorEU:
|
||||
template.UpdateValue(key, adcToEUScalingFactor.ToString("F11"), 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.OffsetEU:
|
||||
{
|
||||
template.UpdateValue(key, offsetEU, 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns a string suitable for the TMATS file for the EU offset for a channel
|
||||
/// </summary>
|
||||
public static string GetOffsetEUString(AnalogInputDASChannel aidc, Common.DAS.Concepts.DataScaler scaler,
|
||||
float [] measuredOffset, int channelIndex, IDiagnosticResult diagnosticResult)
|
||||
{
|
||||
var isUnsigned = DoesChannelStreamUnsigned(aidc);
|
||||
var adcToEU = scaler.GetAdcToEuScalingFactor();
|
||||
|
||||
var midPointRemoval = isUnsigned ? adcToEU * Constants.ADC_MIDPOINT : 0;
|
||||
//FB15339 take the final offset ADC value and normalize it to zero rather than the ADC midpoint before converting to EU
|
||||
var offset = (scaler.GetEU((short)diagnosticResult.FinalOffsetADC) - midPointRemoval).ToString("F11");
|
||||
|
||||
if (aidc.ZeroMethod == ZeroMethodType.None)
|
||||
{
|
||||
//18806 & 44255
|
||||
//the above offset takes into consideration midpoint, initial EU, AND final offset
|
||||
//with none we don't want the final offset, but we want the midpoint and initial EU
|
||||
offset = (-1D * midPointRemoval + aidc.InitialEU).ToString("F11");
|
||||
}
|
||||
|
||||
AdjustOffsetForEUAtMv(ref offset, aidc, midPointRemoval, scaler, diagnosticResult);
|
||||
if (measuredOffset != null)
|
||||
{
|
||||
//we _do_ have a measured offset, but in the case of TSR AIR that's actually the EU
|
||||
//AND if we set return it as the offset it's going to double the reading ... this could be the same problem with TC
|
||||
//so lets just return 0 for signed das ...
|
||||
return isUnsigned ? measuredOffset[channelIndex].ToString() : "0.00";
|
||||
}
|
||||
else
|
||||
{
|
||||
return RunTestVariables.MaskEUMetaData ? "0" : offset;
|
||||
}
|
||||
}
|
||||
private static void AdjustOffsetForEUAtMv(ref string offset, AnalogInputDASChannel aidc, double midPointRemoval, Common.DAS.Concepts.DataScaler scaler,
|
||||
IDiagnosticResult diagnosticResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (null == aidc) { return; }
|
||||
if (null == scaler) { return; }
|
||||
|
||||
if (string.IsNullOrWhiteSpace(aidc.InitialOffset)) { return; }
|
||||
|
||||
var io = new InitialOffset();
|
||||
io.FromDbSerializeString(aidc.InitialOffset);
|
||||
if (io.Form != InitialOffsetTypes.EUAtMV) { return; }
|
||||
//DataScaler should take care of most of the work here, if we feed it in the final offset ADC it should adjust that by the eu@mv difference
|
||||
var eu = scaler.GetEU((short)diagnosticResult.FinalOffsetADC);
|
||||
offset = ( eu - midPointRemoval).ToString("F11");
|
||||
}
|
||||
catch( Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes the TMT file to the S6A
|
||||
/// 14531 Implement TMATS support for S6A stream on boot
|
||||
/// </summary>
|
||||
public virtual void WriteTmtFile(IDASCommunication das, Dictionary<IDASCommunication, ushort> dataChannelIds, Dictionary<IDASCommunication, ushort> timeChannelIds,
|
||||
Dictionary<IDASCommunication, ushort> uartChannelIds, int dasIndex, ICommunication communication,
|
||||
float[] scaleFactors = null, float[] ranges = null, float[] measuredOffset = null)
|
||||
{
|
||||
if ( das is EthernetSlice6AirThermocoupler)
|
||||
{
|
||||
//temporary hack to allow all TC channels
|
||||
MaxChannels = 24;
|
||||
}
|
||||
var template = GetTMTTemplate(Template);
|
||||
var globalKeys = Enum.GetValues(typeof(TMTGlobalKeys)).Cast<TMTGlobalKeys>()
|
||||
.ToArray();
|
||||
// FB 26736 Get time & data channel Ids from dictionary based on serial
|
||||
ushort? dataChannelId = null;
|
||||
ushort? timeChannelId = null;
|
||||
ushort? uartChannelId = null;
|
||||
var dataChannelIdPair = dataChannelIds.FirstOrDefault(p => p.Key.SerialNumber == SerialNumber);
|
||||
|
||||
var bitsPerFrame = 32 + 16 * MaxChannels;
|
||||
if (dataChannelIdPair.Key != null)
|
||||
{
|
||||
dataChannelId = dataChannelIdPair.Value;
|
||||
if (dataChannelIdPair.Key.IsTSRAIR()) { bitsPerFrame = Constants.BITS_PER_MINOR_FRAME_TSRAIR; }
|
||||
}
|
||||
|
||||
var timeChannelIdPair = timeChannelIds.FirstOrDefault(p => p.Key.SerialNumber == SerialNumber);
|
||||
if (timeChannelIdPair.Key != null)
|
||||
{
|
||||
timeChannelId = timeChannelIdPair.Value;
|
||||
}
|
||||
|
||||
//FB43761
|
||||
var uartChannelIdPair = uartChannelIds.FirstOrDefault(p => p.Key.SerialNumber == SerialNumber);
|
||||
if (uartChannelIdPair.Key != null)
|
||||
{
|
||||
uartChannelId = uartChannelIdPair.Value;
|
||||
}
|
||||
|
||||
foreach (var key in globalKeys)
|
||||
{
|
||||
TmtSingleFile.UpdateGlobalField(das, key, template, ConfigData, SerialNumber, timeChannelId, dataChannelId, uartChannelId, dasIndex, bitsPerFrame);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MaxChannels; i++)
|
||||
{
|
||||
UpdateTMTChannel(template, i, scaleFactors, ranges, measuredOffset);
|
||||
}
|
||||
WriteTMTFile((ICommunication)das, template.GetAllLines(), das.TestDirectory);
|
||||
}
|
||||
public static void WriteTMTFile(ICommunication communication, string [] allLines,
|
||||
string testDirectory)
|
||||
{
|
||||
var sfd = new SetFileData(communication);
|
||||
var byteData = Encoding.UTF8.GetBytes(string.Join("\n", allLines));
|
||||
var maxFileSize = InformationCommands.MAX_FILE_LENGTH_ID100;
|
||||
if (communication is ITMATSStreamingDevice tmatsStreamer)
|
||||
{
|
||||
maxFileSize = tmatsStreamer.GetMaxFileLengthTMATS();
|
||||
}
|
||||
if (byteData.Length >= maxFileSize)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(
|
||||
$"TMT File is too large, {byteData.Length} >= {maxFileSize}");
|
||||
}
|
||||
|
||||
//15241 store uploaded TMATS file to DASConfigs folder
|
||||
WriteTMTFilePC(byteData, testDirectory, communication.SerialNumber);
|
||||
sfd.StartByteCount = 0;
|
||||
sfd.FileID = SetFileData.TMT_FILE_ID;
|
||||
|
||||
sfd.Data = Constants.XML_STORE_MAGIC_BYTES;
|
||||
sfd.SyncExecute();
|
||||
|
||||
//Store Header - data length
|
||||
var maxLen = Convert.ToUInt32(byteData.Length);
|
||||
sfd.StartByteCount = Constants.XML_HEADER_LENGTH / 2;
|
||||
sfd.FileID = SetFileData.TMT_FILE_ID;
|
||||
sfd.Data = BitConverter.GetBytes(maxLen);
|
||||
sfd.SyncExecute();
|
||||
|
||||
//Store Data
|
||||
for (uint i = 0; i < maxLen; i += (uint)sfd.MaximumFileStreamBytes)
|
||||
{
|
||||
long array_size = sfd.MaximumFileStreamBytes;
|
||||
if ((i + sfd.MaximumFileStreamBytes) > maxLen)
|
||||
{
|
||||
array_size = maxLen - i;
|
||||
}
|
||||
|
||||
var dataToSend = new byte[array_size];
|
||||
Array.Copy(byteData, i, dataToSend, 0, array_size);
|
||||
|
||||
sfd.Data = dataToSend;
|
||||
sfd.FileID = SetFileData.TMT_FILE_ID;
|
||||
sfd.StartByteCount = i + Constants.XML_HEADER_LENGTH;
|
||||
sfd.SyncExecute();
|
||||
}
|
||||
}
|
||||
//FB 30035 Refactored to create TmtFile object and return it based on profile
|
||||
/// <summary>
|
||||
/// returns a new template file object given a udp stream profile
|
||||
/// 29430 Store TMAT file that corresponds to Stream Profile
|
||||
/// </summary>
|
||||
/// <param name="profile"></param>
|
||||
/// <param name="serialNumber"></param>
|
||||
/// <param name="dasInfo"></param>
|
||||
/// <param name="configData"></param>
|
||||
/// <param name="channelDiagnosticsResults"></param>
|
||||
/// <returns></returns>
|
||||
public static ITmtFile GetS6ATMATSFileTypeForProfile(UDPStreamProfile profile, string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults)
|
||||
{
|
||||
switch (profile)
|
||||
{
|
||||
case UDPStreamProfile.CH10_ANALOG:
|
||||
case UDPStreamProfile.CH10_ANALOG_2HDR:
|
||||
return new Slice6AirAnalogTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
case UDPStreamProfile.CH10_PCM128_MM:
|
||||
case UDPStreamProfile.CH10_PCM_128BIT_2HDR:
|
||||
case UDPStreamProfile.CH10_PCM_STANDARD:
|
||||
case UDPStreamProfile.CH10_PCM_STANDARD_2HDR:
|
||||
case UDPStreamProfile.CH10_PCM_SUPERCOM:
|
||||
case UDPStreamProfile.CH10_PCM_SUPERCOM_2HDR:
|
||||
return new Slice6AirPcmTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
//FB 28292 "TmNS 144 bit PCM" and "TmNS Supercom 4x ADC PCM" profiles
|
||||
case UDPStreamProfile.TMNS_PCM_STANDARD:
|
||||
return new Slice6AirTmNs144PcmTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
case UDPStreamProfile.TMNS_PCM_SUPERCOM:
|
||||
return new Slice6AirTmNsSuperCom4XPcmTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
default:
|
||||
APILogger.Log($"GetTMATSTypeForProfile unsupported profile type: {profile}");
|
||||
return new Slice6AirAnalogTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public class Slice6AirAnalogTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirAnalogTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_ANALOG;
|
||||
}
|
||||
}
|
||||
|
||||
public class Slice6AirPcmTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirPcmTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_PCM;
|
||||
}
|
||||
}
|
||||
|
||||
public class Slice6AirTmNs144PcmTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirTmNs144PcmTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_TmNS_144PPCM;
|
||||
}
|
||||
}
|
||||
|
||||
public class Slice6AirTmNsSuperCom4XPcmTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirTmNsSuperCom4XPcmTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_TmNS_SuperCom4xPCM;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class DiagnoseParameters : IStatusParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// controls whether we should remain in state or not
|
||||
/// </summary>
|
||||
public bool ProceedToRealtimeWhenDone { get; set; }
|
||||
public bool RequireAllUnitsPassDiagnostic { get; set; }
|
||||
|
||||
public bool AllUnitsPassedDiagnostic { get; set; }
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
ProceedToRealtimeWhenDone = true;
|
||||
RequireAllUnitsPassDiagnostic = false;
|
||||
AllUnitsPassedDiagnostic = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class CANConfig : IXmlSerializable
|
||||
{
|
||||
private readonly Dictionary<string, CANModuleConfig> _modules = new Dictionary<string, CANModuleConfig>();
|
||||
public Dictionary<string, CANModuleConfig> Modules { get { return _modules; } }
|
||||
private readonly string _fileName;
|
||||
public string FileName { get { return _fileName; } }
|
||||
|
||||
public CANConfig()
|
||||
{
|
||||
}
|
||||
|
||||
public CANConfig(string fileName, bool deleteIfPresent)
|
||||
{
|
||||
const string dasConfigs = "DASConfigs";
|
||||
var location = Path.Combine(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), dasConfigs), fileName);
|
||||
|
||||
_fileName = location;
|
||||
if (File.Exists(location))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (deleteIfPresent)
|
||||
{
|
||||
try { File.Delete(_fileName); }
|
||||
catch (Exception ex) { APILogger.Log("Problem deleting ", _fileName, ex); }
|
||||
}
|
||||
else { using (var sr = new StreamReader(_fileName)) { ReadXml(XmlReader.Create(sr)); } }
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Problem reading ", _fileName, ex); }
|
||||
}
|
||||
}
|
||||
public void SetModule(CANModuleConfig module)
|
||||
{
|
||||
if (_modules.ContainsKey(module.SerialNumber)) { _modules[module.SerialNumber] = module; }
|
||||
else { _modules.Add(module.SerialNumber, module); }
|
||||
}
|
||||
public CANModuleConfig GetModule(CANModuleConfig module)
|
||||
{
|
||||
if (_modules.ContainsKey(module.SerialNumber)) { return _modules[module.SerialNumber]; }
|
||||
else
|
||||
{
|
||||
_modules.Add(module.SerialNumber, module);
|
||||
return module;
|
||||
}
|
||||
}
|
||||
public XmlSchema GetSchema()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
//
|
||||
// Summary:
|
||||
// Generates an object from its XML representation.
|
||||
//
|
||||
// Parameters:
|
||||
// reader:
|
||||
// The System.Xml.XmlReader stream from which the object is deserialized.
|
||||
public void ReadXml(XmlReader reader)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
reader.ReadStartElement("CANConfig");
|
||||
|
||||
reader.ReadStartElement("Modules");
|
||||
|
||||
while (reader.MoveToContent() == XmlNodeType.Element)
|
||||
{
|
||||
CANModuleConfig tConfig = new CANModuleConfig();
|
||||
tConfig.ReadXml(reader);
|
||||
SetModule(tConfig);
|
||||
}
|
||||
|
||||
reader.ReadEndElement();
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
//
|
||||
// Summary:
|
||||
// Converts an object into its XML representation.
|
||||
//
|
||||
// Parameters:
|
||||
// writer:
|
||||
// The System.Xml.XmlWriter stream to which the object is serialized.
|
||||
public void WriteXml(XmlWriter writer)
|
||||
{
|
||||
writer.WriteStartElement("CANConfig");
|
||||
|
||||
writer.WriteStartElement("Modules");
|
||||
writer.Flush();
|
||||
|
||||
foreach (CANModuleConfig module in _modules.Values)
|
||||
{
|
||||
module.WriteXml(writer);
|
||||
writer.Flush();
|
||||
}
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement();
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,807 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.DASLib.Command;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.WINUSBConnection;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.DASLib.Service.Classes.Diagnostics;
|
||||
using DTS.Common.Interface.DASFactory.ARM;
|
||||
using DTS.Common.Interface.DASFactory.Download;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.SLICE.RealtimeCommands;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public partial class Slice<T> : Communication<T>,
|
||||
IDASCommunication,
|
||||
IConfigurationActions,
|
||||
IDiagnosticsActions,
|
||||
ITriggerCheckActions,
|
||||
IRealTimeActions,
|
||||
IArmActions,
|
||||
IDownloadActions where T : IConnection, new()
|
||||
{
|
||||
public virtual HardwareTypes GetHardwareType()
|
||||
{
|
||||
if (SerialNumber.Contains("BA5"))
|
||||
{
|
||||
return HardwareTypes.SLICE_NANO_Base;
|
||||
}
|
||||
if (SerialNumber.Contains("BA0"))
|
||||
{
|
||||
return HardwareTypes.SLICE_Micro_Base;
|
||||
}
|
||||
if (SerialNumber.StartsWith("SG5"))
|
||||
{
|
||||
return HardwareTypes.SLICE1_G5Stack;
|
||||
}
|
||||
return HardwareTypes.SLICE_Base;
|
||||
}
|
||||
public virtual int[] GetStackChannelConfigTypes()
|
||||
{
|
||||
return new int[] { 0 };
|
||||
}
|
||||
public float InputLowVoltage { get; set; } = 7;
|
||||
|
||||
public float InputMediumVoltage { get; set; } = 11;
|
||||
|
||||
public float InputHighVoltage { get; set; } = 15;
|
||||
|
||||
public float BatteryLowVoltage { get; set; } = 8;
|
||||
|
||||
public float BatteryMediumVoltage { get; set; } = 8.5F;
|
||||
|
||||
public float BatteryHighVoltage { get; set; } = 9;
|
||||
|
||||
public double MinimumValidInputVoltage { get; set; } = 4;
|
||||
|
||||
public virtual double MaximumValidInputVoltage { get; set; } = 19;
|
||||
|
||||
public double MinimumValidBatteryVoltage { get; set; } = 4;
|
||||
|
||||
public double MaximumValidBatteryVoltage { get; set; } = 9;
|
||||
|
||||
#region Configuration
|
||||
|
||||
// our public configure member
|
||||
public IConfigurationData ConfigData { get; set; }
|
||||
|
||||
//FB 25526 moved from SLICE6AIR class so can be used by subtypes
|
||||
/// <summary>
|
||||
/// returns true if the device is using a stream mode (either S6A streaming or record and stream)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ShouldWriteStreamInfo()
|
||||
{
|
||||
if (Array.Exists(ConfigData.Modules, m => RecordingModeExtensions.IsAStreamMode(m.RecordingMode))) { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Diagnostics
|
||||
|
||||
// our public diagnostics member
|
||||
public IDiagnosticActions[] ChannelDiagnostics { get; set; }
|
||||
public void SetChannelDiagnosticActions(IDiagnosticActions[] actions, bool setInDb = true)
|
||||
{
|
||||
DiagnosticsActions.SetChannelDiagnosticActions(this, actions, setInDb);
|
||||
}
|
||||
public IDiagnosticResult[] ChannelDiagnosticsResults { get; set; }
|
||||
public void ClearChannelDiagnosticsResults(bool bClearDb = true)
|
||||
{
|
||||
DiagnosticsResultActions.ClearChannelDiagnosticsResults(this, bClearDb);
|
||||
}
|
||||
|
||||
public void SetChannelDiagnosticsResults(IDiagnosticResult[] results, bool setInDb)
|
||||
{
|
||||
DiagnosticsResultActions.SetChannelDiagnosticsResults(this, results, setInDb);
|
||||
}
|
||||
public IModuleDiagnosticsResult[] ModuleDiagnosticsResults { get; set; }
|
||||
|
||||
public IBaseInputValues BaseInput { get; set; }
|
||||
|
||||
public IArmCheckActions ArmCheckActions { get; set; }
|
||||
public IArmCheckResults ArmCheckResults { get; set; }
|
||||
public IOptimizationValues OptimizationValues { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Trigger check
|
||||
|
||||
// our public trigger check member
|
||||
public ITriggerCheckResult TriggerResult { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Real time
|
||||
|
||||
// our public real time member
|
||||
public List<int> RealtimeDASChannels { get; set; }
|
||||
|
||||
public List<double> TiltAxisData { get; set; }
|
||||
#endregion
|
||||
|
||||
#region FlashErase
|
||||
|
||||
public FlashEraseStatus DASFlashEraseStatus { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Arming
|
||||
public bool GetIsInArm()
|
||||
{
|
||||
if (null == DASArmStatus) { return false; }
|
||||
return DASArmStatus.IsArmed;
|
||||
}
|
||||
public bool GetIsInRealtime()
|
||||
{
|
||||
if (null == DASArmStatus) { return false; }
|
||||
return DASArmStatus.IsInRealtime;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns true if the unit is known to be streaming
|
||||
/// does not query the hardware, just returns a flag if it has been set
|
||||
/// </summary>
|
||||
/// <returns>true if known to be streaming, false otherwise</returns>
|
||||
public virtual bool GetIsStreaming()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public void SetInArm(bool WriteToDb)
|
||||
{
|
||||
if (null == DASArmStatus)
|
||||
{
|
||||
var armStatus = new ArmStatus()
|
||||
{
|
||||
IsArmed = true
|
||||
};
|
||||
ArmStatus.SetArmStatus(this, armStatus, WriteToDb);
|
||||
}
|
||||
else
|
||||
{
|
||||
DASArmStatus.IsArmed = true;
|
||||
if (WriteToDb)
|
||||
{
|
||||
SetDASArmStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetInRealtime(bool WriteToDb, bool ExitRealtimeIfPossible)
|
||||
{
|
||||
//before we mark it as realtime, check for qats, if we have
|
||||
//qats it's armed, not realtime
|
||||
try
|
||||
{
|
||||
var qats = new QueryArmAndTriggerStatus(this);
|
||||
qats.SyncExecute();
|
||||
if (qats.IsArmed)
|
||||
{
|
||||
SetInArm(WriteToDb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//don't bother logging.
|
||||
}
|
||||
|
||||
if (ExitRealtimeIfPossible)
|
||||
{
|
||||
try
|
||||
{
|
||||
var exitRT = new EndRealtimeMode(this);
|
||||
exitRT.SyncExecute();
|
||||
//presumably we succeeded?
|
||||
//should we turn off power too? I'm not sure, uncomment the following lines to turn off power...
|
||||
//var info = new SliceServiceAsyncInfo((ServiceCallbackData data) => { }, this);
|
||||
//AsyncEnterLowPowerMode(info);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
if (null == DASArmStatus)
|
||||
{
|
||||
var armStatus = new ArmStatus()
|
||||
{
|
||||
IsInRealtime = true
|
||||
};
|
||||
ArmStatus.SetArmStatus(this, armStatus, WriteToDb);
|
||||
}
|
||||
else
|
||||
{
|
||||
DASArmStatus.IsInRealtime = true;
|
||||
if (WriteToDb)
|
||||
{
|
||||
SetDASArmStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
public IArmStatusData DASArmStatus { get; set; }
|
||||
public void SetDASArmStatus(IArmStatusData status, bool bSetInDb)
|
||||
{
|
||||
ArmStatus.SetArmStatus(this, status, bSetInDb);
|
||||
}
|
||||
public void SetDASArmStatus()
|
||||
{
|
||||
//FB 26817
|
||||
if (DASArmStatus.IsArmed)
|
||||
{
|
||||
DASArmStatus.MaxEventsPossible = GetTSRAIRMaxEventsPossible();
|
||||
}
|
||||
ArmStatus.SetArmStatus(this, DASArmStatus, true);
|
||||
}
|
||||
|
||||
//FB 26817 Only for TSR AIR Query MaxEventsPossible after Arm to get the supported max events
|
||||
private ushort? GetTSRAIRMaxEventsPossible()
|
||||
{
|
||||
if (this is WinUSBTsrAir || this is EthernetTsrAir)
|
||||
{
|
||||
try
|
||||
{
|
||||
//per WIKI before querying we should set to 0 first to calculate?
|
||||
var setMaxEventsPossible = new SetSystemAttribute(this);
|
||||
setMaxEventsPossible.DeviceID = 0;
|
||||
setMaxEventsPossible.SetValue(AttributeTypes.SystemAttributes.MaxEventsPossible, new[] { (ushort)0, (ushort)0 }, true);
|
||||
setMaxEventsPossible.SyncExecute();
|
||||
|
||||
var getMaxEventsPossible = new QuerySystemAttribute(this);
|
||||
getMaxEventsPossible.DeviceID = 0;
|
||||
getMaxEventsPossible.Key = AttributeTypes.SystemAttributes.MaxEventsPossible;
|
||||
getMaxEventsPossible.SyncExecute();
|
||||
ushort maxEventPossible = ((ushort[])getMaxEventsPossible.Value)[1];
|
||||
return maxEventPossible;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public DFConstantsAndEnums.CommandStatus AutoArmStatus { get; set; } = DFConstantsAndEnums.CommandStatus.StatusNoError;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Clock Sync
|
||||
public IDictionary<InputClockSource, bool> DASClockSyncStatus { get; set; } = null;
|
||||
public bool ClockSyncInUTC { get; set; } = false;
|
||||
public ClockSyncProfile DASClockSyncProfile { get; set; }
|
||||
public byte PTPDomainID { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Downloading
|
||||
|
||||
public virtual IDownloadRequest WhatToDownload { get; set; }
|
||||
public void SetWhatToDownload(IDownloadRequest request, bool bSetInDb = true)
|
||||
{
|
||||
DownloadRequest.SetWhatToDownload(this, request, bSetInDb);
|
||||
}
|
||||
public IDownloadReport EventInfo { get; set; }
|
||||
public void SetEventInfo(IDownloadReport eventInfo, bool bSetInDb = true)
|
||||
{
|
||||
DownloadReport.SetEventInfo(this, eventInfo, bSetInDb);
|
||||
}
|
||||
public bool[] EventDownloadedStatus { get; set; }
|
||||
public void SetEventDownloadStatus(bool[] status, bool storeInDb = true)
|
||||
{
|
||||
DownloadReport.SetEventDownloadStatus(this, status, storeInDb);
|
||||
}
|
||||
public Guid[] EventGuids { get; set; }
|
||||
public void SetEventGuids(Guid[] guids, bool storeInDb = true)
|
||||
{
|
||||
DownloadReport.SetEventGuids(this, guids, storeInDb);
|
||||
}
|
||||
public ushort[] FaultFlags { get; set; }
|
||||
public void SetEventFaultFlags(ushort[] flags, bool storeInDb = true)
|
||||
{
|
||||
DownloadReport.SetEventFaultFlags(this, flags, storeInDb);
|
||||
}
|
||||
uint[] IDownload.ExtendedFaultFlags1 { get; set; }
|
||||
uint[] IDownload.ExtendedFaultFlags2 { get; set; }
|
||||
uint[] IDownload.ExtendedFaultFlags3 { get; set; }
|
||||
uint[] IDownload.ExtendedFaultFlags4 { get; set; }
|
||||
void IDownload.SetExtendedFaultFlags(uint[][] flags)
|
||||
{
|
||||
DownloadExtendedFaultFunctions.SetExtendedFaultFlags(flags, this);
|
||||
}
|
||||
|
||||
public byte[] ArmAttempts { get; set; }
|
||||
public void SetEventArmAttemps(byte[] armAttempts, bool storeInDb = true)
|
||||
{
|
||||
DownloadReport.SetEventArmAttempts(this, armAttempts, storeInDb);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Information
|
||||
public virtual bool SupportsTriggerInversion() { return true; }
|
||||
public virtual bool SupportsStartInversion() { return true; }
|
||||
public bool InvertTrigger { get; set; }
|
||||
public bool InvertStart { get; set; }
|
||||
|
||||
public bool IgnoreShortedStart { get; set; }
|
||||
public bool IgnoreShortedTrigger { get; set; }
|
||||
|
||||
public new IInfoResult DASInfo { get; set; }
|
||||
public void SetDASInfo(IInfoResult dasInfo, bool bSetInDb = true)
|
||||
{
|
||||
InfoResult.SetDASInfo(this, dasInfo, bSetInDb);
|
||||
}
|
||||
public void SetDASInfo() { InfoResult.SetDASInfo(this); }
|
||||
public static StaticInformation StaticDASBridgeInfo = new StaticInformation(new double[]
|
||||
{//1,2,4,8,10,16,20,32,40,64,80,128,160,320,640,1280
|
||||
2400D/1.0,
|
||||
2400D/2.0,
|
||||
2400D/4.0,
|
||||
2400D/8.0,
|
||||
2400D/10.0,
|
||||
2400D/16.0,
|
||||
2400D/20.0,
|
||||
2400D/32.0,
|
||||
2400D/40.0,
|
||||
2400D/64.0,
|
||||
2400D/80.0,
|
||||
2400D/128.0,
|
||||
2400D/160.0,
|
||||
2400D/320.0,
|
||||
2400D/640.0,
|
||||
2400D/1280.0
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// the breakpoints for IEPE ranges possible on S6
|
||||
/// FB15462 split off S6 IEPE gain selection from S6A
|
||||
/// </summary>
|
||||
public static StaticInformation StaticDASS6EIEPEInfo = new StaticInformation(new double[]
|
||||
{//1,2,4,8,10,16,20,32,40,64,80,128,160,320,640,1280
|
||||
2400D/(1.0/6),
|
||||
2400D/(2.0/6),
|
||||
2400D/(4.0/6),
|
||||
2400D/(8.0/6),
|
||||
2400D/(10.0/6),
|
||||
2400D/(16.0/6),
|
||||
2400D/(20.0/6),
|
||||
2400D/(32.0/6),
|
||||
2400D/(40.0/6),
|
||||
2400D/(64.0/6),
|
||||
2400D/(80.0/6),
|
||||
2400D/(128.0/6),
|
||||
2400D/(160.0/6),
|
||||
2400D/(320.0/6),
|
||||
2400D/(640.0/6),
|
||||
2400D/(1280.0/6)
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// the breakpoints for IEPE ranges possible on S6A
|
||||
/// 14558 IEPE gain selection limited to gain 1 and 10 in DataPRO for SLICE6 AIR
|
||||
/// 15462 Limit SLICE 6 AIR gains as they are not functional with IEPE accel
|
||||
/// </summary>
|
||||
public static StaticInformation StaticDASS6AEIEPEInfo = new StaticInformation(new double[]
|
||||
{//1,2,4,8,10,16,20,32,40,64,80,128,160,320,640,1280
|
||||
2400D/(1.0/6), //G1
|
||||
2400D/(2.0/6), //G2
|
||||
2400D/(4.0/6), //G3
|
||||
2400D/(8.0/6), //G4
|
||||
2400D/(10.0/6),//G5 - 1440
|
||||
2400D/(16.0/6),//G6 - 900
|
||||
2400D/(20.0/6),//G7 - 720
|
||||
2400D/(32.0/6),//G8 - 450
|
||||
2400D/(40.0/6),//G9 - 360
|
||||
2400D/(64.0/6),//G10 - 225
|
||||
2400D/(80.0/6),//G11 - 180
|
||||
2400D/(128.0/6),//G12 - 112.5
|
||||
2400D/(160.0/6),//G13 - 90
|
||||
2400D/(320.0/6),//G14 - 45
|
||||
2400D/(640.0/6),//G15 - 22.5
|
||||
2400D/(1280.0/6)//G16 - 11.25
|
||||
});
|
||||
|
||||
public enum GainCodesSLICE6IEPE //Used by Slice PRO Gen3
|
||||
{
|
||||
[MaxInputRange(14400D)]
|
||||
[MinInputRange(7200D)]
|
||||
[FirmwareInputRange(10800D)]
|
||||
G1,
|
||||
|
||||
[MaxInputRange(7200D)]
|
||||
[MinInputRange(3600D)]
|
||||
[FirmwareInputRange(5400D)]
|
||||
G2,
|
||||
|
||||
[MaxInputRange(3600D)]
|
||||
[MinInputRange(1800D)]
|
||||
[FirmwareInputRange(2700)]
|
||||
G3,
|
||||
|
||||
[MaxInputRange(1800D)]
|
||||
[MinInputRange(1440)]
|
||||
[FirmwareInputRange(1620)]
|
||||
G4,
|
||||
|
||||
[MaxInputRange(1440D)]
|
||||
[MinInputRange(900D)]
|
||||
[FirmwareInputRange(1170D)]
|
||||
G5,
|
||||
|
||||
[MaxInputRange(900D)]
|
||||
[MinInputRange(720D)]
|
||||
[FirmwareInputRange(810D)]
|
||||
G6,
|
||||
|
||||
[MaxInputRange(720D)]
|
||||
[MinInputRange(450D)]
|
||||
[FirmwareInputRange(585)]
|
||||
G7,
|
||||
|
||||
[GainDisabled(true)]
|
||||
[MaxInputRange(450D)]
|
||||
[MinInputRange(360D)]
|
||||
[FirmwareInputRange(405)]
|
||||
G8,
|
||||
|
||||
[MaxInputRange(360D)]
|
||||
[MinInputRange(225D)]
|
||||
[FirmwareInputRange(292.5)]
|
||||
G9,
|
||||
|
||||
[GainDisabled(true)]
|
||||
[MaxInputRange(225D)]
|
||||
[MinInputRange(180D)]
|
||||
[FirmwareInputRange(202.5)]
|
||||
G10,
|
||||
|
||||
[MaxInputRange(180)]
|
||||
[MinInputRange(112.5)]
|
||||
[FirmwareInputRange(146.25)]
|
||||
G11,
|
||||
|
||||
[GainDisabled(true)]
|
||||
[MaxInputRange(112.5)]
|
||||
[MinInputRange(90)]
|
||||
[FirmwareInputRange(101.25)]
|
||||
G12,
|
||||
|
||||
[MaxInputRange(90)]
|
||||
[MinInputRange(45)]
|
||||
[FirmwareInputRange(67.5)]
|
||||
G13,
|
||||
|
||||
[MaxInputRange(45)]
|
||||
[MinInputRange(22.5)]
|
||||
[FirmwareInputRange(33.75)]
|
||||
G14,
|
||||
|
||||
[GainDisabled(true)]
|
||||
[MaxInputRange(22.5)]
|
||||
[MinInputRange(11.25)]
|
||||
[FirmwareInputRange(16.875)]
|
||||
G15,
|
||||
|
||||
[GainDisabled(true)]
|
||||
[MaxInputRange(11.25)]
|
||||
[MinInputRange(0)]
|
||||
[FirmwareInputRange(5.625)]
|
||||
G16
|
||||
};
|
||||
//0.2040816327F, 2.0408163265F
|
||||
public static StaticInformation StaticDASIEPEInfo = new StaticInformation(new double[]
|
||||
{
|
||||
2400D/.2040816327D,
|
||||
2400D/2.0408163265D
|
||||
});
|
||||
|
||||
#endregion
|
||||
|
||||
#region Firmware Utility
|
||||
public string FWUtilSerialNumber { get; set; }
|
||||
public Dictionary<ushort, object> SystemAttributes { get; set; }
|
||||
public Dictionary<ushort, object> UserAttributes { get; set; }
|
||||
public Dictionary<ushort, object> ArmAttributes { get; set; }
|
||||
public Dictionary<ushort, object> EventAttributes { get; set; }
|
||||
public ushort EventAttributeEventNumber { get; set; }
|
||||
#endregion
|
||||
|
||||
//I'm guessing hiding was not intended, this member hides an inherited member (from ICommunication)
|
||||
//public string SerialNumber { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var sn = SerialNumber;
|
||||
if (!string.IsNullOrEmpty(sn))
|
||||
return sn;
|
||||
return "Unknown DAS";
|
||||
}
|
||||
|
||||
public virtual int NumberOfConfiguredChannels()
|
||||
{
|
||||
if (ConfigData == null)
|
||||
return 0;
|
||||
return ConfigData.NumberOfConfiguredChannels();
|
||||
}
|
||||
|
||||
public virtual int NumberOfChannels()
|
||||
{
|
||||
if (ConfigData == null)
|
||||
return 0;
|
||||
return ConfigData.NumberOfChannels();
|
||||
}
|
||||
|
||||
public virtual int NumberOfDownloadChannels()
|
||||
{
|
||||
if (ConfigData == null)
|
||||
return 0;
|
||||
return ConfigData.NumberOfDownloadChannels();
|
||||
}
|
||||
|
||||
public int CompareTo(IDASCommunication das)
|
||||
{
|
||||
if (das == null || string.IsNullOrEmpty(das.SerialNumber) || string.IsNullOrEmpty(SerialNumber))
|
||||
return 0;
|
||||
return SerialNumber.CompareTo(das.SerialNumber);
|
||||
}
|
||||
|
||||
public virtual bool DiagnosticsHasBeenRun { get; set; }
|
||||
private bool _configureHasBeenRun = false;
|
||||
public virtual bool ConfigureHasBeenRun
|
||||
{
|
||||
get => _configureHasBeenRun;
|
||||
set
|
||||
{
|
||||
if (!value && null != ConfigData) { ConfigData.ClearSetup = true; }
|
||||
_configureHasBeenRun = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Sub classes used for identification
|
||||
|
||||
public class WinUSBSlice : Slice<WINUSBConnection>
|
||||
{
|
||||
public WinUSBSlice()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = true;
|
||||
}
|
||||
}
|
||||
public class CDCUSBSlice : SLICE2<WINUSBConnection>
|
||||
{
|
||||
public CDCUSBSlice()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
|
||||
public class WinUSBSlice1_5 : SLICE1_5<WINUSBConnection>
|
||||
{
|
||||
public WinUSBSlice1_5()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
public class WinUSBSlice6 : SLICE6<WINUSBConnection>
|
||||
{
|
||||
public WinUSBSlice6()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
public class WinUSBSlice6Air : SLICE6AIR<WINUSBConnection>
|
||||
{
|
||||
public WinUSBSlice6Air()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
public class WinUSBSlice6AirBridge : SLICE6AIRBR<WINUSBConnection>
|
||||
{
|
||||
public WinUSBSlice6AirBridge()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
public class WinUSBTsrAir : TSRAIR<WINUSBConnection>
|
||||
{
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
if (UNKNOWN_REVISION == _hardwareRevision) QueryHardwareRevision();
|
||||
switch (_hardwareRevision)
|
||||
{
|
||||
case (int)TSR_AIR_HW_REVISION.DIR:
|
||||
return HardwareTypes.DIR;
|
||||
case (int)TSR_AIR_HW_REVISION.DKR:
|
||||
return HardwareTypes.DKR;
|
||||
default:
|
||||
return HardwareTypes.UNDEFINED;
|
||||
}
|
||||
}
|
||||
public WinUSBTsrAir()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
// no network time sync
|
||||
TSRAIR_MinimumProtocols.Remove(DFConstantsAndEnums.ProtocolLimitedCommands.PTPSyncStatus);
|
||||
TSRAIR_MinimumProtocols.Remove(DFConstantsAndEnums.ProtocolLimitedCommands.PTPTimestamp);
|
||||
_haveInited = true;
|
||||
}
|
||||
}
|
||||
public class WinUSBSlice6AirThermocoupler : SLICE6AIRTC<WINUSBConnection>
|
||||
{
|
||||
public WinUSBSlice6AirThermocoupler()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
public class EthernetSlice : Slice<EthernetConnection>
|
||||
{
|
||||
public EthernetSlice()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = true;
|
||||
}
|
||||
}
|
||||
public class EthernetSlice2 : SLICE2<EthernetConnection>
|
||||
{
|
||||
public EthernetSlice2()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
public class EthernetSlice6 : SLICE6<EthernetConnection>
|
||||
{
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
return HardwareTypes.SLICE6_Base;
|
||||
}
|
||||
public EthernetSlice6()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
((EthernetConnection)Transport).RequiresKeepAliveReset = true;
|
||||
}
|
||||
}
|
||||
public class EthernetSlice6Air : SLICE6AIR<EthernetConnection>
|
||||
{
|
||||
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
return IsEthernetRecorder ? HardwareTypes.S6A_EthernetRecorder : HardwareTypes.SLICE6_AIR;
|
||||
}
|
||||
public EthernetSlice6Air()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
((EthernetConnection)Transport).RequiresKeepAliveReset = true;
|
||||
}
|
||||
}
|
||||
public class EthernetSlice6AirBridge : SLICE6AIRBR<EthernetConnection>
|
||||
{
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
return HardwareTypes.SLICE6_AIR_BR;
|
||||
}
|
||||
public EthernetSlice6AirBridge()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
((EthernetConnection)Transport).RequiresKeepAliveReset = true;
|
||||
}
|
||||
}
|
||||
public class EthernetSlice6DB : SLICE6DB<EthernetConnection>
|
||||
{
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
switch (S6DBMode)
|
||||
{
|
||||
case S6DBModes.INDUMMY:
|
||||
return HardwareTypes.SLICE6DB_InDummy;
|
||||
//case S6DBModes.AIR:
|
||||
// return HardwareTypes.SLICE6DB_AIR;
|
||||
default:
|
||||
return HardwareTypes.SLICE6DB;
|
||||
}
|
||||
}
|
||||
public EthernetSlice6DB()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
public class EthernetPowerPro : PowerPro<EthernetConnection>
|
||||
{
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
return HardwareTypes.PowerPro;
|
||||
}
|
||||
public EthernetPowerPro()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
public class EthernetTsrAir : TSRAIR<EthernetConnection>
|
||||
{
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
if (UNKNOWN_REVISION == _hardwareRevision) QueryHardwareRevision();
|
||||
switch (_hardwareRevision)
|
||||
{
|
||||
case (int)TSR_AIR_HW_REVISION.REV_A:
|
||||
return HardwareTypes.TSR_AIR;
|
||||
case (int)TSR_AIR_HW_REVISION.REV_B:
|
||||
return HardwareTypes.TSR_AIR_RevB;
|
||||
default:
|
||||
return HardwareTypes.UNDEFINED;
|
||||
}
|
||||
}
|
||||
public EthernetTsrAir()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
((EthernetConnection)Transport).RequiresKeepAliveReset = true;
|
||||
}
|
||||
}
|
||||
public class EthernetSlice6DB3 : SLICE6DB<EthernetConnection>
|
||||
{
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
return HardwareTypes.SLICE6DB3;
|
||||
}
|
||||
public EthernetSlice6DB3()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
public class EthernetSlicePRODB : SLICEPRODB<EthernetConnection>
|
||||
{
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
return HardwareTypes.SLICE_Pro_Distributor;
|
||||
}
|
||||
public EthernetSlicePRODB()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
|
||||
public class EthernetSlice1_5 : SLICE1_5<EthernetConnection>
|
||||
{
|
||||
public EthernetSlice1_5()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
}
|
||||
}
|
||||
|
||||
public class EthernetSliceDB : SliceDB<EthernetConnection>
|
||||
{
|
||||
public bool SupportsDiagnostics => IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics);
|
||||
|
||||
public EthernetSliceDB()
|
||||
{
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SerialNumber))
|
||||
{
|
||||
return SerialNumber;
|
||||
}
|
||||
else return base.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class EthernetSlice6AirThermocoupler : SLICE6AIRTC<EthernetConnection>
|
||||
{
|
||||
public override HardwareTypes GetHardwareType()
|
||||
{
|
||||
return HardwareTypes.SLICE6_AIR_TC;
|
||||
}
|
||||
public EthernetSlice6AirThermocoupler()
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = false;
|
||||
((EthernetConnection)Transport).RequiresKeepAliveReset = true;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,854 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.DASLib.Service;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Utilities;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.DASLib.Command.SLICE.DownloadCommands;
|
||||
using DTS.DASLib.Command.SLICE.RealtimeCommands;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Service.FirmwareUtility
|
||||
{
|
||||
#region SLICE Recorder class
|
||||
public class SLICERecorder
|
||||
{
|
||||
private ICommunication unit;
|
||||
public delegate void SetAttributeMethod(object val);
|
||||
|
||||
public SLICERecorder(DTS.Common.Interface.DASFactory.ICommunication _unit)
|
||||
{
|
||||
unit = _unit;
|
||||
}
|
||||
|
||||
public ushort EventNumber { get; set; }
|
||||
|
||||
public void QueryFirmwareVersion(out string firmwareversion)
|
||||
{
|
||||
var fvq = new QueryFirmwareVersion(unit);
|
||||
fvq.SyncExecute();
|
||||
firmwareversion = fvq.Version;
|
||||
}
|
||||
|
||||
public void QuerySerialNumber(out string serialnumber)
|
||||
{
|
||||
var snq = new QuerySerialNumber(unit);
|
||||
snq.SyncExecute();
|
||||
serialnumber = snq.SerialNumber;
|
||||
}
|
||||
|
||||
public void RunFlashSelfTest(UInt32 BlocksToTest, out double[] BlockTimingMicroSeconds)
|
||||
{
|
||||
const UInt32 skip = 4;
|
||||
const UInt32 FirstSector = 827392 + skip;
|
||||
|
||||
// Have the recorder run the test
|
||||
var fstest = new SelfTestFlash(unit);
|
||||
fstest.BlocksToTest = BlocksToTest;
|
||||
fstest.SyncExecute();
|
||||
|
||||
// Pick up the results, skipping skip
|
||||
BlocksToTest -= skip;
|
||||
BlockTimingMicroSeconds = new double[BlocksToTest - 1];
|
||||
|
||||
ulong[] ticks = new ulong[BlocksToTest];
|
||||
var flashread = new ReadArbitraryFlash(unit);
|
||||
|
||||
for (UInt32 CurrentSector = 0; CurrentSector < BlocksToTest; CurrentSector++)
|
||||
{
|
||||
flashread.Address = (CurrentSector + FirstSector) * 512;
|
||||
flashread.Length = 16;
|
||||
|
||||
flashread.SyncExecute();
|
||||
byte[] u64 = new byte[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
u64[i] = flashread.Data[2 * i + 1];
|
||||
}
|
||||
ByteConvertor.Convert(u64, 0, out ticks[(int)CurrentSector]);
|
||||
}
|
||||
|
||||
for (UInt32 CurrentSector = 0; CurrentSector < BlocksToTest - 1; CurrentSector++)
|
||||
{
|
||||
BlockTimingMicroSeconds[(int)CurrentSector] = (ticks[(int)CurrentSector + 1] - ticks[(int)CurrentSector]) / 10.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void QuerySystemAttributes(out Dictionary<AttributeTypes.SystemAttributes, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QuerySystemAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributes, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributes)key;
|
||||
var query = new QuerySystemAttribute(unit);
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttribute(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QuerySystemAttributes_SLICE6DB(out Dictionary<AttributeTypes.SystemAttributesSLICE6DB, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QuerySystemAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributesSLICE6DB, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributesSLICE6DB)key;
|
||||
var query = new QuerySystemAttributeSLICE6DB(unit);
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttributeSLICE6DB(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QuerySystemAttributes_SLICE6AIR(out Dictionary<AttributeTypes.SystemAttributesSLICE6AIR, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QuerySystemAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributesSLICE6AIR, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributesSLICE6AIR)key;
|
||||
var query = new QuerySystemAttributeSLICE6AIR(unit);
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttributeSLICE6AIR(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QuerySystemAttributes_SLICE6(out Dictionary<AttributeTypes.SystemAttributesSLICE6, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QuerySystemAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributesSLICE6, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributesSLICE6)key;
|
||||
var query = new QuerySystemAttributeSLICE6(unit);
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttributeSLICE6(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QuerySystemAttributes_SLICE2(out Dictionary<AttributeTypes.SystemAttributesSLICE2, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QuerySystemAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributesSLICE2, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributesSLICE2)key;
|
||||
var query = new QuerySystemAttributeSLICE2(unit);
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttributeSLICE2(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryBridgeAttributes_SLICE2(byte bridgeID, out Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE2, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = System.Enum.GetValues(typeof(AttributeTypes.SystemAttributes_Bridge_SLICE2));
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE2, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributes_Bridge_SLICE2)key;
|
||||
var query = new QuerySystemAttribute_Slice2Bridge(unit);
|
||||
query.DeviceID = bridgeID;
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttribute_Bridge_SLICE2(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryBridgeAttributes_TOM(byte bridgeID, out Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE_TOM, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = System.Enum.GetValues(typeof(AttributeTypes.SystemAttributes_Bridge_SLICE_TOM));
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE_TOM, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributes_Bridge_SLICE_TOM)key;
|
||||
var query = new QuerySystemAttribute_Slice_TOM(unit);
|
||||
query.DeviceID = bridgeID;
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttributes_Bridge_SLICE_TOM(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryBridgeAttributes(byte bridgeID, out Dictionary<AttributeTypes.SystemAttributes_Bridge, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = System.Enum.GetValues(typeof(AttributeTypes.SystemAttributes_Bridge));
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributes_Bridge, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributes_Bridge)key;
|
||||
var query = new QuerySystemAttribute_Bridge(unit);
|
||||
query.DeviceID = bridgeID;
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttribute_Bridge(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public delegate object UpdateAttribute(object value, bool overwrite);
|
||||
|
||||
public void SetSystemAttribute(AttributeTypes.SystemAttributes key, object value, bool ShouldOverwrite)
|
||||
{
|
||||
var set = new SetSystemAttribute(unit);
|
||||
set.SetValue(key, value, ShouldOverwrite);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void SetUserAttribute(AttributeTypes.SliceUserAttributes key, object value, bool ShouldOverwrite)
|
||||
{
|
||||
var set = new SetUserAttribute(unit);
|
||||
set.SetValue(key, value, ShouldOverwrite);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void QueryUserAttributes(out Dictionary<AttributeTypes.SliceUserAttributes, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QueryUserAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SliceUserAttributes, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SliceUserAttributes)key;
|
||||
var query = new QueryUserAttribute(unit);
|
||||
query.Key = (AttributeTypes.SliceUserAttributes)key;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetUserAttribute(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryArmAttributes(out Dictionary<AttributeTypes.ArmAndEventAttributes, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = new QueryArmAttributeKeys(unit);
|
||||
getKeys.SyncExecute();
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.ArmAndEventAttributes, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.ArmAndEventAttributes)key;
|
||||
var query = new QueryArmAttribute(unit);
|
||||
query.Key = (AttributeTypes.ArmAndEventAttributes)key;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetArmAttribute(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void SetArmAttribute(AttributeTypes.ArmAndEventAttributes key, object value, bool ShouldOverwrite)
|
||||
{
|
||||
var set = new SetArmAttribute(unit);
|
||||
set.SetValue(key, value, ShouldOverwrite);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void QueryEventAttributes(ushort EventNumber, out Dictionary<AttributeTypes.ArmAndEventAttributes, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
ushort TotalEvents;
|
||||
attributes = new Dictionary<AttributeTypes.ArmAndEventAttributes, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
keys = new List<int>();
|
||||
|
||||
GetTotalEventsStored(out TotalEvents);
|
||||
if (0 == TotalEvents) return;
|
||||
|
||||
var getKeys = new QueryEventAttributeKeys(unit);
|
||||
getKeys.EventNumber = EventNumber;
|
||||
getKeys.SyncExecute();
|
||||
|
||||
foreach (ushort key in getKeys.Keys)
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.ArmAndEventAttributes)key;
|
||||
var query = new QueryEventAttribute(unit);
|
||||
query.EventNumber = EventNumber;
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetEventAttribute(unit);
|
||||
attrSet.EventNumber = EventNumber;
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEventAttribute(ushort EventNumber, AttributeTypes.ArmAndEventAttributes key, object value, bool ShouldOverwrite)
|
||||
{
|
||||
var set = new SetEventAttribute(unit);
|
||||
set.EventNumber = EventNumber;
|
||||
set.SetValue(key, value, ShouldOverwrite);
|
||||
set.SyncExecute();
|
||||
}
|
||||
|
||||
public void SetAntiAliasFilterImmediately(float cutoffFrequencyHz)
|
||||
{
|
||||
var aafilterSet = new SetAAFilterImmediate(unit);
|
||||
aafilterSet.FrequencyHz = cutoffFrequencyHz;
|
||||
aafilterSet.SyncExecute();
|
||||
}
|
||||
|
||||
public void ResetEventList()
|
||||
{
|
||||
var reset = new ResetEventList(unit);
|
||||
reset.SyncExecute();
|
||||
}
|
||||
|
||||
public void Arm()
|
||||
{
|
||||
var arm = new Arm(unit);
|
||||
arm.SyncExecute();
|
||||
}
|
||||
|
||||
public void Disarm()
|
||||
{
|
||||
var disarm = new Disarm(unit);
|
||||
disarm.SyncExecute();
|
||||
}
|
||||
|
||||
public void GetSingleSample(out short[] adc, out int channels)
|
||||
{
|
||||
var ss = new RetrieveSingleSample(unit);
|
||||
ss.SyncExecute();
|
||||
channels = ss.Channels;
|
||||
adc = new short[channels];
|
||||
for (int i = 0; i < channels; i++)
|
||||
{
|
||||
adc[i] = ss.GetChannelData(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetTotalEventsStored(out ushort TotalEvents)
|
||||
{
|
||||
var eventCountQuery = new QuerySystemAttribute(unit);
|
||||
eventCountQuery.Key = AttributeTypes.SystemAttributes.TotalEventsStored;
|
||||
eventCountQuery.SyncExecute();
|
||||
|
||||
TotalEvents = (ushort)eventCountQuery.Value;
|
||||
}
|
||||
|
||||
public void GetTotalChannelsByEvent(ushort EventNumberFromZero, out byte TotalChannels)
|
||||
{
|
||||
ushort TotalEvents;
|
||||
GetTotalEventsStored(out TotalEvents);
|
||||
if (TotalEvents <= EventNumberFromZero)
|
||||
{
|
||||
TotalChannels = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var totalChannelsQuery = new QueryEventAttribute(unit);
|
||||
totalChannelsQuery.EventNumber = EventNumberFromZero;
|
||||
totalChannelsQuery.Key = AttributeTypes.ArmAndEventAttributes.TotalChannels;
|
||||
totalChannelsQuery.SyncExecute();
|
||||
TotalChannels = (byte)totalChannelsQuery.Value;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public bool IsEventAlreadyStored(ushort EventNumberFromZero)
|
||||
{
|
||||
ushort TotalEvents;
|
||||
GetTotalEventsStored(out TotalEvents);
|
||||
return (TotalEvents > EventNumberFromZero);
|
||||
}
|
||||
|
||||
public bool IsChannelValidForEvent(ushort EventNumberFromZero, byte ChannelNumberFromZero)
|
||||
{
|
||||
byte TotalChannels;
|
||||
GetTotalChannelsByEvent(EventNumberFromZero, out TotalChannels);
|
||||
return (ChannelNumberFromZero <= TotalChannels);
|
||||
}
|
||||
|
||||
public void QueryEventDescription(ushort EventNumberFromZero, out string EventDescription)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
EventDescription = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the EventDescription event attribute
|
||||
var descriptionQuery = new QueryEventAttribute(unit);
|
||||
descriptionQuery.EventNumber = EventNumberFromZero;
|
||||
descriptionQuery.Key = AttributeTypes.ArmAndEventAttributes.Description;
|
||||
descriptionQuery.SyncExecute();
|
||||
|
||||
if (null == descriptionQuery.Value)
|
||||
{
|
||||
EventDescription = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
EventDescription = (string)descriptionQuery.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryEventID(ushort EventNumberFromZero, out string EventID)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
EventID = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the EventDescription event attribute
|
||||
var idQuery = new QueryEventAttribute(unit);
|
||||
idQuery.EventNumber = EventNumberFromZero;
|
||||
idQuery.Key = AttributeTypes.ArmAndEventAttributes.Name;
|
||||
idQuery.SyncExecute();
|
||||
|
||||
if (null == idQuery.Value)
|
||||
{
|
||||
EventID = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
EventID = (string)idQuery.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryEventSampleRate(ushort EventNumberFromZero, out UInt32 SampleRate)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
SampleRate = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the EventDescription event attribute
|
||||
var sampleRateQuery = new QueryEventAttribute(unit);
|
||||
sampleRateQuery.EventNumber = EventNumberFromZero;
|
||||
sampleRateQuery.Key = AttributeTypes.ArmAndEventAttributes.SampleRate;
|
||||
sampleRateQuery.SyncExecute();
|
||||
|
||||
if (null == sampleRateQuery.Value)
|
||||
{
|
||||
SampleRate = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SampleRate = (UInt32)sampleRateQuery.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetPreTriggerSamplesByEvent(ushort EventNumberFromZero, out ulong PreTriggerSamples)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
PreTriggerSamples = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the TotalSamples event attribute
|
||||
var preTriggerSamplesQuery = new QueryEventAttribute(unit);
|
||||
preTriggerSamplesQuery.EventNumber = EventNumberFromZero;
|
||||
preTriggerSamplesQuery.Key = AttributeTypes.ArmAndEventAttributes.PreTriggerSamplesRequested;
|
||||
preTriggerSamplesQuery.SyncExecute();
|
||||
|
||||
if (null == preTriggerSamplesQuery.Value)
|
||||
{
|
||||
PreTriggerSamples = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
PreTriggerSamples = (ulong)preTriggerSamplesQuery.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetPostTriggerSamplesByEvent(ushort EventNumberFromZero, out ulong PostTriggerSamples)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
PostTriggerSamples = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the TotalSamples event attribute
|
||||
var postTriggerSamplesQuery = new QueryEventAttribute(unit);
|
||||
postTriggerSamplesQuery.EventNumber = EventNumberFromZero;
|
||||
postTriggerSamplesQuery.Key = AttributeTypes.ArmAndEventAttributes.PostTriggerSamplesRequested;
|
||||
postTriggerSamplesQuery.SyncExecute();
|
||||
|
||||
if (null == postTriggerSamplesQuery.Value)
|
||||
{
|
||||
PostTriggerSamples = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
PostTriggerSamples = (ulong)postTriggerSamplesQuery.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetTotalSamplesByEvent(ushort EventNumberFromZero, out ulong TotalSamples)
|
||||
{
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
TotalSamples = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the TotalSamples event attribute
|
||||
var totalSamplesQuery = new QueryEventAttribute(unit);
|
||||
totalSamplesQuery.EventNumber = EventNumberFromZero;
|
||||
totalSamplesQuery.Key = AttributeTypes.ArmAndEventAttributes.TotalSamplesRecorded;
|
||||
try
|
||||
{
|
||||
totalSamplesQuery.SyncExecute();
|
||||
TotalSamples = (ulong)totalSamplesQuery.Value;
|
||||
}
|
||||
|
||||
// Store the value in the out param, but take care because it may not
|
||||
// have been stored in the event's attribute store
|
||||
catch
|
||||
{
|
||||
TotalSamples = 0;
|
||||
}
|
||||
|
||||
// If the param is 0, fake it by summing pre and post trigger samples
|
||||
// requested for the event
|
||||
if (0 == TotalSamples)
|
||||
{
|
||||
ulong PreTriggerSamples, PostTriggerSamples;
|
||||
GetPreTriggerSamplesByEvent(EventNumberFromZero, out PreTriggerSamples);
|
||||
GetPostTriggerSamplesByEvent(EventNumberFromZero, out PostTriggerSamples);
|
||||
|
||||
TotalSamples = PreTriggerSamples + PostTriggerSamples;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetEventDataByChannel(ushort EventNumberFromZero, byte ChannelNumberFromZero, out short[] adc)
|
||||
{
|
||||
// Make sure the channel is valid for the event requested
|
||||
if (false == IsChannelValidForEvent(EventNumberFromZero, ChannelNumberFromZero))
|
||||
{
|
||||
adc = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab all the event data for the event
|
||||
List<short[]> adc_all;
|
||||
GetEventDataByEvent(EventNumberFromZero, out adc_all);
|
||||
|
||||
if (null == adc_all)
|
||||
{
|
||||
adc = null;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
adc = new short[adc_all[0].Length];
|
||||
}
|
||||
|
||||
// Copy out the requested channel
|
||||
Buffer.BlockCopy(adc_all[ChannelNumberFromZero], 0, adc, 0, 2 * adc_all[ChannelNumberFromZero].Length);
|
||||
}
|
||||
|
||||
public void GetEventDataByEvent(ushort EventNumberFromZero, out List<short[]> adc)
|
||||
{
|
||||
// Figure out how many samples are stored and then ...
|
||||
ulong TotalSamples;
|
||||
GetTotalSamplesByEvent(EventNumberFromZero, out TotalSamples);
|
||||
|
||||
// Grab them all
|
||||
GetEventSampleRangeByEvent(EventNumberFromZero, out adc, 0, TotalSamples - 1);
|
||||
}
|
||||
|
||||
public QueryEventDataBase GetQueryEventData(DTS.Common.Interface.DASFactory.ICommunication unit)
|
||||
{
|
||||
return new QueryEventDataBase(unit, QueryEventDataBase.Default_IO_Timeout);
|
||||
//need to do something else if unit is slice2 ...
|
||||
}
|
||||
public void GetEventSampleRangeByEvent(ushort EventNumberFromZero, out List<short[]> adc,
|
||||
ulong FirstSample, ulong LastSample)
|
||||
{
|
||||
if (FirstSample > LastSample)
|
||||
{
|
||||
adc = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the event is valid
|
||||
if (false == IsEventAlreadyStored(EventNumberFromZero))
|
||||
{
|
||||
adc = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Figure out how many samples are stored
|
||||
ulong TotalSamples;
|
||||
GetTotalSamplesByEvent(EventNumberFromZero, out TotalSamples);
|
||||
|
||||
// Make sure the samples requested are in the available window
|
||||
ulong SamplesToGet = LastSample - FirstSample + 1;
|
||||
if (FirstSample + SamplesToGet > TotalSamples)
|
||||
{
|
||||
adc = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Figure out how many channels were stored
|
||||
byte channels;
|
||||
GetTotalChannelsByEvent(EventNumberFromZero, out channels);
|
||||
|
||||
// Grab the data
|
||||
//var dataQuery = new QueryEventData(unit);
|
||||
var dataQuery = GetQueryEventData(unit);
|
||||
dataQuery.EventNumber = EventNumberFromZero;
|
||||
dataQuery.LastSample = LastSample;
|
||||
dataQuery.ChannelsDownloaded = channels;
|
||||
|
||||
ulong SamplesGotten = 0;
|
||||
adc = null;
|
||||
while (SamplesGotten < SamplesToGet)
|
||||
{
|
||||
dataQuery.FirstSample = SamplesGotten;
|
||||
dataQuery.SyncExecute();
|
||||
ulong SamplesThisTime = 0;
|
||||
if (null == adc)
|
||||
{
|
||||
adc = new List<short[]>(dataQuery.ChannelsDownloaded);
|
||||
for (int i = 0; i < adc.Capacity; i++)
|
||||
{
|
||||
adc.Add(new short[SamplesToGet]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < dataQuery.ChannelsDownloaded; i++)
|
||||
{
|
||||
short[] tmp;
|
||||
dataQuery.GetChannelData(i, out tmp);
|
||||
SamplesThisTime = (ulong)tmp.Length;
|
||||
Buffer.BlockCopy(tmp, 0, adc[i], (int)(2 * SamplesGotten),
|
||||
tmp.Length > (int)(SamplesToGet - SamplesGotten) ? (int)(2 * (SamplesToGet - SamplesGotten)) : 2 * tmp.Length);
|
||||
}
|
||||
|
||||
SamplesGotten += SamplesThisTime;
|
||||
}
|
||||
}
|
||||
|
||||
#region private members
|
||||
// empty
|
||||
#endregion
|
||||
|
||||
public void QueryBridgeAttributes_SLICE2_GEN3(byte bridgeID, out Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE2_GEN3, object> attributes, out List<SetAttributeMethod> setmethods, out List<int> keys)
|
||||
{
|
||||
var getKeys = System.Enum.GetValues(typeof(AttributeTypes.SystemAttributes_Bridge_SLICE2_GEN3));
|
||||
keys = new List<int>();
|
||||
attributes = new Dictionary<AttributeTypes.SystemAttributes_Bridge_SLICE2_GEN3, object>();
|
||||
setmethods = new List<SetAttributeMethod>();
|
||||
|
||||
foreach (ushort key in getKeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
var CurrentAttribute = (AttributeTypes.SystemAttributes_Bridge_SLICE2_GEN3)key;
|
||||
var query = new QuerySystemAttribute_Slice2Bridge_GEN3(unit);
|
||||
query.DeviceID = bridgeID;
|
||||
query.Key = CurrentAttribute;
|
||||
query.SyncExecute();
|
||||
attributes.Add(CurrentAttribute, query.Value);
|
||||
keys.Add(key);
|
||||
setmethods.Add(delegate (object val)
|
||||
{
|
||||
var attrSet = new SetSystemAttribute_Slice2Bridge_GEN3(unit);
|
||||
attrSet.SetValue(CurrentAttribute, val, true);
|
||||
attrSet.SyncExecute();
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public enum SLICEPRO_Generation
|
||||
{
|
||||
SLICEPRO_GEN2 = 0, // baseType = 0
|
||||
SLICEPRO_GEN3 = 1, // baseType = 0
|
||||
SLICEPRO_REVC = 2 // baseType = 0,3,4 reserve for board 204revC
|
||||
}
|
||||
|
||||
public SLICEPRO_Generation GetSLICEProHardwareVersion(DTS.Common.Interface.DASFactory.ICommunication comm)
|
||||
{
|
||||
byte hardwareVersion = (byte)SLICEPRO_Generation.SLICEPRO_GEN2;
|
||||
if (comm.IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision))
|
||||
{
|
||||
QuerySystemAttributeSLICE2 qsas2 = new QuerySystemAttributeSLICE2(comm, 1000);
|
||||
qsas2.DeviceGroup = 0;
|
||||
qsas2.DeviceID = 0;
|
||||
qsas2.Key = AttributeTypes.SystemAttributesSLICE2.BaseHardwareRevision;
|
||||
qsas2.SyncExecute();
|
||||
hardwareVersion = (byte)qsas2.Value;
|
||||
}
|
||||
return (SLICEPRO_Generation)hardwareVersion;
|
||||
}
|
||||
|
||||
public enum SLICEPRO_BaseType
|
||||
{
|
||||
SLICEPRO_BASE_SIM = 0,
|
||||
SLICE_NANO_PHRDR = 1,
|
||||
SLICE_BASE_PLUS = 2,
|
||||
SLICEPRO_DIM = 3,
|
||||
SLICEPRO_TOM = 4,
|
||||
// reserve 5 for Trigger Distributor Module which has no com to PC.
|
||||
SLICE6 = 6,
|
||||
SLICE6DB = 7,
|
||||
SLICE6AIR = 8,
|
||||
POWER_PRO = 9,
|
||||
TSRAIR = 10,
|
||||
SLICE6DB_3 = 11,
|
||||
}
|
||||
|
||||
// type
|
||||
public SLICEPRO_BaseType GetSLICEProBaseType(DTS.Common.Interface.DASFactory.ICommunication comm)
|
||||
{
|
||||
byte baseType = (byte)SLICEPRO_BaseType.SLICEPRO_BASE_SIM;
|
||||
|
||||
QuerySystemAttributeSLICE2 qsa = new QuerySystemAttributeSLICE2(comm, 2000);
|
||||
qsa.Key = AttributeTypes.SystemAttributesSLICE2.BaseType;
|
||||
qsa.SyncExecute();
|
||||
baseType = Convert.ToByte(qsa.Value);
|
||||
|
||||
return (SLICEPRO_BaseType)baseType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for channels encoding sample timestamps
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TimestampDASChannel : InputDASChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// CTOR to populate a channel's owning module and channel WRT that module. Calls
|
||||
/// base class CTOR.
|
||||
/// </summary>
|
||||
/// <param name="owner">Module that contains this channel.</param>
|
||||
/// <param name="channelNumber">ChannelNumber of this channel WRT owning module.</param>
|
||||
public TimestampDASChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
}
|
||||
|
||||
public TimestampDASChannel()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the rtc channel exists, it is "Configured".
|
||||
/// </summary>
|
||||
public override bool IsConfigured()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public const string MARKER = "MARKER";
|
||||
public const string SEC_H = "SECONDS_HIGH";
|
||||
public const string SEC_L = "SECONDS_LOW";
|
||||
public const string NANOS_H = "NANOSECONDS_HIGH";
|
||||
public const string NANOS_L = "NANOSECONDS_LOW";
|
||||
public const string RSVD = "RESERVED";
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
switch (OwningModule.ModuleType())
|
||||
{
|
||||
case DFConstantsAndEnums.ModuleType.EmbeddedClockSecondsAndMarker:
|
||||
switch (ModuleChannelNumber)
|
||||
{
|
||||
case 0:
|
||||
return MARKER;
|
||||
case 1:
|
||||
return SEC_H;
|
||||
case 2:
|
||||
return SEC_L;
|
||||
}
|
||||
break;
|
||||
case DFConstantsAndEnums.ModuleType.EmbeddedClockNanosAndPad:
|
||||
switch (ModuleChannelNumber)
|
||||
{
|
||||
case 0:
|
||||
return NANOS_H;
|
||||
case 1:
|
||||
return NANOS_L;
|
||||
case 2:
|
||||
return RSVD;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ModuleChannelNumber.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// While the unit is waiting for a flash erase to complete, an object of this type in the
|
||||
/// corresponding <see cref="IDASCommunication" /> can be updated to reflect the progress and
|
||||
/// any errors for the current flash erase.
|
||||
/// </summary>
|
||||
public class FlashEraseStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The last error that occurred during flash erase. This could be
|
||||
/// DFConstantsAndEnums.CommandStatus .StatusNoError if everything is okay.
|
||||
/// </summary>
|
||||
public DFConstantsAndEnums.CommandStatus LastError { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How far along is the current flash erase?
|
||||
/// </summary>
|
||||
public float PercentComplete { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.DASLib.Service.Interfaces
|
||||
{
|
||||
public interface IUARTDownloadActions
|
||||
{
|
||||
/// <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>
|
||||
void UARTDownload(ServiceCallback callback, object userData);
|
||||
/// <summary>
|
||||
/// Retrieve UART 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 QueryUARTDownload(ServiceCallback callback, object userData, int eventIndex, TDASServiceSetupInfo setupInfo);
|
||||
|
||||
/// <summary>
|
||||
/// FB15268: Set UART connection settings
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
/// <param name="baudRate"></param>
|
||||
/// <param name="dataBits"></param>
|
||||
/// <param name="stopBits"></param>
|
||||
/// <param name="parity"></param>
|
||||
/// <param name="flowControl"></param>
|
||||
void SetUARTSettings(ServiceCallback callback, object userData, uint baudRate, uint dataBits, uint stopBits, uint parity, uint flowControl);
|
||||
|
||||
void GetUARTSettings(ServiceCallback callback, object userData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="DTS.DASLib.Service.ServiceBase" Collapsed="true">
|
||||
<Position X="7" Y="0.5" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>gAAACAAgYigABQAAAAAIIAKAAAACCAAAAAAAgAAABgE=</HashCode>
|
||||
<FileName>Classes\GenericServices.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Service.ConfigurationService">
|
||||
<Position X="0.75" Y="2" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAACAAAAQACAAAAAAIIIAAAAAAAgBADAAAABAA=</HashCode>
|
||||
<FileName>Classes\GenericServices.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Service.DiagnosticsService" Collapsed="true">
|
||||
<Position X="3" Y="2" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAMAAAAAAAAQAAQACCEAAABAAAAACAABAAAAAATEA=</HashCode>
|
||||
<FileName>Classes\GenericServices.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Service.TriggerCheckService" Collapsed="true">
|
||||
<Position X="5.25" Y="2" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAACAAAQAAAAAAAAAAAAgAAAgAIAAAAAAABAA=</HashCode>
|
||||
<FileName>Classes\GenericServices.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Service.RealtimeService" Collapsed="true">
|
||||
<Position X="7.5" Y="2" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>gAAAAAAAACAAAQAAAAAAAAAAAAACAAAAIAAABAAABAg=</HashCode>
|
||||
<FileName>Classes\GenericServices.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Service.TimingService" Collapsed="true">
|
||||
<Position X="9.75" Y="2" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAIAAAAAAABAA=</HashCode>
|
||||
<FileName>Classes\GenericServices.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Service.ArmingService" Collapsed="true">
|
||||
<Position X="12" Y="2" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>SAAAAGAAAAAAQRAAEAAAIAgAAEEAABBBABhAIAAABAA=</HashCode>
|
||||
<FileName>Classes\GenericServices.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Service.DownloadService" Collapsed="true">
|
||||
<Position X="14.25" Y="2" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AQAQAgCEBIAACRAAEAAIAAQAAAAAQIgAQQEAAECmBAY=</HashCode>
|
||||
<FileName>Classes\GenericServices.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,506 @@
|
||||
using DTS.Common;
|
||||
using DTS.Common.Behaviors;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Classes.TMAT;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace DTS.DASLib.Service.Classes
|
||||
{
|
||||
public interface ITmtFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes the TMT file to the device
|
||||
/// </summary>
|
||||
void WriteTmtFile(IDASCommunication das, Dictionary<IDASCommunication, ushort> dataChannelIds, Dictionary<IDASCommunication, ushort> timeChannelIds, Dictionary<IDASCommunication, ushort> uartChannelIds, int dasIndex, ICommunication communication, float[] scaleFactors = null, float[] ranges = null, float[] measuredOffset = null);
|
||||
}
|
||||
//FB 25526 This class encapsulates the methods used in SLICE6AIR.cs before to intract with TMT files, the subclasses can support multiple types need like SLICE6AIR & TSRAIR
|
||||
public abstract class TmtFile : ITmtFile
|
||||
{
|
||||
protected TmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults)
|
||||
{
|
||||
SerialNumber = serialNumber;
|
||||
DASInfo = dasInfo;
|
||||
ConfigData = configData;
|
||||
ChannelDiagnosticsResults = channelDiagnosticsResults;
|
||||
}
|
||||
|
||||
protected static ITMTTemplate GetTMTTemplate(TMAT_TEMPLATES tmat_TEMPLATES)
|
||||
{
|
||||
var tmtFileName = StringMetaDataAttr.GetStringMetaData(tmat_TEMPLATES);
|
||||
|
||||
var tokens = tmtFileName.Split(';');
|
||||
if ( tokens.Length == 2) { return GetSplitFile(tokens[0], tokens[1]); }
|
||||
|
||||
if (string.IsNullOrWhiteSpace(tmtFileName))
|
||||
{
|
||||
tmtFileName = "S6ATMTTemplate_PCM.tmt";
|
||||
}
|
||||
return GetTMTSingleFile(tmtFileName);
|
||||
}
|
||||
/// <summary>
|
||||
/// returns a single file template
|
||||
/// </summary>
|
||||
private static ITMTTemplate GetTMTSingleFile(string tmtFileName)
|
||||
{
|
||||
return new TmtSingleFile($"TMTTemplates/{tmtFileName}");
|
||||
}
|
||||
/// <summary>
|
||||
/// returns split file template
|
||||
/// </summary>
|
||||
private static ITMTTemplate GetSplitFile(string dasTemplate, string channelTemplate)
|
||||
{
|
||||
return new TmtSplitFile($"TMTTemplates/{dasTemplate}", $"TMTTemplates/{channelTemplate}");
|
||||
}
|
||||
|
||||
protected TMAT_TEMPLATES Template { get; set; }
|
||||
protected int MaxChannels { get; set; }
|
||||
protected string SerialNumber { get; set; }
|
||||
protected IInfoResult DASInfo { get; set; }
|
||||
protected IConfigurationData ConfigData { get; set; }
|
||||
protected IDiagnosticResult[] ChannelDiagnosticsResults { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// writes tmats file to the DASConfigs log directory, file is serial_TMT.txt
|
||||
/// </summary>
|
||||
protected static void WriteTMTFilePC(byte[] data, string testDirectory, string serialNumber)
|
||||
{
|
||||
const string dasConfigs = "DASConfigs";
|
||||
try
|
||||
{
|
||||
var fileName = Path.Combine(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), dasConfigs),
|
||||
$"{serialNumber}_TMT.txt");
|
||||
if (File.Exists(fileName)) { File.Delete(fileName); }
|
||||
File.WriteAllBytes(fileName, data);
|
||||
|
||||
//43789 Now, also write the file to the Data folder because the copy in the current directory gets overwritten every test
|
||||
fileName = Path.Combine(testDirectory);
|
||||
if (!Directory.Exists(fileName))
|
||||
{
|
||||
Directory.CreateDirectory(fileName);
|
||||
}
|
||||
fileName = Path.Combine(fileName, $"{serialNumber}_TMT.txt");
|
||||
File.WriteAllBytes(fileName, data);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
try
|
||||
{
|
||||
var fileName = Path.Combine(testDirectory, dasConfigs);
|
||||
if (!Directory.Exists(fileName))
|
||||
{
|
||||
Directory.CreateDirectory(fileName);
|
||||
}
|
||||
fileName = Path.Combine(fileName, $"{serialNumber}_TMT.txt");
|
||||
File.WriteAllBytes(fileName, data);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
}
|
||||
|
||||
private static bool DoesChannelStreamUnsigned(AnalogInputDASChannel aic)
|
||||
{
|
||||
if (null == aic) { return true; }
|
||||
if (null == aic.OwningModule) { return true; }
|
||||
if (null == aic.OwningModule.OwningDAS) { return true; }
|
||||
switch (aic.OwningModule.OwningDAS.GetHardwareType())
|
||||
{
|
||||
case Common.Enums.Hardware.HardwareTypes.TSR_AIR_RevB:
|
||||
case Common.Enums.Hardware.HardwareTypes.SLICE6_AIR_TC: return false;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
private static HashSet<HardwareTypes> _signedDAS = new HashSet<HardwareTypes>() { HardwareTypes.TSR_AIR, HardwareTypes.TSR_AIR_RevB, HardwareTypes.SLICE6_AIR_TC };
|
||||
private static bool GetIsSignedData(AnalogInputDASChannel aic)
|
||||
{
|
||||
if ( null == aic || null == aic.OwningModule || aic == aic.OwningModule.OwningDAS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var type = aic.OwningModule.OwningDAS.GetHardwareType();
|
||||
if (_signedDAS.Contains(type)) { return true; }
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// writes a channel to the template in memory
|
||||
/// </summary>
|
||||
protected void UpdateTMTChannel(ITMTTemplate template, int channelIndex, float[] scaleFactors = null, float[] ranges = null, float[] measuredOffset = null)
|
||||
{
|
||||
var channelKeys = Enum.GetValues(typeof(TMTChannelKeys)).Cast<TMTChannelKeys>()
|
||||
.ToArray();
|
||||
|
||||
var number = (1 + channelIndex).ToString();
|
||||
var moduleArrayIndex = DASInfo.MapDASChannelNumber2ModuleArrayIndex(channelIndex);
|
||||
var moduleChannelIndex = DASInfo.MapDASChannelNumber2ModuleChannelNumber(channelIndex);
|
||||
var aidc = ConfigData.Modules[moduleArrayIndex].Channels[moduleChannelIndex] as AnalogInputDASChannel;
|
||||
var diagnosticResult =
|
||||
(from dr in ChannelDiagnosticsResults where dr.DASChannelNumber == channelIndex select dr)
|
||||
.FirstOrDefault();
|
||||
//this was throwing an exception for SLICE-TC, but it doesn't really need a datascaler
|
||||
//as the scale factor is always 1, so just create a new default scaler
|
||||
//note that I fixed diagnostics which may have fixed the lack of scaler with thermo channels too
|
||||
DataScaler scaler = new DataScaler();
|
||||
try
|
||||
{
|
||||
scaler = aidc.GetDataScaler();
|
||||
}
|
||||
catch( Exception ex) { APILogger.Log(ex); }
|
||||
|
||||
var tempEU = scaler.GetEU(short.MinValue);
|
||||
var tempEU2 = scaler.GetEU(short.MaxValue);
|
||||
var minEU = Math.Min(tempEU, tempEU2);
|
||||
var maxEU = Math.Max(tempEU, tempEU2);
|
||||
var channelName2 = TmtBase.TMT_LimitString(aidc.ChannelName2);
|
||||
var eu = RunTestVariables.MaskEUMetaData ? "---" : aidc.EngineeringUnits?.Trim() ?? "";
|
||||
var offsetEU = GetOffsetEUString(aidc, scaler, measuredOffset, channelIndex, diagnosticResult);
|
||||
var keys2 = Enum.GetValues(typeof(TMTChannelKeysEx)).Cast<TMTChannelKeysEx>();
|
||||
var adcToEUScalingFactor = 1D;
|
||||
if (scaleFactors != null && !RunTestVariables.MaskEUMetaData)
|
||||
{
|
||||
adcToEUScalingFactor = scaleFactors[channelIndex];
|
||||
}
|
||||
else if (!RunTestVariables.MaskEUMetaData)
|
||||
{
|
||||
adcToEUScalingFactor = scaler.GetAdcToEuScalingFactor();
|
||||
}
|
||||
|
||||
var isSigned = GetIsSignedData(aidc);
|
||||
foreach ( var key2 in keys2)
|
||||
{
|
||||
TmtBase.UpdateChannelField(key2, template, channelIndex, ranges, minEU, maxEU,
|
||||
eu, scaleFactors, adcToEUScalingFactor, channelName2, offsetEU, isSigned);
|
||||
}
|
||||
|
||||
foreach (var key in channelKeys)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case TMTChannelKeys.HardwareChannelNumber:
|
||||
template.UpdateValue(key, number, 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.ChannelName:
|
||||
template.UpdateValue(key, channelName2, 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.CouplingMode:
|
||||
var couplingMode = "D";
|
||||
if (aidc.CouplingMode == SensorConstants.CouplingModes.AC && aidc.IEPEChannel)
|
||||
{
|
||||
couplingMode = "A";
|
||||
}
|
||||
template.UpdateValue(key, couplingMode, 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.BridgeResistance:
|
||||
if (null != diagnosticResult.BridgeResistance)
|
||||
{
|
||||
template.UpdateValue(key, ((double)diagnosticResult.BridgeResistance).ToString("F0"),
|
||||
1 + channelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.UpdateValue(key, "0", 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
case TMTChannelKeys.AAF:
|
||||
template.UpdateValue(key, ConfigData.Modules[0].AAFilterRateHz.ToString("F0"),
|
||||
1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.OffsetMV:
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ?
|
||||
"0" : ((short)diagnosticResult.FinalOffsetADC * diagnosticResult.ScalefactorMilliVoltsPerADC)
|
||||
.ToString("F2"),
|
||||
1 + channelIndex);
|
||||
|
||||
break;
|
||||
case TMTChannelKeys.InputRangeMV:
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" : (diagnosticResult.ScalefactorMilliVoltsPerADC * ushort.MaxValue).ToString("F0"),
|
||||
1 + channelIndex);
|
||||
break;
|
||||
// Additional Max Range EU needed for C-1/MOT1 entry for Max input range EU
|
||||
case TMTChannelKeys.MaxRangeEU:
|
||||
if (ranges != null)
|
||||
{
|
||||
template.UpdateValue(key, ranges[channelIndex].ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" :
|
||||
maxEU.ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
case TMTChannelKeys.MinRangeEU:
|
||||
|
||||
if (ranges != null)
|
||||
{
|
||||
template.UpdateValue(key, (-1 * ranges[channelIndex]).ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" :
|
||||
minEU.ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
case TMTChannelKeys.EU:
|
||||
template.UpdateValue(key,
|
||||
eu,
|
||||
1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.ScaleFactorEU:
|
||||
template.UpdateValue(key, adcToEUScalingFactor.ToString("F11"), 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.OffsetEU:
|
||||
{
|
||||
template.UpdateValue(key, offsetEU, 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns a string suitable for the TMATS file for the EU offset for a channel
|
||||
/// </summary>
|
||||
public static string GetOffsetEUString(AnalogInputDASChannel aidc, Common.DAS.Concepts.DataScaler scaler,
|
||||
float [] measuredOffset, int channelIndex, IDiagnosticResult diagnosticResult)
|
||||
{
|
||||
var isUnsigned = DoesChannelStreamUnsigned(aidc);
|
||||
var adcToEU = scaler.GetAdcToEuScalingFactor();
|
||||
|
||||
var midPointRemoval = 0;
|
||||
//FB15339 take the final offset ADC value and normalize it to zero rather than the ADC midpoint before converting to EU
|
||||
var offset = (scaler.GetEU((short)diagnosticResult.FinalOffsetADC) - midPointRemoval).ToString("F11");
|
||||
|
||||
if (aidc.ZeroMethod == ZeroMethodType.None)
|
||||
{
|
||||
//18806 & 44255
|
||||
//the above offset takes into consideration midpoint, initial EU, AND final offset
|
||||
//with none we don't want the final offset, but we want the midpoint and initial EU
|
||||
offset = (-1D * midPointRemoval + aidc.InitialEU).ToString("F11");
|
||||
}
|
||||
|
||||
AdjustOffsetForEUAtMv(ref offset, aidc, midPointRemoval, scaler, diagnosticResult);
|
||||
if (measuredOffset != null)
|
||||
{
|
||||
//we _do_ have a measured offset, but in the case of TSR AIR that's actually the EU
|
||||
//AND if we set return it as the offset it's going to double the reading ... this could be the same problem with TC
|
||||
//so lets just return 0 for signed das ...
|
||||
return isUnsigned ? measuredOffset[channelIndex].ToString() : "0.00";
|
||||
}
|
||||
else
|
||||
{
|
||||
return RunTestVariables.MaskEUMetaData ? "0" : offset;
|
||||
}
|
||||
}
|
||||
private static void AdjustOffsetForEUAtMv(ref string offset, AnalogInputDASChannel aidc, double midPointRemoval, Common.DAS.Concepts.DataScaler scaler,
|
||||
IDiagnosticResult diagnosticResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (null == aidc) { return; }
|
||||
if (null == scaler) { return; }
|
||||
|
||||
if (string.IsNullOrWhiteSpace(aidc.InitialOffset)) { return; }
|
||||
|
||||
var io = new InitialOffset();
|
||||
io.FromDbSerializeString(aidc.InitialOffset);
|
||||
if (io.Form != InitialOffsetTypes.EUAtMV) { return; }
|
||||
//DataScaler should take care of most of the work here, if we feed it in the final offset ADC it should adjust that by the eu@mv difference
|
||||
var eu = scaler.GetEU((short)diagnosticResult.FinalOffsetADC);
|
||||
offset = ( eu - midPointRemoval).ToString("F11");
|
||||
}
|
||||
catch( Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes the TMT file to the S6A
|
||||
/// 14531 Implement TMATS support for S6A stream on boot
|
||||
/// </summary>
|
||||
public virtual void WriteTmtFile(IDASCommunication das, Dictionary<IDASCommunication, ushort> dataChannelIds, Dictionary<IDASCommunication, ushort> timeChannelIds,
|
||||
Dictionary<IDASCommunication, ushort> uartChannelIds, int dasIndex, ICommunication communication,
|
||||
float[] scaleFactors = null, float[] ranges = null, float[] measuredOffset = null)
|
||||
{
|
||||
if ( das is EthernetSlice6AirThermocoupler)
|
||||
{
|
||||
//temporary hack to allow all TC channels
|
||||
MaxChannels = 24;
|
||||
}
|
||||
var template = GetTMTTemplate(Template);
|
||||
var globalKeys = Enum.GetValues(typeof(TMTGlobalKeys)).Cast<TMTGlobalKeys>()
|
||||
.ToArray();
|
||||
// FB 26736 Get time & data channel Ids from dictionary based on serial
|
||||
ushort? dataChannelId = null;
|
||||
ushort? timeChannelId = null;
|
||||
ushort? uartChannelId = null;
|
||||
var dataChannelIdPair = dataChannelIds.FirstOrDefault(p => p.Key.SerialNumber == SerialNumber);
|
||||
|
||||
var bitsPerFrame = 32 + 16 * MaxChannels;
|
||||
if (dataChannelIdPair.Key != null)
|
||||
{
|
||||
dataChannelId = dataChannelIdPair.Value;
|
||||
if (dataChannelIdPair.Key.IsTSRAIR()) { bitsPerFrame = Constants.BITS_PER_MINOR_FRAME_TSRAIR; }
|
||||
}
|
||||
|
||||
var timeChannelIdPair = timeChannelIds.FirstOrDefault(p => p.Key.SerialNumber == SerialNumber);
|
||||
if (timeChannelIdPair.Key != null)
|
||||
{
|
||||
timeChannelId = timeChannelIdPair.Value;
|
||||
}
|
||||
|
||||
//FB43761
|
||||
var uartChannelIdPair = uartChannelIds.FirstOrDefault(p => p.Key.SerialNumber == SerialNumber);
|
||||
if (uartChannelIdPair.Key != null)
|
||||
{
|
||||
uartChannelId = uartChannelIdPair.Value;
|
||||
}
|
||||
|
||||
foreach (var key in globalKeys)
|
||||
{
|
||||
TmtSingleFile.UpdateGlobalField(das, key, template, ConfigData, SerialNumber, timeChannelId, dataChannelId, uartChannelId, dasIndex, bitsPerFrame);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MaxChannels; i++)
|
||||
{
|
||||
UpdateTMTChannel(template, i, scaleFactors, ranges, measuredOffset);
|
||||
}
|
||||
WriteTMTFile((ICommunication)das, template.GetAllLines(), das.TestDirectory);
|
||||
}
|
||||
public static void WriteTMTFile(ICommunication communication, string [] allLines,
|
||||
string testDirectory)
|
||||
{
|
||||
var sfd = new SetFileData(communication);
|
||||
var byteData = Encoding.UTF8.GetBytes(string.Join("\n", allLines));
|
||||
var maxFileSize = InformationCommands.MAX_FILE_LENGTH_ID100;
|
||||
if (communication is ITMATSStreamingDevice tmatsStreamer)
|
||||
{
|
||||
maxFileSize = tmatsStreamer.GetMaxFileLengthTMATS();
|
||||
}
|
||||
if (byteData.Length >= maxFileSize)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(
|
||||
$"TMT File is too large, {byteData.Length} >= {maxFileSize}");
|
||||
}
|
||||
|
||||
//15241 store uploaded TMATS file to DASConfigs folder
|
||||
WriteTMTFilePC(byteData, testDirectory, communication.SerialNumber);
|
||||
sfd.StartByteCount = 0;
|
||||
sfd.FileID = SetFileData.TMT_FILE_ID;
|
||||
|
||||
sfd.Data = Constants.XML_STORE_MAGIC_BYTES;
|
||||
sfd.SyncExecute();
|
||||
|
||||
//Store Header - data length
|
||||
var maxLen = Convert.ToUInt32(byteData.Length);
|
||||
sfd.StartByteCount = Constants.XML_HEADER_LENGTH / 2;
|
||||
sfd.FileID = SetFileData.TMT_FILE_ID;
|
||||
sfd.Data = BitConverter.GetBytes(maxLen);
|
||||
sfd.SyncExecute();
|
||||
|
||||
//Store Data
|
||||
for (uint i = 0; i < maxLen; i += (uint)sfd.MaximumFileStreamBytes)
|
||||
{
|
||||
long array_size = sfd.MaximumFileStreamBytes;
|
||||
if ((i + sfd.MaximumFileStreamBytes) > maxLen)
|
||||
{
|
||||
array_size = maxLen - i;
|
||||
}
|
||||
|
||||
var dataToSend = new byte[array_size];
|
||||
Array.Copy(byteData, i, dataToSend, 0, array_size);
|
||||
|
||||
sfd.Data = dataToSend;
|
||||
sfd.FileID = SetFileData.TMT_FILE_ID;
|
||||
sfd.StartByteCount = i + Constants.XML_HEADER_LENGTH;
|
||||
sfd.SyncExecute();
|
||||
}
|
||||
}
|
||||
//FB 30035 Refactored to create TmtFile object and return it based on profile
|
||||
/// <summary>
|
||||
/// returns a new template file object given a udp stream profile
|
||||
/// 29430 Store TMAT file that corresponds to Stream Profile
|
||||
/// </summary>
|
||||
/// <param name="profile"></param>
|
||||
/// <param name="serialNumber"></param>
|
||||
/// <param name="dasInfo"></param>
|
||||
/// <param name="configData"></param>
|
||||
/// <param name="channelDiagnosticsResults"></param>
|
||||
/// <returns></returns>
|
||||
public static ITmtFile GetS6ATMATSFileTypeForProfile(UDPStreamProfile profile, string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults)
|
||||
{
|
||||
switch (profile)
|
||||
{
|
||||
case UDPStreamProfile.CH10_ANALOG:
|
||||
case UDPStreamProfile.CH10_ANALOG_2HDR:
|
||||
return new Slice6AirAnalogTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
case UDPStreamProfile.CH10_PCM128_MM:
|
||||
case UDPStreamProfile.CH10_PCM_128BIT_2HDR:
|
||||
case UDPStreamProfile.CH10_PCM_STANDARD:
|
||||
case UDPStreamProfile.CH10_PCM_STANDARD_2HDR:
|
||||
case UDPStreamProfile.CH10_PCM_SUPERCOM:
|
||||
case UDPStreamProfile.CH10_PCM_SUPERCOM_2HDR:
|
||||
return new Slice6AirPcmTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
//FB 28292 "TmNS 144 bit PCM" and "TmNS Supercom 4x ADC PCM" profiles
|
||||
case UDPStreamProfile.TMNS_PCM_STANDARD:
|
||||
return new Slice6AirTmNs144PcmTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
case UDPStreamProfile.TMNS_PCM_SUPERCOM:
|
||||
return new Slice6AirTmNsSuperCom4XPcmTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
default:
|
||||
APILogger.Log($"GetTMATSTypeForProfile unsupported profile type: {profile}");
|
||||
return new Slice6AirAnalogTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public class Slice6AirAnalogTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirAnalogTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_ANALOG;
|
||||
}
|
||||
}
|
||||
|
||||
public class Slice6AirPcmTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirPcmTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_PCM;
|
||||
}
|
||||
}
|
||||
|
||||
public class Slice6AirTmNs144PcmTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirTmNs144PcmTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_TmNS_144PPCM;
|
||||
}
|
||||
}
|
||||
|
||||
public class Slice6AirTmNsSuperCom4XPcmTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirTmNsSuperCom4XPcmTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_TmNS_SuperCom4xPCM;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,437 @@
|
||||
using DTS.Common;
|
||||
using DTS.Common.Behaviors;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Classes.TMAT;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
namespace DTS.DASLib.Service.Classes
|
||||
{
|
||||
public interface ITmtFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes the TMT file to the device
|
||||
/// </summary>
|
||||
void WriteTmtFile(IDASCommunication das, Dictionary<IDASCommunication, ushort> dataChannelIds, Dictionary<IDASCommunication, ushort> timeChannelIds, int dasIndex, Common.Interface.DASFactory.ICommunication communication, float[] scaleFactors = null, float[] ranges = null, float[] measuredOffset = null);
|
||||
}
|
||||
//FB 25526 This class encapsulates the methods used in SLICE6AIR.cs before to intract with TMT files, the subclasses can support multiple types need like SLICE6AIR & TSRAIR
|
||||
public abstract class TmtFile : ITmtFile
|
||||
{
|
||||
protected TmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults)
|
||||
{
|
||||
SerialNumber = serialNumber;
|
||||
DASInfo = dasInfo;
|
||||
ConfigData = configData;
|
||||
ChannelDiagnosticsResults = channelDiagnosticsResults;
|
||||
}
|
||||
|
||||
protected ITMTTemplate GetTMTTemplate(TMAT_TEMPLATES tmat_TEMPLATES)
|
||||
{
|
||||
var tmtFileName = StringMetaDataAttr.GetStringMetaData(tmat_TEMPLATES);
|
||||
if (string.IsNullOrWhiteSpace(tmtFileName))
|
||||
{
|
||||
tmtFileName = "S6ATMTTemplate_PCM.tmt";
|
||||
}
|
||||
var path = $"TMTTemplates/{tmtFileName}";
|
||||
return new TMTTemplate(path);
|
||||
}
|
||||
|
||||
protected TMAT_TEMPLATES Template { get; set; }
|
||||
protected int MaxChannels { get; set; }
|
||||
protected string SerialNumber { get; set; }
|
||||
protected IInfoResult DASInfo { get; set; }
|
||||
protected IConfigurationData ConfigData { get; set; }
|
||||
protected IDiagnosticResult[] ChannelDiagnosticsResults { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// writes tmats file to the DASConfigs log directory, file is serial_TMT.txt
|
||||
/// </summary>
|
||||
protected static void WriteTMTFilePC(byte[] data, string testDirectory, string serialNumber)
|
||||
{
|
||||
const string dasConfigs = "DASConfigs";
|
||||
try
|
||||
{
|
||||
var fileName = Path.Combine(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), dasConfigs),
|
||||
$"{serialNumber}_TMT.txt");
|
||||
if (File.Exists(fileName)) { File.Delete(fileName); }
|
||||
File.WriteAllBytes(fileName, data);
|
||||
|
||||
//43789 Now, also write the file to the Data folder because the copy in the current directory gets overwritten every test
|
||||
fileName = Path.Combine(testDirectory);
|
||||
if (!Directory.Exists(fileName))
|
||||
{
|
||||
Directory.CreateDirectory(fileName);
|
||||
}
|
||||
fileName = Path.Combine(fileName, $"{serialNumber}_TMT.txt");
|
||||
File.WriteAllBytes(fileName, data);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
try
|
||||
{
|
||||
var fileName = Path.Combine(testDirectory, dasConfigs);
|
||||
if (!Directory.Exists(fileName))
|
||||
{
|
||||
Directory.CreateDirectory(fileName);
|
||||
}
|
||||
fileName = Path.Combine(fileName, $"{serialNumber}_TMT.txt");
|
||||
File.WriteAllBytes(fileName, data);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
}
|
||||
|
||||
private static bool DoesChannelStreamUnsigned(AnalogInputDASChannel aic)
|
||||
{
|
||||
if (null == aic) { return true; }
|
||||
if (null == aic.OwningModule) { return true; }
|
||||
if (null == aic.OwningModule.OwningDAS) { return true; }
|
||||
switch (aic.OwningModule.OwningDAS.GetHardwareType())
|
||||
{
|
||||
case Common.Enums.Hardware.HardwareTypes.TSR_AIR_RevB: return false;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// writes a channel to the template in memory
|
||||
/// </summary>
|
||||
protected void UpdateTMTChannel(ITMTTemplate template, int channelIndex, float[] scaleFactors = null, float[] ranges = null, float[] measuredOffset = null)
|
||||
{
|
||||
var channelKeys = Enum.GetValues(typeof(TMTChannelKeys)).Cast<TMTChannelKeys>()
|
||||
.ToArray();
|
||||
var number = (1 + channelIndex).ToString();
|
||||
var moduleArrayIndex = DASInfo.MapDASChannelNumber2ModuleArrayIndex(channelIndex);
|
||||
var moduleChannelIndex = DASInfo.MapDASChannelNumber2ModuleChannelNumber(channelIndex);
|
||||
var aidc = ConfigData.Modules[moduleArrayIndex].Channels[moduleChannelIndex] as AnalogInputDASChannel;
|
||||
var diagnosticResult =
|
||||
(from dr in ChannelDiagnosticsResults where dr.DASChannelNumber == channelIndex select dr)
|
||||
.FirstOrDefault();
|
||||
var scaler = aidc.GetDataScaler();
|
||||
|
||||
var tempEU = scaler.GetEU(short.MinValue);
|
||||
var tempEU2 = scaler.GetEU(short.MaxValue);
|
||||
var minEU = Math.Min(tempEU, tempEU2);
|
||||
var maxEU = Math.Max(tempEU, tempEU2);
|
||||
|
||||
foreach (var key in channelKeys)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case TMTChannelKeys.HardwareChannelNumber:
|
||||
template.UpdateValue(key, number, 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.ChannelName:
|
||||
template.UpdateValue(key, TMTTemplate.TMT_LimitString(aidc.ChannelName2), 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.CouplingMode:
|
||||
var couplingMode = "D";
|
||||
if (aidc.CouplingMode == SensorConstants.CouplingModes.AC && aidc.IEPEChannel)
|
||||
{
|
||||
couplingMode = "A";
|
||||
}
|
||||
|
||||
template.UpdateValue(key, couplingMode, 1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.BridgeResistance:
|
||||
if (null != diagnosticResult.BridgeResistance)
|
||||
{
|
||||
template.UpdateValue(key, ((double)diagnosticResult.BridgeResistance).ToString("F0"),
|
||||
1 + channelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.UpdateValue(key, "0", 1 + channelIndex);
|
||||
}
|
||||
|
||||
break;
|
||||
case TMTChannelKeys.AAF:
|
||||
template.UpdateValue(key, ConfigData.Modules[0].AAFilterRateHz.ToString("F0"),
|
||||
1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.OffsetMV:
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ?
|
||||
"0" : ((short)diagnosticResult.FinalOffsetADC * diagnosticResult.ScalefactorMilliVoltsPerADC)
|
||||
.ToString("F2"),
|
||||
1 + channelIndex);
|
||||
|
||||
break;
|
||||
case TMTChannelKeys.InputRangeMV:
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" : (diagnosticResult.ScalefactorMilliVoltsPerADC * ushort.MaxValue).ToString("F0"),
|
||||
1 + channelIndex);
|
||||
break;
|
||||
// Additional Max Range EU needed for C-1/MOT1 entry for Max input range EU
|
||||
case TMTChannelKeys.MaxRangeEU:
|
||||
if (ranges != null)
|
||||
{
|
||||
template.UpdateValue(key, ranges[channelIndex].ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" :
|
||||
maxEU.ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
case TMTChannelKeys.MinRangeEU:
|
||||
|
||||
if (ranges != null)
|
||||
{
|
||||
template.UpdateValue(key, (-1 * ranges[channelIndex]).ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" :
|
||||
minEU.ToString("F0"), 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
case TMTChannelKeys.EU:
|
||||
template.UpdateValue(key,
|
||||
RunTestVariables.MaskEUMetaData ? "---" : aidc.EngineeringUnits?.Trim() ?? "",
|
||||
1 + channelIndex);
|
||||
break;
|
||||
case TMTChannelKeys.ScaleFactorEU:
|
||||
if (scaleFactors != null)
|
||||
{
|
||||
template.UpdateValue(key, scaleFactors[channelIndex].ToString("F11"), 1 + channelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" : scaler.GetAdcToEuScalingFactor().ToString("F11"),
|
||||
1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
case TMTChannelKeys.OffsetEU:
|
||||
{
|
||||
var offsetEU = GetOffsetEUString(aidc, scaler, measuredOffset, channelIndex, diagnosticResult);
|
||||
template.UpdateValue(key, offsetEU, 1 + channelIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns a string suitable for the TMATS file for the EU offset for a channel
|
||||
/// </summary>
|
||||
public static string GetOffsetEUString(AnalogInputDASChannel aidc, Common.DAS.Concepts.DataScaler scaler,
|
||||
float [] measuredOffset, int channelIndex, IDiagnosticResult diagnosticResult)
|
||||
{
|
||||
var isUnsigned = DoesChannelStreamUnsigned(aidc);
|
||||
var adcToEU = scaler.GetAdcToEuScalingFactor();
|
||||
|
||||
var midPointRemoval = isUnsigned ? adcToEU * Constants.ADC_MIDPOINT : 0;
|
||||
//FB15339 take the final offset ADC value and normalize it to zero rather than the ADC midpoint before converting to EU
|
||||
var offset = (scaler.GetEU((short)diagnosticResult.FinalOffsetADC) - midPointRemoval).ToString("F11");
|
||||
|
||||
if (aidc.ZeroMethod == ZeroMethodType.None)
|
||||
{
|
||||
//18806 & 44255
|
||||
//the above offset takes into consideration midpoint, initial EU, AND final offset
|
||||
//with none we don't want the final offset, but we want the midpoint and initial EU
|
||||
offset = (-1D * midPointRemoval + aidc.InitialEU).ToString("F11");
|
||||
}
|
||||
|
||||
AdjustOffsetForEUAtMv(ref offset, aidc, midPointRemoval, scaler, diagnosticResult);
|
||||
if (measuredOffset != null)
|
||||
{
|
||||
return measuredOffset[channelIndex].ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return RunTestVariables.MaskEUMetaData ? "0" : offset;
|
||||
}
|
||||
}
|
||||
private static void AdjustOffsetForEUAtMv(ref string offset, AnalogInputDASChannel aidc, double midPointRemoval, Common.DAS.Concepts.DataScaler scaler,
|
||||
IDiagnosticResult diagnosticResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (null == aidc) { return; }
|
||||
if (null == scaler) { return; }
|
||||
|
||||
if (string.IsNullOrWhiteSpace(aidc.InitialOffset)) { return; }
|
||||
|
||||
var io = new InitialOffset();
|
||||
io.FromDbSerializeString(aidc.InitialOffset);
|
||||
if (io.Form != InitialOffsetTypes.EUAtMV) { return; }
|
||||
//DataScaler should take care of most of the work here, if we feed it in the final offset ADC it should adjust that by the eu@mv difference
|
||||
var eu = scaler.GetEU((short)diagnosticResult.FinalOffsetADC);
|
||||
offset = ( eu - midPointRemoval).ToString("F11");
|
||||
}
|
||||
catch( Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes the TMT file to the S6A
|
||||
/// 14531 Implement TMATS support for S6A stream on boot
|
||||
/// </summary>
|
||||
public virtual void WriteTmtFile(IDASCommunication das, Dictionary<IDASCommunication, ushort> dataChannelIds, Dictionary<IDASCommunication, ushort> timeChannelIds, int dasIndex, Common.Interface.DASFactory.ICommunication communication,
|
||||
float[] scaleFactors = null, float[] ranges = null, float[] measuredOffset = null)
|
||||
{
|
||||
var template = GetTMTTemplate(Template);
|
||||
var globalKeys = Enum.GetValues(typeof(TMTGlobalKeys)).Cast<TMTGlobalKeys>()
|
||||
.ToArray();
|
||||
// FB 26736 Get time & data channel Ids from ddictionary based on serial
|
||||
ushort? dataChannelId = null;
|
||||
ushort? timeChannelId = null;
|
||||
var dataChannelIdPair = dataChannelIds.FirstOrDefault(p => p.Key.SerialNumber == SerialNumber);
|
||||
|
||||
var bitsPerFrame = Constants.BITS_PER_MINOR_FRAME_S6A;
|
||||
if (dataChannelIdPair.Key != null)
|
||||
{
|
||||
dataChannelId = dataChannelIdPair.Value;
|
||||
if (dataChannelIdPair.Key.IsTSRAIR()) { bitsPerFrame = Constants.BITS_PER_MINOR_FRAME_TSRAIR; }
|
||||
}
|
||||
|
||||
var timeChannelIdPair = timeChannelIds.FirstOrDefault(p => p.Key.SerialNumber == SerialNumber);
|
||||
if (timeChannelIdPair.Key != null)
|
||||
{
|
||||
timeChannelId = timeChannelIdPair.Value;
|
||||
}
|
||||
|
||||
|
||||
foreach (var key in globalKeys)
|
||||
{
|
||||
TMTTemplate.UpdateGlobalField(das, key, template, ConfigData, SerialNumber, timeChannelId, dataChannelId, dasIndex, bitsPerFrame);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MaxChannels; i++)
|
||||
{
|
||||
UpdateTMTChannel(template, i, scaleFactors, ranges, measuredOffset);
|
||||
}
|
||||
WriteTMTFile((ICommunication)das, template.GetAllLines(), das.TestDirectory);
|
||||
}
|
||||
public static void WriteTMTFile(ICommunication communication, string [] allLines,
|
||||
string testDirectory)
|
||||
{
|
||||
var sfd = new SetFileData(communication);
|
||||
var byteData = Encoding.UTF8.GetBytes(string.Join("\n", allLines));
|
||||
if (byteData.Length >= InformationCommands.MAX_FILE_LENGTH_ID100)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(
|
||||
$"TMT File is too large, {byteData.Length} >= {InformationCommands.MAX_FILE_LENGTH_ID100}");
|
||||
}
|
||||
|
||||
//15241 store uploaded TMATS file to DASConfigs folder
|
||||
WriteTMTFilePC(byteData, testDirectory, communication.SerialNumber);
|
||||
sfd.StartByteCount = 0;
|
||||
sfd.FileID = SetFileData.TMT_FILE_ID;
|
||||
|
||||
sfd.Data = Constants.XML_STORE_MAGIC_BYTES;
|
||||
sfd.SyncExecute();
|
||||
|
||||
//Store Header - data length
|
||||
var maxLen = Convert.ToUInt32(byteData.Length);
|
||||
sfd.StartByteCount = Constants.XML_HEADER_LENGTH / 2;
|
||||
sfd.FileID = SetFileData.TMT_FILE_ID;
|
||||
sfd.Data = BitConverter.GetBytes(maxLen);
|
||||
sfd.SyncExecute();
|
||||
|
||||
//Store Data
|
||||
for (uint i = 0; i < maxLen; i += (uint)sfd.MaximumFileStreamBytes)
|
||||
{
|
||||
long array_size = sfd.MaximumFileStreamBytes;
|
||||
if ((i + sfd.MaximumFileStreamBytes) > maxLen)
|
||||
{
|
||||
array_size = maxLen - i;
|
||||
}
|
||||
|
||||
var dataToSend = new byte[array_size];
|
||||
Array.Copy(byteData, i, dataToSend, 0, array_size);
|
||||
|
||||
sfd.Data = dataToSend;
|
||||
sfd.FileID = SetFileData.TMT_FILE_ID;
|
||||
sfd.StartByteCount = i + Constants.XML_HEADER_LENGTH;
|
||||
sfd.SyncExecute();
|
||||
}
|
||||
}
|
||||
//FB 30035 Refactored to create TmtFile object and return it based on profile
|
||||
/// <summary>
|
||||
/// returns a new template file object given a udp stream profile
|
||||
/// 29430 Store TMAT file that corresponds to Stream Profile
|
||||
/// </summary>
|
||||
/// <param name="profile"></param>
|
||||
/// <param name="serialNumber"></param>
|
||||
/// <param name="dasInfo"></param>
|
||||
/// <param name="configData"></param>
|
||||
/// <param name="channelDiagnosticsResults"></param>
|
||||
/// <returns></returns>
|
||||
public static ITmtFile GetS6ATMATSFileTypeForProfile(UDPStreamProfile profile, string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults)
|
||||
{
|
||||
switch (profile)
|
||||
{
|
||||
case UDPStreamProfile.CH10_ANALOG:
|
||||
case UDPStreamProfile.CH10_ANALOG_2HDR:
|
||||
return new Slice6AirAnalogTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
case UDPStreamProfile.CH10_PCM128_MM:
|
||||
case UDPStreamProfile.CH10_PCM_128BIT_2HDR:
|
||||
case UDPStreamProfile.CH10_PCM_STANDARD:
|
||||
case UDPStreamProfile.CH10_PCM_STANDARD_2HDR:
|
||||
case UDPStreamProfile.CH10_PCM_SUPERCOM:
|
||||
case UDPStreamProfile.CH10_PCM_SUPERCOM_2HDR:
|
||||
return new Slice6AirPcmTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
//FB 28292 "TmNS 144 bit PCM" and "TmNS Supercom 4x ADC PCM" profiles
|
||||
case UDPStreamProfile.TMNS_PCM_STANDARD:
|
||||
return new Slice6AirTmNs144PcmTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
case UDPStreamProfile.TMNS_PCM_SUPERCOM:
|
||||
return new Slice6AirTmNsSuperCom4XPcmTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
default:
|
||||
APILogger.Log($"GetTMATSTypeForProfile unsupported profile type: {profile}");
|
||||
return new Slice6AirAnalogTmtFile(serialNumber, dasInfo, configData, channelDiagnosticsResults);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public class Slice6AirAnalogTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirAnalogTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_ANALOG;
|
||||
}
|
||||
}
|
||||
|
||||
public class Slice6AirPcmTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirPcmTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_PCM;
|
||||
}
|
||||
}
|
||||
|
||||
public class Slice6AirTmNs144PcmTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirTmNs144PcmTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_TmNS_144PPCM;
|
||||
}
|
||||
}
|
||||
|
||||
public class Slice6AirTmNsSuperCom4XPcmTmtFile : TmtFile
|
||||
{
|
||||
public Slice6AirTmNsSuperCom4XPcmTmtFile(string serialNumber, IInfoResult dasInfo, IConfigurationData configData, IDiagnosticResult[] channelDiagnosticsResults) :
|
||||
base(serialNumber, dasInfo, configData, channelDiagnosticsResults)
|
||||
{
|
||||
MaxChannels = 6;
|
||||
Template = TMAT_TEMPLATES.S6Air_TmNS_SuperCom4xPCM;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,108 @@
|
||||
|
||||
|
||||
using DASFactoryDb.Download;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Download;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// This class describes what should be downloaded from the DAS to the PC.
|
||||
/// </summary>
|
||||
public class DownloadRequest : IDownloadRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Setting the DASChannelNumber property of this object to this constant value will
|
||||
/// download all channels from the DAS. Currently, this is the only option that is supported
|
||||
/// so DASChannelNumber MUST be equal to this value.
|
||||
/// </summary>
|
||||
public const byte ALL_CHANNELS = 0xFF;
|
||||
|
||||
/// <summary>
|
||||
/// From which event do we want to download data?
|
||||
/// </summary>
|
||||
public ushort EventNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Which channel? (set to ALL_CHANNELS for all)
|
||||
/// </summary>
|
||||
public byte DASChannelNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The first sample you want.
|
||||
/// </summary>
|
||||
public virtual ulong StartSample { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The last sample you want.
|
||||
/// </summary>
|
||||
public virtual ulong EndSample { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is used for sub-sampling data, 0 (or 1) means don't sub-sample, 2 means
|
||||
/// give me every other sample and so on. The number of samples requested
|
||||
/// (EndSample-StartSample+1) must be an multiple of SamplesToSkip.
|
||||
/// </summary>
|
||||
public ulong SamplesToSkip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public double StartRecordTimestampSec { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public double TriggerTimestampSec { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public double StartRecordTimestampNanoSec { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public double TriggerTimestampNanoSec { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool PTPMasterSync { get; set; }
|
||||
|
||||
public static void SetWhatToDownload(IDASCommunication das, IDownloadRequest request, bool bSetInDb)
|
||||
{
|
||||
if (null != request)
|
||||
{
|
||||
APILogger.Log($"WhatToDownload = Event: {request.EventNumber}, StartSample: {request.StartSample}, EndSample: {request.EndSample}");
|
||||
}
|
||||
das.WhatToDownload = request;
|
||||
if (!bSetInDb || !DASFactoryDb.DbWrapper.Connected) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
Download.ClearExistingDownloadRequests(das.RecordId);
|
||||
if (null != request)
|
||||
{
|
||||
Download.DownloadRequestInsert(das.RecordId,
|
||||
request.EventNumber,
|
||||
request.DASChannelNumber,
|
||||
request.StartSample,
|
||||
request.EndSample,
|
||||
request.SamplesToSkip,
|
||||
request.StartRecordTimestampSec,
|
||||
request.TriggerTimestampSec,
|
||||
request.StartRecordTimestampNanoSec,
|
||||
request.TriggerTimestampNanoSec,
|
||||
request.PTPMasterSync);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// The delegate that we call with the callback data
|
||||
/// </summary>
|
||||
/// <param name="data">The actual callback data</param>
|
||||
public delegate void ServiceCallback(ServiceCallbackData data);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// diagnostics interface for a DAS unit, see <see cref="IDASCommunication" />.
|
||||
/// </summary>
|
||||
public interface IDiagnos
|
||||
{
|
||||
DiagnosticsActions[] ChannelDiagnostics { get; set; }
|
||||
DiagnosticsResult[] ChannelDiagnosticsResults { get; set; }
|
||||
ModuleDiagnosticsResult[] ModuleDiagnosticsResults { get; set; }
|
||||
BaseInputValues BaseInput { get; set; }
|
||||
ClockSyncStatus DASClockSyncStatus { get; set; }
|
||||
ArmCheckActions ArmCheckActions { get; set; }
|
||||
ArmCheckResults ArmCheckResults { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class TriggerCheckResult : ITriggerCheckResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Is the status good on the DAS?
|
||||
/// </summary>
|
||||
public bool IsStatusGood { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is the start record line currently active on the DAS?
|
||||
/// </summary>
|
||||
public bool IsStartRecordActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Has the start record line been active at any point after arm?
|
||||
/// </summary>
|
||||
public bool HasStartRecordBeenActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is the trigger currently active?
|
||||
/// </summary>
|
||||
public bool IsTriggered { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Has the trigger line been active at any point after arm?
|
||||
/// </summary>
|
||||
public bool HasTriggered { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using DTS.Common.Enums;
|
||||
using System.Text;
|
||||
using DTS.Common.Utilities;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for storing/applying Streaming output settings as a channel
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class StreamOutputDASChannel : OutputDASChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// CTOR to populate a channel's owning module and channel WRT that module. Calls
|
||||
/// base class CTOR.
|
||||
/// </summary>
|
||||
/// <param name="owner">Module that contains this channel.</param>
|
||||
/// <param name="channelNumber">ChannelNumber of this channel WRT owning module.</param>
|
||||
public StreamOutputDASChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
}
|
||||
|
||||
public StreamOutputDASChannel()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Serial number of the sensor.
|
||||
/// </summary>
|
||||
public string SerialNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the hardware channel
|
||||
/// </summary>
|
||||
public string HardwareChannelName { get; set; }
|
||||
|
||||
public string UDPProfileName { get; set; } = UDPStreamProfile.CH10_ANALOG_2HDR.ToString();
|
||||
public ushort UDPTimeChannelId { get; set; }
|
||||
public ushort UDPDataChannelId { get; set; }
|
||||
public ushort IRIGTimeDataPacketIntervalMs { get; set; }
|
||||
/// <summary>
|
||||
/// time between sending TMATS information while streaming
|
||||
/// http://manuscript.dts.local/f/cases/29987/Add-CG-DP-TMATS-interval-UI-support
|
||||
/// </summary>
|
||||
public ushort TMATSIntervalMs { get; set; } = StreamOutputRecord.DEFAULT_TMATS_INTERVAL_MS;
|
||||
public string UDPAddress { get; set; } = string.Empty;
|
||||
public uint[] UDPTmNSConfig { get; set; } = new uint[8];
|
||||
|
||||
/// <summary>
|
||||
/// If the channel has a serial number in the SerialNumber field, it is "Configured".
|
||||
/// </summary>
|
||||
public override bool IsConfigured()
|
||||
{
|
||||
return !string.IsNullOrEmpty(SerialNumber);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Stream{ModuleChannelNumber}";
|
||||
}
|
||||
public override void WriteXml(XmlWriter writer)
|
||||
{
|
||||
base.WriteXml(writer);
|
||||
|
||||
// SerialNumber
|
||||
XMLHelper.PutString(writer, "SerialNumber", SerialNumber);
|
||||
XMLHelper.PutString(writer, "HardwareChannelName", HardwareChannelName);
|
||||
XMLHelper.PutString(writer, "UDPProfileName", UDPProfileName);
|
||||
XMLHelper.PutString(writer, "UDPTimeChannelId", UDPTimeChannelId.ToString());
|
||||
XMLHelper.PutString(writer, "UDPDataChannelId", UDPDataChannelId.ToString());
|
||||
XMLHelper.PutString(writer, "IRIGTimeDataPacketIntervalMs", IRIGTimeDataPacketIntervalMs.ToString());
|
||||
XMLHelper.PutString(writer, TMATS_INTERVAL_MS_TAG, TMATSIntervalMs.ToString());
|
||||
XMLHelper.PutString(writer, "UDPAddress", UDPAddress.ToString());
|
||||
XMLHelper.PutString(writer, "UDPTmNSConfig", ArrayToString.ArrayObjectToString(UDPTmNSConfig));
|
||||
}
|
||||
private const string SERIALNUMBER_TAG = "SerialNumber";
|
||||
private const string HARDWARECHANNELNAME_TAG = "HardwareChannelName";
|
||||
private const string UDPPROFILENAME_TAG = "UDPProfileName";
|
||||
private const string UDPTIMECHANNELID_TAG = "UDPTimeChannelId";
|
||||
private const string UDPDATACHANNELID_TAG = "UDPDataChannelId";
|
||||
private const string IRIGTIMEDATAPACKETINTERVALMS_TAG = "IRIGTimeDataPacketIntervalMs";
|
||||
private const string UDPADDRESS_TAG = "UDPAddress";
|
||||
private const string UDPTMNSCONFIG_TAG = "UDPTmNSConfig";
|
||||
private const string TMATS_INTERVAL_MS_TAG = "TMATSIntervalMs";
|
||||
protected override void HandleElement(XmlReader reader)
|
||||
{
|
||||
base.HandleElement(reader);
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
var value = string.Empty;
|
||||
switch (reader.Name)
|
||||
{
|
||||
case SERIALNUMBER_TAG:
|
||||
SerialNumber = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case HARDWARECHANNELNAME_TAG:
|
||||
HardwareChannelName = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case UDPPROFILENAME_TAG:
|
||||
UDPProfileName = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case UDPTIMECHANNELID_TAG:
|
||||
UDPTimeChannelId = Convert.ToUInt16(XMLHelper.GetInt(reader));
|
||||
break;
|
||||
case UDPDATACHANNELID_TAG:
|
||||
UDPDataChannelId = Convert.ToUInt16(XMLHelper.GetInt(reader));
|
||||
break;
|
||||
case IRIGTIMEDATAPACKETINTERVALMS_TAG:
|
||||
IRIGTimeDataPacketIntervalMs = Convert.ToUInt16(XMLHelper.GetInt(reader));
|
||||
break;
|
||||
case UDPADDRESS_TAG:
|
||||
UDPAddress = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case UDPTMNSCONFIG_TAG:
|
||||
UDPTmNSConfig = ArrayToString.StringToUIntArray(XMLHelper.GetString(reader));
|
||||
break;
|
||||
case TMATS_INTERVAL_MS_TAG:
|
||||
TMATSIntervalMs = Convert.ToUInt16(XMLHelper.GetInt(reader));
|
||||
break;
|
||||
default:
|
||||
// let child handle it
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public enum State
|
||||
{
|
||||
Prepare,
|
||||
HardwareDiscovery,
|
||||
HardwareDiscoveryStart,
|
||||
Configure,
|
||||
ConfigureStart,
|
||||
Diagnose,
|
||||
Realtime,
|
||||
Arming,
|
||||
Arm,
|
||||
Download,
|
||||
RealtimeStart,
|
||||
DownloadStart
|
||||
}
|
||||
|
||||
public class States
|
||||
{
|
||||
private static readonly States instance = new States();
|
||||
private Dictionary<State, IDASState> _statesDict = new Dictionary<State, IDASState>();
|
||||
private Dictionary<State, IDASStateWithSelector> _statesSelectableDict = new Dictionary<State, IDASStateWithSelector>();
|
||||
|
||||
// Explicit static constructor to tell C# compiler
|
||||
// not to mark type as beforefieldinit
|
||||
// https://csharpindepth.com/articles/singleton
|
||||
static States()
|
||||
{
|
||||
}
|
||||
|
||||
public IDASState Prepare { get => _statesDict[State.Prepare]; }
|
||||
public IDASState HardwareDiscovery { get => _statesDict[State.HardwareDiscovery]; }
|
||||
public IDASStateWithSelector HardwareDiscoveryStart { get => _statesSelectableDict[State.HardwareDiscoveryStart]; }
|
||||
public IDASState Download { get => _statesDict[State.Download]; }
|
||||
public IDASStateWithSelector DownloadStart { get => _statesSelectableDict[State.DownloadStart]; }
|
||||
public IDASStateWithSelector Diagnose { get => _statesSelectableDict[State.Diagnose]; }
|
||||
public IDASStateWithSelector Configure { get => _statesSelectableDict[State.Configure]; }
|
||||
public IDASState Arming { get => _statesDict[State.Arming]; }
|
||||
public IDASState Arm { get => _statesDict[State.Arm]; }
|
||||
public IDASState Realtime { get => _statesDict[State.Realtime]; }
|
||||
public IDASStateWithSelector RealtimeStart { get => _statesSelectableDict[State.RealtimeStart]; }
|
||||
public IDASStateWithSelector ConfigureStart
|
||||
{
|
||||
get => _statesSelectableDict[State.ConfigureStart];
|
||||
}
|
||||
|
||||
public static void SetDASFactory(IDASFactory dasFactory)
|
||||
{
|
||||
foreach (var enumState in Instance._statesDict)
|
||||
{
|
||||
enumState.Value.DASFactory = dasFactory;
|
||||
}
|
||||
|
||||
foreach (var enumState in Instance._statesSelectableDict)
|
||||
{
|
||||
enumState.Value.DASFactory = dasFactory;
|
||||
}
|
||||
}
|
||||
private States()
|
||||
{
|
||||
AddState(State.Prepare, new Prepare());
|
||||
AddState(State.HardwareDiscovery, new HardwareDiscovery());
|
||||
AddState(State.HardwareDiscoveryStart, new HardwareDiscoveryStart());
|
||||
AddState(State.Configure, new Configure());
|
||||
AddState(State.Download, new Download());
|
||||
AddState(State.Diagnose, new Diagnose());
|
||||
AddState(State.Arming, new Arming());
|
||||
AddState(State.Arm, new Arm());
|
||||
AddState(State.Realtime, new Realtime());
|
||||
AddState(State.ConfigureStart, new ConfigureStart());
|
||||
AddState(State.RealtimeStart, new RealtimeStart());
|
||||
AddState(State.DownloadStart, new DownloadStart());
|
||||
}
|
||||
private void AddState<T>(State state, T dasState)
|
||||
{
|
||||
if (dasState is IDASStateWithSelector)
|
||||
{
|
||||
_statesSelectableDict.Add(state, (IDASStateWithSelector)dasState);
|
||||
return;
|
||||
}
|
||||
_statesDict.Add(state, (IDASState)dasState);
|
||||
}
|
||||
public IDASState GetIDASState(State state)
|
||||
{
|
||||
if (_statesDict.ContainsKey(state))
|
||||
{
|
||||
return _statesDict[state];
|
||||
}
|
||||
if (_statesSelectableDict.ContainsKey(state))
|
||||
{
|
||||
return _statesSelectableDict[state];
|
||||
}
|
||||
throw new InvalidOperationException("Undefined State");
|
||||
}
|
||||
|
||||
public static States Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for SQUIB channels.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class OutputTOMDigitalChannel : DigitalOutputDASChannel
|
||||
{
|
||||
public DigitalOutputModes OutputMode { get; set; } = DigitalOutputModes.NONE;
|
||||
|
||||
public double DelayMS { get; set; } = 0D;
|
||||
|
||||
public bool LimitDuration { get; set; } = false;
|
||||
|
||||
public double DurationMS { get; set; } = 0D;
|
||||
|
||||
public string DigitalChannelDescription { get; set; } = "";
|
||||
|
||||
public string LastModifiedBy { get; set; } = "";
|
||||
|
||||
public DateTime LastModified { get; set; }
|
||||
|
||||
public bool LocalOnly { get; set; } = false;
|
||||
|
||||
public string HardwareChannelName { get; set; }
|
||||
|
||||
public OutputTOMDigitalChannel(XmlReader reader)
|
||||
{
|
||||
IDs = new[] { new EID() };
|
||||
ReadXml(reader);
|
||||
}
|
||||
|
||||
public OutputTOMDigitalChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
}
|
||||
|
||||
public OutputTOMDigitalChannel()
|
||||
{
|
||||
}
|
||||
|
||||
public override void WriteXml(XmlWriter writer)
|
||||
{
|
||||
base.WriteXml(writer);
|
||||
|
||||
XMLHelper.PutDouble(writer, "DelayMS", DelayMS);
|
||||
XMLHelper.PutString(writer, "ChannelDescription", DigitalChannelDescription);
|
||||
XMLHelper.PutDouble(writer, "DurationMS", DurationMS);
|
||||
XMLHelper.PutString(writer, "OutputMode", OutputMode.ToString());
|
||||
XMLHelper.PutBool(writer, "LimitDuration", LimitDuration);
|
||||
}
|
||||
public int Version { get; set; }
|
||||
|
||||
public DateTime Date { get; }
|
||||
|
||||
|
||||
public override void WriteXmlCRC32(XmlWriter writer)
|
||||
{
|
||||
base.WriteXmlCRC32(writer);
|
||||
|
||||
XMLHelper.PutDouble(writer, "DelayMS", DelayMS);
|
||||
XMLHelper.PutString(writer, "ChannelDescription", DigitalChannelDescription);
|
||||
XMLHelper.PutDouble(writer, "DurationMS", DurationMS);
|
||||
XMLHelper.PutString(writer, "OutputMode", OutputMode.ToString());
|
||||
XMLHelper.PutBool(writer, "LimitDuration", LimitDuration);
|
||||
}
|
||||
private const string OUTPUTMODE_TAG = "OutputMode";
|
||||
private const string CHANNELDESCRIPTION_TAG = "ChannelDescription";
|
||||
private const string DELAYMS_TAG = "DelayMS";
|
||||
private const string DURATIONMS_TAG = "DurationMS";
|
||||
private const string LIMITDURATION_TAG = "LimitDuration";
|
||||
protected override void HandleElement(XmlReader reader)
|
||||
{
|
||||
base.HandleElement(reader);
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case OUTPUTMODE_TAG:
|
||||
OutputMode = (DigitalOutputModes)Enum.Parse(typeof(DigitalOutputModes), XMLHelper.GetString(reader));
|
||||
break;
|
||||
case CHANNELDESCRIPTION_TAG:
|
||||
DigitalChannelDescription = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case DELAYMS_TAG:
|
||||
DelayMS = XMLHelper.GetDouble(reader);
|
||||
break;
|
||||
case DURATIONMS_TAG:
|
||||
DurationMS = XMLHelper.GetDouble(reader);
|
||||
break;
|
||||
case LIMITDURATION_TAG:
|
||||
LimitDuration = XMLHelper.GetBool(reader);
|
||||
break;
|
||||
default:
|
||||
// let child handle it
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsConfigured()
|
||||
{
|
||||
return OutputMode != DigitalOutputModes.NONE && !string.IsNullOrEmpty(DigitalChannelDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
using System.Threading;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.ICommunication;
|
||||
using System;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public partial class TDAS<T> : Communication<T>,
|
||||
IDASCommunication,
|
||||
IConfigurationActions,
|
||||
IDiagnosticsActions,
|
||||
ITriggerCheckActions,
|
||||
IRealTimeActions,
|
||||
IArmActions,
|
||||
IDownloadActions where T : IConnection, new()
|
||||
{
|
||||
#region Trigger check
|
||||
void ITriggerCheckActions.PreStartTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
void ITriggerCheckActions.PostStartTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
private class TriggerCheckPacket : TDASServiceAsyncInfo
|
||||
{
|
||||
public TriggerCheckPacket(ServiceCallback cb, object ud)
|
||||
: base(cb, ud)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void ITriggerCheckActions.StartTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
LaunchAsyncWorker("TDAS.StartTriggerCheck", AsyncStartTriggerCheck, info);
|
||||
}
|
||||
|
||||
private void AsyncStartTriggerCheck(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is TriggerCheckPacket info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (null == DASArmStatus)
|
||||
{
|
||||
SetDASArmStatus(new ArmStatus(), true);
|
||||
}
|
||||
var status = DASArmStatus;
|
||||
try
|
||||
{
|
||||
status.IsArmed = true;
|
||||
status.IsRecording = false;
|
||||
status.IsTriggered = false;
|
||||
foreach (var module in DASInfo.Modules)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (module.TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsG5())
|
||||
{
|
||||
var testTrigger = new Command.TDAS.TestTrigger(this)
|
||||
{
|
||||
ModuleIndex = module.ModuleArrayIndex,
|
||||
SubCommand = Command.TDAS.TestTrigger.SubCommandValues.ARM
|
||||
};
|
||||
testTrigger.SyncExecute();
|
||||
break;
|
||||
}
|
||||
|
||||
var qsn = new Command.TDAS.QuerySerialNumberBroadcast(this, module.ModuleArrayIndex);
|
||||
qsn.SyncExecute();
|
||||
|
||||
var ttb = new Command.TDAS.TestTriggerBroadcast(this, module.ModuleArrayIndex)
|
||||
{
|
||||
SubCommand = Command.TDAS.TestTrigger.SubCommandValues.ARM
|
||||
};
|
||||
ttb.SyncExecute();
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
SetDASArmStatus(status, true);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//assuming this is for logging purposes...unknown
|
||||
var ta = new Command.TDAS.TestAll(this) { Mode = Command.TDAS.TestAllCommandString.Modes.CURR };
|
||||
ta.SyncExecute();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
info.Success();
|
||||
}
|
||||
|
||||
void ITriggerCheckActions.DoTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
LaunchAsyncWorker("TDAS.DoTriggercheck", AsyncDoTriggerCheck, info);
|
||||
}
|
||||
void ITriggerCheckActions.DoStartCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
LaunchAsyncWorker("TDAS.DoStartcheck", AsyncDoStartCheck, info);
|
||||
}
|
||||
private void AsyncDoStartCheck(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is TriggerCheckPacket info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (null == DASArmStatus)
|
||||
{
|
||||
SetDASArmStatus(new ArmStatus(), false);
|
||||
}
|
||||
var status = DASArmStatus;
|
||||
try
|
||||
{
|
||||
var ta = new Command.TDAS.TestAll(this) { Mode = Command.TDAS.TestAllCommandString.Modes.PREV };
|
||||
try
|
||||
{
|
||||
ta.SyncExecute();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ta.StartedRecordingFlag == DFConstantsAndEnums.VoltageStatusColor.Yellow
|
||||
|| ta.StartedRecordingFlag == DFConstantsAndEnums.VoltageStatusColor.Red)
|
||||
{
|
||||
status.IsRecording = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
StartRecord = false;
|
||||
}
|
||||
|
||||
if (DASArmStatus.IsRecording)
|
||||
{
|
||||
status.IsArmed = false;
|
||||
}
|
||||
status.IsArmed = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
SetDASArmStatus(status, true);
|
||||
}
|
||||
|
||||
info.Success();
|
||||
}
|
||||
|
||||
void ITriggerCheckActions.DoTriggerCheckSync()
|
||||
{
|
||||
//this function was created as part of
|
||||
//5211 Add check to ECM event line during ArmChecklist
|
||||
//however to minimize impact since the issue doesn't affect TDAS
|
||||
//I'll not make the changes to TDAS trigger check/armchecklist checks
|
||||
//instead for now I'll leave it as is
|
||||
//since this function shouldn't be used (unless we make the changes above), I'll leave it
|
||||
//with an exception to warn anyone that hooks it up not realizing the issue
|
||||
throw new NotImplementedException("DoTriggerCheckSync is not implemented for TDAS");
|
||||
}
|
||||
private void AsyncDoTriggerCheck(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is TriggerCheckPacket info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var ta = new Command.TDAS.TestAll(this) { Mode = Command.TDAS.TestAllCommandString.Modes.PREV };
|
||||
ta.SyncExecute();
|
||||
|
||||
if (ta.TriggerFlag == DFConstantsAndEnums.VoltageStatusColor.Red
|
||||
|| ta.TriggerFlag == DFConstantsAndEnums.VoltageStatusColor.Yellow)
|
||||
{
|
||||
DASArmStatus.IsTriggered = true;
|
||||
SetDASArmStatus();
|
||||
try
|
||||
{
|
||||
var status = new ArmStatus();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var module in DASInfo.Modules)
|
||||
{
|
||||
if (IsG5() && 0 < module.ModuleArrayIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (module.TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var testTrigger = new Command.TDAS.TestTrigger(this, 5000);
|
||||
testTrigger.ModuleIndex = module.ModuleArrayIndex;
|
||||
testTrigger.SubCommand = Command.TDAS.TestTrigger.SubCommandValues.STATUS;
|
||||
try
|
||||
{
|
||||
testTrigger.SyncExecute();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Module probably timed out because it is still armed and never responded to the rack trigger/event line.
|
||||
status.IsArmed = true;
|
||||
status.IsTriggered = false;
|
||||
info.Error(module.SerialNumber + " did not trigger, but other modules did");
|
||||
return;
|
||||
}
|
||||
|
||||
if (testTrigger.TriggerStatus == Command.TDAS.TestTrigger.StatusValues.OFF)
|
||||
{
|
||||
status.IsTriggered = true;
|
||||
status.IsArmed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (status.IsTriggered)
|
||||
{
|
||||
info.Error(module.SerialNumber + " did not trigger, but other modules did");
|
||||
return;
|
||||
}
|
||||
|
||||
status.IsTriggered = false;
|
||||
status.IsArmed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally { SetDASArmStatus(status, true); }
|
||||
|
||||
info.Success();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info.Success();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
info.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
void ITriggerCheckActions.CancelTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new TriggerCheckPacket(callback, userData);
|
||||
LaunchAsyncWorker("TDAS.CancelTriggerCheck", AsyncCancelTriggerCheck, info);
|
||||
}
|
||||
|
||||
private void AsyncCancelTriggerCheck(object asyncInfo)
|
||||
{
|
||||
if (!(asyncInfo is TriggerCheckPacket info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
foreach (var m in DASInfo.Modules)
|
||||
{
|
||||
if (m.SerialNumber == "EMPTY" || m.TypeOfModule == DFConstantsAndEnums.ModuleType.EMPTYBANK) continue;
|
||||
if (IsG5())
|
||||
{
|
||||
var testTrigger = new Command.TDAS.TestTrigger(this);
|
||||
testTrigger.ModuleIndex = m.ModuleArrayIndex;
|
||||
testTrigger.SubCommand = Command.TDAS.TestTrigger.SubCommandValues.OFF;
|
||||
testTrigger.SyncExecute();
|
||||
|
||||
var qsn = new Command.TDAS.QuerySerialNumber(this);
|
||||
qsn.ModuleIndex = m.ModuleArrayIndex;
|
||||
qsn.SyncExecute();
|
||||
break;
|
||||
}
|
||||
var qsc = new Command.TDAS.QuerySerialNumberBroadcast(this, m.ModuleArrayIndex);
|
||||
qsc.SyncExecute();
|
||||
|
||||
var tbc = new Command.TDAS.TestTriggerBroadcast(this, m.ModuleArrayIndex);
|
||||
tbc.SubCommand = Command.TDAS.TestTrigger.SubCommandValues.OFF;
|
||||
tbc.SyncExecute();
|
||||
|
||||
var qsnb = new Command.TDAS.QuerySerialNumberBroadcast(this, m.ModuleArrayIndex);
|
||||
qsnb.SyncExecute();
|
||||
break;
|
||||
}
|
||||
info.Success();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
info.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DataRecorders;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class HardwareDiscoveryParameters
|
||||
{
|
||||
public bool ReadIds { get; set; } = false;
|
||||
/// <summary>
|
||||
/// ip addresses that we expliticly want to connect to
|
||||
/// if not specified in known tdas or known slice ip addresses will try connecting as both slice and tdas
|
||||
/// </summary>
|
||||
public string[] Addresses { get; set; } = new string[0];
|
||||
/// <summary>
|
||||
/// range of address to ping
|
||||
/// items must be in the form of aaa.bbb.ccc.ddd
|
||||
/// will ping all addresses iterating from item1 upto the 4th byte on item 2
|
||||
/// any ip that responds will be added to ips to connect to
|
||||
/// if it's not known whether it's a SLICE or TDAS then will be added to both lists to connect to
|
||||
/// </summary>
|
||||
public Tuple<string, string>[] AddressRanges { get; set; } = new Tuple<string, string>[0];
|
||||
/// <summary>
|
||||
/// ip address that are known to be TDAS, so we don't have to try connecting to as a slice
|
||||
/// </summary>
|
||||
public string[] KnownTDASIPAddresses { get; set; } = new string[0];
|
||||
/// <summary>
|
||||
/// ip addresses that are known to be SLICE, so we don't have to try connecting to as a TDAS
|
||||
/// </summary>
|
||||
public string[] KnownSLICEIPAddresses { get; set; } = new string[0];
|
||||
/// <summary>
|
||||
/// controls whether we should remain in state or not
|
||||
/// sometimes the user just wants to see the hardware detected and not go onto resolve channels or any additional
|
||||
/// actions
|
||||
/// </summary>
|
||||
public bool ProceedWhenDone { get; set; } = false;
|
||||
/// <summary>
|
||||
/// whether all das are required to be found
|
||||
/// </summary>
|
||||
public bool RequireAllDASFound { get; set; } = false;
|
||||
/// <summary>
|
||||
/// whether to proceed to download state after completion
|
||||
/// </summary>
|
||||
public bool GoToDownload { get; set; } = false;
|
||||
/// <summary>
|
||||
/// controls whether we are ping and connecting or just pinging ...
|
||||
/// </summary>
|
||||
public bool Connect { get; set; } = false;
|
||||
/// <summary>
|
||||
/// controls whether UDP/Multicast discovery should be performed
|
||||
/// </summary>
|
||||
public bool UseMulticastDiscover { get; set; } = false;
|
||||
public int ConnectTimeoutMS { get; set; } = 30000; //30 seconds
|
||||
/// <summary>
|
||||
/// whether to run auto-sense or not
|
||||
/// note that DisableAutoSense overrules this setting
|
||||
/// </summary>
|
||||
public bool RunAutoSense { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// specific device to query, when present
|
||||
/// this is used to signal that there's a device already attached that
|
||||
/// we want to requery
|
||||
/// this is done when the device configuration is changed
|
||||
/// </summary>
|
||||
public IDASCommunication RequeryDevice { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// serial numbers that are required to connect
|
||||
/// </summary>
|
||||
public string[] RequiredSerials { get; set; } = new string[0];
|
||||
/// <summary>
|
||||
/// controls whether to perform hardware checks (voltage/memory/firmware/etc)
|
||||
/// after connecting to hardware
|
||||
/// </summary>
|
||||
public bool DoHardwareChecks { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// hardware that we expect to be connected once ping and connect completes
|
||||
/// used as part of DoHardwareChecks
|
||||
/// </summary>
|
||||
public IDASHardware[] ExpectedHardware { get; set; } = new IDASHardware[0];
|
||||
|
||||
public delegate bool UnitIsInDbDelegate(IDASCommunication das);
|
||||
public UnitIsInDbDelegate UnitIsInDbQuery { get; set; } = null;
|
||||
|
||||
public delegate string FirmwareExpectedVersionDelegate(IDASCommunication das);
|
||||
public FirmwareExpectedVersionDelegate UnitExpectedFirmwareQuery { get; set; } = null;
|
||||
|
||||
public delegate bool IsCalDateExpiredDelegate(IDASCommunication das);
|
||||
public IsCalDateExpiredDelegate CalDateExpiredQuery { get; set; } = null;
|
||||
|
||||
public delegate long UnitExpectedMaxMemoryDelegate(IDASCommunication das);
|
||||
public UnitExpectedMaxMemoryDelegate UnitExpectedMaxMemoryQuery { get; set; } = null;
|
||||
|
||||
public delegate void UpdateMaxMemoryDelegate(IDASCommunication das);
|
||||
public UpdateMaxMemoryDelegate UpdateMaxMemoryAction { get; set; } = null;
|
||||
/// <summary>
|
||||
/// whether to check the input/battery voltage for units or not
|
||||
/// </summary>
|
||||
public bool DoVoltageChecks { get; set; } = true;
|
||||
public void Reset()
|
||||
{
|
||||
ReadIds = false;
|
||||
Addresses = new string[0];
|
||||
AddressRanges = new Tuple<string, string>[0];
|
||||
ProceedWhenDone = false;
|
||||
RequireAllDASFound = false;
|
||||
KnownSLICEIPAddresses = new string[0];
|
||||
KnownTDASIPAddresses = new string[0];
|
||||
RequeryDevice = null;
|
||||
RequiredSerials = new string[0];
|
||||
DoHardwareChecks = false;
|
||||
ExpectedHardware = new IDASHardware[0];
|
||||
UnitIsInDbQuery = null;
|
||||
UnitExpectedFirmwareQuery = null;
|
||||
CalDateExpiredQuery = null;
|
||||
UnitExpectedMaxMemoryQuery = null;
|
||||
UpdateMaxMemoryAction = null;
|
||||
DoVoltageChecks = true;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"ReadIds={ReadIds.ToString()}");
|
||||
sb.AppendLine($"Addresses={string.Join(",", Addresses)}");
|
||||
sb.Append("AddressRanges=");
|
||||
for (int i = 0; i < AddressRanges.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Append($"({AddressRanges[i].Item1},{AddressRanges[i].Item2})");
|
||||
}
|
||||
sb.AppendLine();
|
||||
sb.AppendLine($"ProceedWhenDone={ProceedWhenDone.ToString()}");
|
||||
sb.AppendLine($"RequireAllDASFound={RequireAllDASFound.ToString()}");
|
||||
sb.AppendLine($"KnownSLICEIPAddresses={string.Join(",", KnownSLICEIPAddresses)}");
|
||||
sb.AppendLine($"KnownTDASIPAddresses={string.Join(",", KnownTDASIPAddresses)}");
|
||||
sb.Append("RequiryDevice=");
|
||||
if (null == RequeryDevice)
|
||||
{
|
||||
sb.AppendLine("null");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(RequeryDevice.SerialNumber);
|
||||
}
|
||||
|
||||
sb.AppendLine($"RequiredSerials={string.Join(",", RequiredSerials)}");
|
||||
sb.AppendLine($"DoHardwareChecks={DoHardwareChecks.ToString()}");
|
||||
sb.Append("ExpectedHardware=");
|
||||
for (var i = 0; i < ExpectedHardware.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Append(ExpectedHardware[i].SerialNumber);
|
||||
}
|
||||
sb.AppendLine();
|
||||
|
||||
sb.Append("UnitIsInDbQuery=");
|
||||
sb.AppendLine(null == UnitIsInDbQuery ? "[null]" : "[defined]");
|
||||
|
||||
sb.Append("UnitExpectedFirmwareQuery=");
|
||||
sb.AppendLine(null == UnitExpectedFirmwareQuery ? "[null]" : "[defined]");
|
||||
|
||||
sb.Append("CalDateExpiredQuery=");
|
||||
sb.AppendLine(null == CalDateExpiredQuery ? "[null]" : "[defined]");
|
||||
|
||||
sb.Append("UnitExpectedMaxMemoryQuery=");
|
||||
sb.AppendLine(null == UnitExpectedMaxMemoryQuery ? "[null]" : "[defined]");
|
||||
|
||||
sb.Append("UpdateMaxMemoryAction=");
|
||||
sb.AppendLine(null == UpdateMaxMemoryAction ? "[null]" : "[defined]");
|
||||
|
||||
sb.Append("DoVoltageChecks=");
|
||||
sb.AppendLine(DoVoltageChecks.ToString());
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Digital output channel.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class DigitalOutputDASChannel : OutputDASChannel
|
||||
{
|
||||
public DigitalOutputDASChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
}
|
||||
|
||||
public DigitalOutputDASChannel()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,898 @@
|
||||
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;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Communication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.StatusAndProgressBar;
|
||||
using DTS.Common.Utilities;
|
||||
using DTS.DASLib.Command.SLICE.DownloadCommands;
|
||||
using DTS.DASLib.Command.SLICEDB;
|
||||
using DTS.Common.Constant.DASSpecific;
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using DisableFaultChecking = DTS.DASLib.Command.SLICE.DisableFaultChecking;
|
||||
using DTS.Common;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class PowerPro<T> : PowerPro_Base<T>, //IDASReconfigure,
|
||||
IDASCommunication,
|
||||
IConfigurationActions,
|
||||
IDiagnosticsActions,
|
||||
ITriggerCheckActions,
|
||||
IRealTimeActions,
|
||||
IArmActions,
|
||||
IDownloadActions
|
||||
where T : IConnection, new()
|
||||
{
|
||||
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();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("failed to configure", SerialNumber, ex);
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
base.AsyncConfigure(configAsyncInfo);
|
||||
}
|
||||
public override string ConvertInputVoltage2BatteryCharging(double inputVoltage)
|
||||
{
|
||||
bool isCharging;
|
||||
var SwitchQuery = new QuerySwitchImmediate(this)
|
||||
{
|
||||
DeviceID = 0,
|
||||
Switch = (byte)Switches.PowerProSwitches.ChargePower
|
||||
};
|
||||
try
|
||||
{
|
||||
SwitchQuery.SyncExecute();
|
||||
if (1 == SwitchQuery.Setting)
|
||||
{
|
||||
isCharging = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isCharging = false;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
isCharging = false;
|
||||
}
|
||||
|
||||
// If we are charging
|
||||
if (isCharging)
|
||||
{
|
||||
return Resources.Charging;
|
||||
}
|
||||
// If we aren't charging and input is valid
|
||||
else if (inputVoltage > MinimumValidInputVoltage && inputVoltage < MaximumValidInputVoltage)
|
||||
{
|
||||
return Resources.NotCharging;
|
||||
}
|
||||
// If we're off input voltage and not charging
|
||||
else
|
||||
{
|
||||
return Resources.Discharging;
|
||||
}
|
||||
}
|
||||
public override bool? ChargingEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void IDASCommunication.SetIsStreamingSupported(bool supported)
|
||||
{
|
||||
IsStreamingSupported = false;
|
||||
}
|
||||
void IDASCommunication.ReadFirstUseDate()
|
||||
{
|
||||
IsFirstUseDateSupported = false;
|
||||
FirstUseDate = null;
|
||||
}
|
||||
/// <summary>
|
||||
/// indicates date of first use
|
||||
/// null indicates the hardware has not been used since calibration
|
||||
/// only valid when IsFirstUseDateSupported is true
|
||||
/// 15524 DAS "First Use Date"
|
||||
/// </summary>
|
||||
public DateTime? FirstUseDate { get; set; } = null;
|
||||
/// <summary>
|
||||
/// returns whether the hardware supports first use or not
|
||||
/// for hardware to support first use the hardware must support
|
||||
/// storage for user attributes in firmware and also have been
|
||||
/// calibrated by software support hardware first use
|
||||
/// 15524 DAS "First Use Date"
|
||||
/// </summary>
|
||||
public bool IsFirstUseDateSupported { get; set; } = false;
|
||||
/// <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 false;
|
||||
}
|
||||
public override bool IsBattery()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override bool IsTSRAIR()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public bool IsSlice6Air()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public bool IsSlice6AirTc()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public override bool IsScheduleEventCountSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void IConfigurationActions.SetFirstUseDate(DateTime firstUseDate, ServiceCallback callback,
|
||||
object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Error("Not supported");
|
||||
}
|
||||
/// <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 PowerProAsyncInfo(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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
void IArmActions.ReArm(ServiceCallback callback, object userData, bool autoArm, bool arm, bool repeatEnable)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(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 PowerProAsyncInfo(callback, userData);
|
||||
try
|
||||
{
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel))
|
||||
{
|
||||
var mppadc = new MeasurePowerProAllDiagnosticChannel(this);
|
||||
mppadc.SyncExecute(); // Just Log it for now
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); }
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
info.Success(); //TEMP until PowerPro Event line is not shorted
|
||||
return;
|
||||
}
|
||||
|
||||
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="whichResult"></param>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
void IDiagnosticsActions.PrepareForDiagnostics(uint diagnosticsSampleRateHz,
|
||||
float diagnosticsAAFilterFrequencyHz,
|
||||
PrePostResults whichResult,
|
||||
ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
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 PowerProAsyncInfo(callback, userData);
|
||||
DiagnosticsHasBeenRun = true;
|
||||
BaseInput = new BaseInputValues();
|
||||
GetBaseInputs(true);
|
||||
ClearChannelDiagnosticsResults(false);
|
||||
info.Success();
|
||||
}
|
||||
public override double MaximumValidInputVoltage { get; set; } = 26D;
|
||||
public void PerformArmChecks(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.PerformArmChecks", new WaitCallback(AsyncPerformArmChecks), info);
|
||||
}
|
||||
|
||||
private void AsyncPerformArmChecks(object o)
|
||||
{
|
||||
var info = o as PowerProAsyncInfo;
|
||||
var dasResults = new ArmCheckResults();
|
||||
info.Progress(25);
|
||||
if (null != ArmCheckActions)
|
||||
{
|
||||
GetBaseInputs(true);
|
||||
if (ArmCheckActions.PerformInputVoltageCheck || ArmCheckActions.PerformBatteryVoltageCheck)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel))
|
||||
{
|
||||
var mppadc = new MeasurePowerProAllDiagnosticChannel(this);
|
||||
mppadc.SyncExecute(); // Just Log it for now
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); }
|
||||
}
|
||||
if (ArmCheckActions.PerformBatteryVoltageCheck)
|
||||
{
|
||||
//if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics))
|
||||
//{
|
||||
try
|
||||
{
|
||||
dasResults.BatteryVoltage = new double?[1];
|
||||
dasResults.BatteryVoltage[0] = BaseInput.BatteryMilliVolts / 1000D;
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to get Battery voltage", ex); }
|
||||
//}
|
||||
}
|
||||
info.Progress(33);
|
||||
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); }
|
||||
//}
|
||||
}
|
||||
info.Progress(66);
|
||||
if (ArmCheckActions.PerformSquibResistanceCheck)
|
||||
{
|
||||
// No Squibs in PowerPro
|
||||
}
|
||||
if (ArmCheckActions.PerformEventLineCheck)
|
||||
{
|
||||
((ITriggerCheckActions)this).DoTriggerCheckSync();
|
||||
}
|
||||
if (ArmCheckActions.PerformSensorIdCheck)
|
||||
{
|
||||
//not needed
|
||||
}
|
||||
if (ArmCheckActions.PerformTemperatureCheck)
|
||||
{
|
||||
//// Temperature
|
||||
//dasResults.TemperaturesPre = new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN };
|
||||
|
||||
//var measure = new MeasureS6DBDiagnosticChannel(this);
|
||||
|
||||
////External sensor 1
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_2_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[0] = measure.Measurement;
|
||||
|
||||
////External sensor 2
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_3_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[1] = measure.Measurement;
|
||||
|
||||
////External sensor 3
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_4_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[2] = measure.Measurement;
|
||||
|
||||
////External sensor 4
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_5_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[3] = measure.Measurement;
|
||||
}
|
||||
}
|
||||
info.Progress(100);
|
||||
dasResults.SensorIds = null;
|
||||
dasResults.TiltSensorDataPre = null;
|
||||
dasResults.SquibResistances = null;
|
||||
ArmCheckResults = dasResults;
|
||||
info.Success();
|
||||
}
|
||||
|
||||
public void CheckAlreadyLevelTriggered(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.CheckAlreadyLevelTriggered", AsyncCheckAlreadyLevelTriggered, info);
|
||||
}
|
||||
private void AsyncCheckAlreadyLevelTriggered(object asyncInfo)
|
||||
{
|
||||
var info = asyncInfo as PowerProAsyncInfo;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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
|
||||
PowerProAsyncInfo info = null;
|
||||
if (null != callback)
|
||||
{
|
||||
info = new PowerProAsyncInfo(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, CheckStartForShort = true, CheckTriggerForShort = 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
|
||||
IsStartShorted = 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.IsStartShorted = status.IsStartShorted || oldStatus.IsStartShorted;
|
||||
//}
|
||||
|
||||
status.IsTriggerShorted = status.IsTriggered;
|
||||
//status.IsStartShorted = status.IsArmed;
|
||||
status.IsStartShorted = status.IsStartShorted;
|
||||
SetDASArmStatus(status, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
InitializeHardwareLines.Log(ex, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
void ITriggerCheckActions.PostStartTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
private class EventDiagnosticsAsyncPacket
|
||||
{
|
||||
public PowerProAsyncInfo 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 PowerProAsyncInfo(callback, userData);
|
||||
packet.EventNumber = EventNumber;
|
||||
packet.WhichResult = WhichResult;
|
||||
|
||||
packet.Info.Success();
|
||||
}
|
||||
public void PerformVoltageCheckTAOnly(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.PerformVoltageCheckTAOnly", AsyncPerformVoltageCheckTAOnly, info);
|
||||
}
|
||||
private void AsyncPerformVoltageCheckTAOnly(object o)
|
||||
{
|
||||
var info = o as PowerProAsyncInfo;
|
||||
info?.Success();
|
||||
}
|
||||
private const double SDB_ERR_VOLTAGE_REPORTING = 100000.0D;
|
||||
/// <summary>
|
||||
/// Retrieve the current arm status from the DAS
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
//void IArmActions.GetArmStatus(ServiceCallback callback, object userData, uint inputVoltageCutoff)
|
||||
//{
|
||||
// var info = new PowerProAsyncInfo(callback, userData);
|
||||
// var status = new ArmStatus { IsArmed = false };
|
||||
// try
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel))
|
||||
// {
|
||||
// var mppadc = new MeasurePowerProAllDiagnosticChannel(this);
|
||||
// mppadc.SyncExecute(); // Just Log it for now
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); }
|
||||
// if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics))
|
||||
// {
|
||||
// var batteryVoltage = 0.0;
|
||||
// try
|
||||
// {
|
||||
|
||||
// var query = new QueryBatteryVoltageMV(this, 3000);
|
||||
// query.SyncExecute();
|
||||
// var d = (double)query.BatteryVoltageMV;
|
||||
// if (d > SDB_ERR_VOLTAGE_REPORTING)
|
||||
// {
|
||||
// d /= 1000.0D;
|
||||
// }
|
||||
|
||||
// status.BatteryMilliVolts = d;
|
||||
|
||||
// batteryVoltage = Math.Round(d / 1000, 1);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// APILogger.Log("Failed to get battery mv", ex);
|
||||
// }
|
||||
|
||||
// try
|
||||
// {
|
||||
// var query = new QueryV1VoltageMV(this, 3000);
|
||||
// query.SyncExecute();
|
||||
// var d = (double)query.V1VoltageMV;
|
||||
// if (d > SDB_ERR_VOLTAGE_REPORTING)
|
||||
// {
|
||||
// d /= 1000.0D;
|
||||
// }
|
||||
|
||||
// status.InputMilliVolts = d;
|
||||
|
||||
// var inputVoltage = Math.Round(d / 1000, 1);
|
||||
|
||||
// if (batteryVoltage < MinimumValidBatteryVoltage || batteryVoltage > MaximumValidBatteryVoltage)
|
||||
// {
|
||||
// batteryVoltage = 0.0;
|
||||
// }
|
||||
|
||||
// BaseInput = new BaseInputValues();
|
||||
// var batteryVoltageStatusColor = DFConstantsAndEnums.VoltageStatusColor.Off;
|
||||
// batteryVoltageStatusColor = BaseInput.ChargeCapacityValid
|
||||
// ? ConvertBatteryCapacity2Color(batteryVoltage, BaseInput.ChargeCapacity)
|
||||
// : ConvertBatteryVoltage2Color(batteryVoltage);
|
||||
// var batteryChargingStatus = string.Empty;
|
||||
// if (batteryVoltage >= MinimumValidBatteryVoltage)
|
||||
// {
|
||||
// batteryChargingStatus = ConvertInputVoltage2BatteryCharging(inputVoltage);
|
||||
// }
|
||||
|
||||
// var statusDisplayBattery =
|
||||
// batteryVoltage < MinimumValidBatteryVoltage || batteryVoltage > MaximumValidBatteryVoltage
|
||||
// ? "---"
|
||||
// : batteryVoltage.ToString(System.Globalization.CultureInfo.InvariantCulture) + " V " +
|
||||
// batteryChargingStatus;
|
||||
// var inputVoltageStatusColor = ConvertInputVoltage2Color(inputVoltage);
|
||||
// BaseInput.InputVoltageStatusColor = inputVoltageStatusColor;
|
||||
// BaseInput.StatusDisplayInput =
|
||||
// inputVoltage < MinimumValidInputVoltage || inputVoltage > MaximumValidInputVoltage
|
||||
// ? "---"
|
||||
// : inputVoltage.ToString(System.Globalization.CultureInfo.InvariantCulture) + " V";
|
||||
// BaseInput.BatteryVoltageStatusColor = batteryVoltageStatusColor;
|
||||
// BaseInput.StatusDisplayBattery = statusDisplayBattery;
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// APILogger.Log("Failed to get input mv", ex);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// SetDASArmStatus(status, true);
|
||||
// }
|
||||
// info.Success();
|
||||
//}
|
||||
void IConfigurationActions.CheckSafetyState(bool bArmed, ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
|
||||
|
||||
//}
|
||||
/// <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 PowerProAsyncInfo
|
||||
{
|
||||
public ServiceCallback Callback { get; set; }
|
||||
public object UserData { get; set; }
|
||||
public object FunctionData { get; set; }
|
||||
|
||||
public PowerProAsyncInfo(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", "PowerPRO 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", "PowerPRO 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", "PowerPRO 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", "PowerPRO ERROR", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class PowerPro_Base<T> : SLICE2_Base<T> where T : IConnection, new()
|
||||
{
|
||||
protected override bool AdjustInputRange(AnalogInputDASChannel analog)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns true if device supports trigger inversion, false otherwise
|
||||
/// <inheritdoc cref="IDASCommunication"/>
|
||||
/// </summary>
|
||||
/// <returns>true if device supports trigger inversion, false otherwise</returns>
|
||||
public override bool SupportsTriggerInversion() => HardwareConstants.SupportsTriggerInversion(GetHardwareType(), ProtocolVersion);
|
||||
/// <summary>
|
||||
/// returns true if device supports start inversion, false otherwise
|
||||
/// <inheritdoc cref="IDASCommunication"/>
|
||||
/// </summary>
|
||||
/// <returns>true if device supports start inversion, false otherwise</returns>
|
||||
public override bool SupportsStartInversion() => HardwareConstants.SupportsStartInversion(GetHardwareType(), ProtocolVersion);
|
||||
|
||||
|
||||
public override bool CheckAAF(float rate) { return true; }
|
||||
public override bool SupportsTimeSynchronization
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override double[] GetNominalRanges(SensorConstants.BridgeType bridgeType)
|
||||
{
|
||||
switch (bridgeType)
|
||||
{
|
||||
case SensorConstants.BridgeType.IEPE:
|
||||
return WinUSBSlice.StaticDASIEPEInfo.NominalRanges;
|
||||
default:
|
||||
return WinUSBSlice.StaticDASBridgeInfo.NominalRanges;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> PowerPro_MinimumProtocols =
|
||||
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 6.0 DB Protocol Limitations
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryMSP430Firmware] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleEvents] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArm] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDefaultMIF] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackSensors] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.TestCommunication] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackLowPowerMode] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetRealtimeSampleRate] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.LevelTrigger] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AttributeStoreBlocks] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MaxEvents] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmDiagnosticDelay] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackChannelAutoArmDiagLevel] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleSamplesRealtime] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
|
||||
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.DiangosShuntDAC] = PowerPRO.DIAGNOS_SHUNT_DAC;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageInsertion] = PowerPRO.DIAGNOS_SHUNT_DAC;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryEthernetMacTable] = PowerPRO.MIN_PROTOCOL_QUERYMACTABLE;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel] = PowerPRO.MIN_PROTOCOL_MEASUREPOWERPROALLDIAGNOSTICCHANNEL;
|
||||
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
|
||||
MinimumProtocols = PowerPro_MinimumProtocols;
|
||||
}
|
||||
protected override Slice<T>.ConfigAttributes GetConfigAttributes(ICommunication com)
|
||||
{
|
||||
return new SLICE6ConfigAttributes(com);
|
||||
}
|
||||
/// <summary>
|
||||
/// SLICE6 config attributes, mostly inherits from SLICE.ConfigAttributes with some functionality removed
|
||||
/// </summary>
|
||||
protected class SLICE6ConfigAttributes : Slice<T>.ConfigAttributes
|
||||
{
|
||||
public SLICE6ConfigAttributes(ICommunication _com)
|
||||
: base(_com)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// QueryEventData also is customized for SLICE6, it needs to perform SLICE6 specific data marshalling
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override QueryEventDataBase GetQueryEventData()
|
||||
{
|
||||
return new QueryEventData_SLICE6(this, QueryEventData_SLICE6.Default_IO_Timeout);
|
||||
}
|
||||
/// <summary>
|
||||
/// we can probably simplify and take common items (slice6+slice1) out of this function, but for now
|
||||
/// it's mostly a copy of SLICE1.AsyncConfigure
|
||||
/// </summary>
|
||||
/// <param name="configAsyncInfo"></param>
|
||||
protected override void AsyncConfigure(object configAsyncInfo)
|
||||
{
|
||||
var info = (SliceConfigServiceAsyncInfo)configAsyncInfo;
|
||||
|
||||
ConfigureHasBeenRun = true;
|
||||
if (info.DiscardDiagnostics) { DiagnosticsHasBeenRun = false; }
|
||||
info.Progress(100);
|
||||
info.Success();
|
||||
}
|
||||
|
||||
#region Voltage Check
|
||||
public void PerformVoltageCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.PerformVoltageCheck", AsyncPerformVoltageCheck, info);
|
||||
}
|
||||
|
||||
private void AsyncPerformVoltageCheck(object o)
|
||||
{
|
||||
var info = o as SliceServiceAsyncInfo;
|
||||
try
|
||||
{
|
||||
GetBaseInputs(true);
|
||||
info?.Success();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
info?.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// hardcoded constants right now ... maybe these belong in attributes in the firmware!
|
||||
/// </summary>
|
||||
protected override uint MaxAAFilterRateHz { get { return PowerPRO.MaxAAFilterRateHz; } }
|
||||
protected override uint MaxSampleRateHz { get { return 400000; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public interface IDiagnosticsActions
|
||||
{
|
||||
/// <summary>
|
||||
/// clears the trigger out line via SetSwitchImmediate
|
||||
/// </summary>
|
||||
void ClearTriggerOut(ServiceCallback callback, object userData);
|
||||
/// <summary>
|
||||
/// clears any latched FPGA via a QATS call
|
||||
/// </summary>
|
||||
void ClearLatches(ServiceCallback callback, object userData);
|
||||
void PerformVoltageCheck(ServiceCallback callback, object userData);
|
||||
void PerformVoltageCheckTAOnly(ServiceCallback callback, object userData);
|
||||
void PerformArmChecks(ServiceCallback callback, object userData);
|
||||
void SaveTiltSensorDataPre(ServiceCallback callback, object userData);
|
||||
void SaveTemperaturesPre(ServiceCallback callback, object userData);
|
||||
/// <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>
|
||||
void PrepareForBridgeResistanceMeasurement(UInt32 DiagnosticsSampleRateHz,
|
||||
float DiagnosticsAAFilterFrequencyHz,
|
||||
ServiceCallback callback, object userData);
|
||||
|
||||
/// <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>
|
||||
void PrepareForDiagnostics(UInt32 DiagnosticsSampleRateHz,
|
||||
float DiagnosticsAAFilterFrequencyHz,
|
||||
DTS.DASLib.Service.PrePostResults WhichResult,
|
||||
ServiceCallback callback, object userData);
|
||||
|
||||
void SetStatusIndicator(DiagnosticsStatusIndicatorState state,
|
||||
ServiceCallback callback, object userData);
|
||||
|
||||
/// <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>
|
||||
void DiagnosAndGetResults(int EventNumber, PrePostResults WhichResult,
|
||||
ServiceCallback callback, object userData);
|
||||
|
||||
/// <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>
|
||||
void GetEventDiagnosticsResults(int EventNumber, PrePostResults WhichResult,
|
||||
ServiceCallback callback, object userData);
|
||||
/// <summary>
|
||||
/// clears the trigger lines for any DAS
|
||||
/// 14229 DataPRO crash when run diagnostics second time
|
||||
/// note there's already a service to clear the trigger lines for S6DB, ECM (TriggerCheck.PreStart)
|
||||
/// 5211 for more info
|
||||
/// however we need one for DAS that will explictly run AFTER prestart runs
|
||||
/// this service just sets trigger out to 0 and runs QATS to reset the FPGA on affected units
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
/// <param name="userData"></param>
|
||||
void ClearDASTriggerLine(ServiceCallback callback, object userData);
|
||||
void SquibFireCheckArm(double delay, double duration, ServiceCallback callback, object userData);
|
||||
|
||||
void TriggerCheckTrigger(ServiceCallback callback, object userData);
|
||||
void TriggerCheckDownload(double delay, double duration, float diagnosticsAAFilterFrequencyHz, uint diagnosticsSampleRateHz, ServiceCallback callback, object userData);
|
||||
/// <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>
|
||||
void GetBridgeMeasurement(ServiceCallback callback, object userData);
|
||||
void MeasureTransferSpeed(ServiceCallback callback, object userData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
//using DTS.DASLib.Command.SLICE;
|
||||
using DTS.Common.DASResource;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Classes.Connection;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public partial class TDAS<T> : Communication<T>,
|
||||
IDASCommunication,
|
||||
IConfigurationActions,
|
||||
IDiagnosticsActions,
|
||||
ITriggerCheckActions,
|
||||
IRealTimeActions,
|
||||
IArmActions,
|
||||
IDownloadActions where T : IConnection, new()
|
||||
{
|
||||
public bool IsEthernetDistributor() { return false; }
|
||||
public bool IsSlice6Distributor() { return false; }
|
||||
public bool IsBattery() { return false; }
|
||||
public bool IsTSRAIR() { return false; }
|
||||
public bool IsSlice6Air() { return false; }
|
||||
public bool IsScheduleEventCountSupported() { return false; }
|
||||
public class TDASDownloadServiceAsyncInfo
|
||||
{
|
||||
public TDASServiceAsyncInfo info { get; set; }
|
||||
public TDASServiceSetupInfo setupInfo { get; set; }
|
||||
|
||||
public TDASDownloadServiceAsyncInfo(TDASServiceAsyncInfo _info, object _setupInfo)
|
||||
{
|
||||
info = _info;
|
||||
if (_setupInfo != null)
|
||||
{
|
||||
setupInfo = _setupInfo as TDASServiceSetupInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TDASServiceQueryConfigAsyncInfo : TDASServiceAsyncInfo
|
||||
{
|
||||
public bool ReadIds { get; set; } = true;
|
||||
|
||||
public TDASServiceQueryConfigAsyncInfo(bool bReadIds, ServiceCallback callback, object userData)
|
||||
: base(callback, userData)
|
||||
{
|
||||
ReadIds = bReadIds;
|
||||
}
|
||||
}
|
||||
public class TDASServiceAsyncInfo
|
||||
{
|
||||
public ServiceCallback callback { get; set; }
|
||||
public object userData { get; set; }
|
||||
public object functionData { get; set; }
|
||||
|
||||
public TDASServiceAsyncInfo(ServiceCallback _callback, object _userData)
|
||||
{
|
||||
callback = _callback;
|
||||
userData = _userData;
|
||||
}
|
||||
|
||||
public void Error(string msg, Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cbData = new ServiceCallbackData();
|
||||
cbData.Status = ServiceCallbackData.CallbackStatus.Failure;
|
||||
cbData.ErrorMessage = msg;
|
||||
cbData.ErrorException = ex;
|
||||
cbData.UserData = userData;
|
||||
callback(cbData);
|
||||
}
|
||||
catch (Exception eex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoError, eex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Error(string msg)
|
||||
{
|
||||
Error(msg, null);
|
||||
}
|
||||
|
||||
public void Progress(int value)
|
||||
{
|
||||
try
|
||||
{
|
||||
var progressData = new ServiceCallbackData();
|
||||
progressData.Status = ServiceCallbackData.CallbackStatus.ProgressReport;
|
||||
progressData.ProgressValue = value;
|
||||
progressData.UserData = userData;
|
||||
callback(progressData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoProgressError, ex);
|
||||
}
|
||||
}
|
||||
public void NewData(object obj)
|
||||
{
|
||||
if (obj is ServiceCallbackData.DiagnosticNewData)
|
||||
{
|
||||
var progressData = new ServiceCallbackData();
|
||||
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
|
||||
progressData.ProgressValue = 0;
|
||||
progressData.UserData = userData;
|
||||
progressData.SetNewDiagnosticData((obj as ServiceCallbackData.DiagnosticNewData));
|
||||
callback(progressData);
|
||||
}
|
||||
else
|
||||
{
|
||||
var newdatadata = obj as NewDataData;
|
||||
var datas = newdatadata.datas;
|
||||
var samplenumbers = newdatadata.SampleNumbers;
|
||||
var timeStamps = newdatadata.TimeStamps;
|
||||
var sequenceNumbers = newdatadata.SequenceNumbers;
|
||||
try
|
||||
{
|
||||
var progressData = new ServiceCallbackData();
|
||||
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
|
||||
progressData.ProgressValue = 0;
|
||||
progressData.UserData = userData;
|
||||
for (var i = 0; i < datas.Length && i < samplenumbers.Length; i++)
|
||||
{
|
||||
progressData.AddSampleData(datas[i], samplenumbers[i], timeStamps[i], sequenceNumbers[i]);
|
||||
}
|
||||
callback(progressData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.SLICEAsyncInfoNewDataError, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void NewData(IList<short[][]> datas, IList<ulong> samplenumbers, IList<ulong> timeStamps, IList<ulong> sequenceNumbers)
|
||||
{
|
||||
try
|
||||
{
|
||||
var progressData = new ServiceCallbackData();
|
||||
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
|
||||
progressData.ProgressValue = 0;
|
||||
progressData.UserData = userData;
|
||||
for (var i = 0; i < datas.Count && i < samplenumbers.Count; i++)
|
||||
{
|
||||
progressData.AddSampleData(datas[i], samplenumbers[i], timeStamps[i], 0);
|
||||
}
|
||||
callback(progressData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoNewDataError, ex);
|
||||
}
|
||||
}
|
||||
public void NewData(short[][] data, ulong samplenumber, ulong timeStamp, ulong sequenceNumber)
|
||||
{
|
||||
try
|
||||
{
|
||||
var progressData = new ServiceCallbackData();
|
||||
progressData.Status = ServiceCallbackData.CallbackStatus.NewData;
|
||||
progressData.ProgressValue = 0;
|
||||
progressData.UserData = userData;
|
||||
progressData.AddSampleData(data, samplenumber, timeStamp, sequenceNumber);
|
||||
callback(progressData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoNewDataError, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Success()
|
||||
{
|
||||
try
|
||||
{
|
||||
var success = new ServiceCallbackData();
|
||||
success.Status = ServiceCallbackData.CallbackStatus.Success;
|
||||
success.UserData = userData;
|
||||
callback(success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoSuccessError, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cancelReport = new ServiceCallbackData();
|
||||
cancelReport.Status = ServiceCallbackData.CallbackStatus.Canceled;
|
||||
cancelReport.ProgressValue = 0;
|
||||
cancelReport.UserData = userData;
|
||||
callback(cancelReport);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("MessageBox", Strings.TDASAsyncInfoCancelError, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LaunchAsyncWorker(string Invoker, WaitCallback cb, object asyncInfo)
|
||||
{
|
||||
if (!Connected)
|
||||
{
|
||||
// "{0}: Not currently connected"
|
||||
throw new NotConnectedException(string.Format(Strings.Slice_LaunchAsyncWorker_Err1, Invoker));
|
||||
}
|
||||
|
||||
if (!ThreadPool.QueueUserWorkItem(cb, asyncInfo))
|
||||
{
|
||||
// "{0}: Unable to enqueue function"
|
||||
throw new Exception(string.Format(Strings.Slice_LaunchAsyncWorker_Err2, Invoker));
|
||||
}
|
||||
}
|
||||
|
||||
private void CallSyncMethod(string Invoker, WaitCallback cb, object info)
|
||||
{
|
||||
if (!Connected)
|
||||
{
|
||||
// "{0}: Not currently connected"
|
||||
throw new NotConnectedException(string.Format(Strings.Slice_LaunchAsyncWorker_Err1, Invoker));
|
||||
}
|
||||
cb(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// compare to an object to determine equality
|
||||
/// </summary>
|
||||
/// <param name="right"></param>
|
||||
/// <returns></returns>
|
||||
public override bool Equals(object right)
|
||||
{
|
||||
|
||||
if (right == null)
|
||||
return false;
|
||||
|
||||
if (ReferenceEquals(this, right))
|
||||
return true;
|
||||
|
||||
if (!(right is TDAS<T> rightSlice))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(SerialNumber))
|
||||
{
|
||||
return string.IsNullOrEmpty(rightSlice.SerialNumber);
|
||||
}
|
||||
if (string.IsNullOrEmpty(rightSlice.SerialNumber))
|
||||
return false;
|
||||
return SerialNumber == rightSlice.SerialNumber;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns identical index for any two 'equal' slice
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (string.IsNullOrEmpty(SerialNumber))
|
||||
return 0;
|
||||
return SerialNumber.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.DASLib.Service.Classes.Diagnostics
|
||||
{
|
||||
public class OptimizationValues : IOptimizationValues
|
||||
{
|
||||
public float TransferSpeed { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.Common.Utilities.DotNetProgrammingConstructs;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class TDASModuleConfig : IXmlSerializable
|
||||
{
|
||||
private string _serialNumber = "";
|
||||
public string SerialNumber { get { return _serialNumber; } set { _serialNumber = value; } }
|
||||
|
||||
private string _testId = "";
|
||||
public string TestId { get { return _testId; } set { _testId = value; } }
|
||||
|
||||
private string _testDescription = "";
|
||||
public string TestDescription { get { return _testDescription; } set { _testDescription = value; } }
|
||||
|
||||
public DFConstantsAndEnums.RecordingMode RecordingMode { get; set; } = DFConstantsAndEnums.RecordingMode.InvalidArmMode;
|
||||
|
||||
private float _aaFilterRateHz = 0;
|
||||
public float AAFilterRateHz { get { return _aaFilterRateHz; } set { _aaFilterRateHz = value; } }
|
||||
|
||||
private double _preTriggerSeconds = 0;
|
||||
public double PreTriggerSeconds { get { return _preTriggerSeconds; } set { _preTriggerSeconds = value; } }
|
||||
|
||||
private double _postTriggerSeconds = 0;
|
||||
public double PostTriggerSeconds { get { return _postTriggerSeconds; } set { _postTriggerSeconds = value; } }
|
||||
|
||||
private Dictionary<int, DASChannel> _channels = new Dictionary<int, DASChannel>();
|
||||
|
||||
private string _fileName;
|
||||
public string FileName { get { return _fileName; } }
|
||||
|
||||
private string _firmwareVersion = "";
|
||||
public string FirmwareVersion { get { return _firmwareVersion; } set { _firmwareVersion = value; } }
|
||||
|
||||
private UInt64? _maxEventStorageSpaceInBytes = 0;
|
||||
public UInt64? MaxEventStorageSpaceInBytes { get { return _maxEventStorageSpaceInBytes; } set { _maxEventStorageSpaceInBytes = value; } }
|
||||
|
||||
private int moduleArrayIndex = 0;
|
||||
public int ModuleArrayIndex { get { return moduleArrayIndex; } set { moduleArrayIndex = value; } }
|
||||
|
||||
public TDASModuleConfig()
|
||||
{
|
||||
}
|
||||
|
||||
public TDASModuleConfig(string fileName)
|
||||
{
|
||||
const string dasConfigs = "DASConfigs";
|
||||
var location = Path.Combine(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), dasConfigs), fileName);
|
||||
_fileName = location; //fileName;
|
||||
if (File.Exists(_fileName))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (StreamReader sr = new StreamReader(_fileName))
|
||||
{
|
||||
ReadXml(System.Xml.XmlReader.Create(sr));
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
APILogger.Log("Problem reading ", _fileName, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void SetChannel(OutputTOMDigitalChannel channel)
|
||||
{
|
||||
if (_channels.ContainsKey(channel.ModuleChannelNumber)) { _channels[channel.ModuleChannelNumber] = channel; }
|
||||
else { _channels.Add(channel.ModuleChannelNumber, channel); }
|
||||
}
|
||||
public void SetChannel(OutputSquibChannel channel)
|
||||
{
|
||||
if (_channels.ContainsKey(channel.ModuleChannelNumber)) { _channels[channel.ModuleChannelNumber] = channel; }
|
||||
else { _channels.Add(channel.ModuleChannelNumber, channel); }
|
||||
}
|
||||
public void SetChannel(AnalogInputDASChannel channel)
|
||||
{
|
||||
if (_channels.ContainsKey(channel.ModuleChannelNumber)) { _channels[channel.ModuleChannelNumber] = channel; }
|
||||
else { _channels.Add(channel.ModuleChannelNumber, channel); }
|
||||
}
|
||||
public AnalogInputDASChannel GetChannel(AnalogInputDASChannel channel)
|
||||
{
|
||||
if (_channels.ContainsKey(channel.ModuleChannelNumber)) { return _channels[channel.ModuleChannelNumber] as AnalogInputDASChannel; }
|
||||
else
|
||||
{
|
||||
_channels.Add(channel.ModuleChannelNumber, channel);
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
public OutputSquibChannel GetChannel(OutputSquibChannel channel)
|
||||
{
|
||||
if (_channels.ContainsKey(channel.ModuleChannelNumber)) { return _channels[channel.ModuleChannelNumber] as OutputSquibChannel; }
|
||||
else
|
||||
{
|
||||
_channels.Add(channel.ModuleChannelNumber, channel);
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
public OutputTOMDigitalChannel GetChannel(OutputTOMDigitalChannel channel)
|
||||
{
|
||||
if (_channels.ContainsKey(channel.ModuleChannelNumber)) { return _channels[channel.ModuleChannelNumber] as OutputTOMDigitalChannel; }
|
||||
else
|
||||
{
|
||||
_channels.Add(channel.ModuleChannelNumber, channel);
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
public XmlSchema GetSchema()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
//
|
||||
// Summary:
|
||||
// Generates an object from its XML representation.
|
||||
//
|
||||
// Parameters:
|
||||
// reader:
|
||||
// The System.Xml.XmlReader stream from which the object is deserialized.
|
||||
public void ReadXml(XmlReader reader)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
reader.ReadStartElement("TDASModule");
|
||||
reader.ReadStartElement("SerialNumber");
|
||||
_serialNumber = reader.ReadString();
|
||||
reader.ReadEndElement();
|
||||
reader.ReadStartElement("TestId");
|
||||
_testId = reader.ReadString();
|
||||
reader.ReadEndElement();
|
||||
reader.ReadStartElement("TestDescription");
|
||||
_testDescription = reader.ReadString();
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("RecordingMode");
|
||||
string recordingMode = reader.ReadString();
|
||||
try
|
||||
{
|
||||
RecordingMode = (DFConstantsAndEnums.RecordingMode)Enum.Parse(typeof(DFConstantsAndEnums.RecordingMode), recordingMode);
|
||||
}
|
||||
catch (System.Exception ex) { APILogger.Log("Failed to load RecordingMode ", recordingMode, ex); }
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("AAFilterRateHz");
|
||||
string aaFilterRateHz = reader.ReadString();
|
||||
try
|
||||
{
|
||||
AAFilterRateHz = (float)Convert.ToDouble(aaFilterRateHz);
|
||||
}
|
||||
catch (System.Exception ex) { APILogger.Log("Failed to load AAFilterRateHz ", aaFilterRateHz, ex); }
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("PreTriggerSeconds");
|
||||
string preTriggerSeconds = reader.ReadString();
|
||||
try
|
||||
{
|
||||
PreTriggerSeconds = Convert.ToDouble(preTriggerSeconds);
|
||||
}
|
||||
catch (System.Exception ex) { APILogger.Log("Failed to load PreTriggerSeconds ", preTriggerSeconds, ex); }
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("PostTriggerSeconds");
|
||||
string postTriggerSeconds = reader.ReadString();
|
||||
try
|
||||
{
|
||||
PostTriggerSeconds = Convert.ToDouble(postTriggerSeconds);
|
||||
}
|
||||
catch (System.Exception ex) { APILogger.Log("Failed to load PostTriggerSeconds ", postTriggerSeconds, ex); }
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("FirmwareVersion");
|
||||
_firmwareVersion = reader.ReadString();
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("MaxEventStorageSpaceInBytes");
|
||||
string maxEventStorageSpaceInBytes = reader.ReadString();
|
||||
|
||||
{
|
||||
double d;
|
||||
if (double.TryParse(maxEventStorageSpaceInBytes, out d))
|
||||
{
|
||||
if (d >= 0 && d < ulong.MaxValue) { MaxEventStorageSpaceInBytes = Convert.ToUInt64(d); }
|
||||
else { APILogger.Log("Failed to load MaxEventStorageSpaceInBytes ", maxEventStorageSpaceInBytes); }
|
||||
}
|
||||
else { APILogger.Log("Failed to load MaxEventStorageSpaceInBytes ", maxEventStorageSpaceInBytes); }
|
||||
}
|
||||
reader.ReadEndElement();
|
||||
|
||||
try
|
||||
{
|
||||
reader.ReadStartElement("ModuleArrayIndex");
|
||||
string moduleArrayIndex = reader.ReadString();
|
||||
|
||||
{
|
||||
int m;
|
||||
if (int.TryParse(moduleArrayIndex, out m))
|
||||
{
|
||||
if (m >= 0 && m < int.MaxValue) { ModuleArrayIndex = Convert.ToInt32(m); }
|
||||
else { APILogger.Log("Failed to load ModuleArrayIndex ", moduleArrayIndex); }
|
||||
}
|
||||
else { APILogger.Log("Failed to load ModuleArrayIndex ", moduleArrayIndex); }
|
||||
}
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
catch
|
||||
{
|
||||
//This must be an old config file
|
||||
}
|
||||
|
||||
reader.ReadStartElement("Channels");
|
||||
|
||||
while (reader.MoveToContent() == XmlNodeType.Element)
|
||||
{
|
||||
string sType = reader.GetAttribute("type");
|
||||
switch (sType)
|
||||
{
|
||||
case "OutputSquibChannel":
|
||||
OutputSquibChannel osc = new OutputSquibChannel();
|
||||
osc.ReadXml(reader);
|
||||
SetChannel(osc);
|
||||
break;
|
||||
case "OutputTOMDigitalChannel":
|
||||
OutputTOMDigitalChannel tom = new OutputTOMDigitalChannel();
|
||||
tom.ReadXml(reader);
|
||||
SetChannel(tom);
|
||||
break;
|
||||
default:
|
||||
AnalogInputDASChannel aic = new AnalogInputDASChannel();
|
||||
aic.ReadXml(reader);
|
||||
SetChannel(aic);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
reader.ReadEndElement();
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
//
|
||||
// Summary:
|
||||
// Converts an object into its XML representation.
|
||||
//
|
||||
// Parameters:
|
||||
// writer:
|
||||
// The System.Xml.XmlWriter stream to which the object is serialized.
|
||||
public void WriteXml(XmlWriter writer)
|
||||
{
|
||||
//writer.WriteStartElement ( attributeExtractor.ExtractAttachedAttributeFromObject ( this
|
||||
writer.WriteStartElement("TDASModule");
|
||||
writer.WriteStartElement("SerialNumber");
|
||||
writer.WriteString(SerialNumber);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteStartElement("TestId");
|
||||
writer.WriteString(TestId);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteStartElement("TestDescription");
|
||||
writer.WriteString(TestDescription);
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("RecordingMode");
|
||||
writer.WriteString(RecordingMode.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("AAFilterRateHz");
|
||||
writer.WriteString(AAFilterRateHz.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("PreTriggerSeconds");
|
||||
writer.WriteString(PreTriggerSeconds.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("PostTriggerSeconds");
|
||||
writer.WriteString(PostTriggerSeconds.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("FirmwareVersion");
|
||||
writer.WriteString(FirmwareVersion);
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("MaxEventStorageSpaceInBytes");
|
||||
writer.WriteString(MaxEventStorageSpaceInBytes.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("ModuleArrayIndex");
|
||||
writer.WriteString(ModuleArrayIndex.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("Channels");
|
||||
writer.Flush();
|
||||
|
||||
foreach (DASChannel channel in _channels.Values)
|
||||
{
|
||||
channel.WriteElementStart(writer);
|
||||
channel.WriteXml(writer);
|
||||
channel.WriteElementEnd(writer);
|
||||
writer.Flush();
|
||||
}
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement();
|
||||
writer.Flush();
|
||||
}
|
||||
public virtual void WriteElementStart(XmlWriter writer)
|
||||
{
|
||||
writer.WriteStartElement("TDASModule");
|
||||
var tgt = GetType();
|
||||
writer.WriteAttributeString("xsi", "type", null, tgt.Name);
|
||||
}
|
||||
|
||||
public virtual void WriteElementEnd(XmlWriter writer)
|
||||
{
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<DirectedGraph DataVirtualized="True" Layout="Sugiyama" ZoomLevel="-1" xmlns="http://schemas.microsoft.com/vs/2009/dgml">
|
||||
<Nodes>
|
||||
<Node Id="@10" Category="CodeSchema_Assembly" AssemblyTimestamp="12/14/2018 20:47:53" Bounds="157.107245477469,9.99999999999996,135.89,25" CodeSchemaProperty_StrongName="DASFactory, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" DelayedChildNodesState="NotFetched" DelayedCrossGroupLinksState="Fetched" FilePath="$(02eeba8c-7b22-4bc3-bf3a-8de23eaf2e61.OutputPath)" Group="Collapsed" Label="DASFactory.dll">
|
||||
<Category Ref="FileSystem.Category.FileOfType.dll" />
|
||||
</Node>
|
||||
<Node Id="@2" Category="CodeSchema_Assembly" AssemblyTimestamp="12/14/2018 20:48:43" Bounds="5.65334754981237,-45.0001,129.18,25" CodeSchemaProperty_StrongName="DataPRO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" DelayedChildNodesState="NotFetched" DelayedCrossGroupLinksState="Fetched" FilePath="$(8baa9433-8034-4fde-822c-537c59d3a7ec.OutputPath)" Group="Collapsed" Label="DataPRO.exe">
|
||||
<Category Ref="CodeMap_WpfProject" />
|
||||
<Category Ref="FileSystem.Category.FileOfType.exe" />
|
||||
</Node>
|
||||
<Node Id="@4" Category="CodeSchema_Assembly" AssemblyTimestamp="12/14/2018 20:47:52" Bounds="-264.822954522531,10,126.51,25" CodeSchemaProperty_StrongName="SensorDB, Version=1.6.81.0, Culture=neutral, PublicKeyToken=null" DelayedChildNodesState="NotFetched" DelayedCrossGroupLinksState="Fetched" FilePath="$(444ef10c-046e-47ad-a9a5-17318d488723.OutputPath)" Group="Collapsed" Label="SensorDB.dll">
|
||||
<Category Ref="FileSystem.Category.FileOfType.dll" />
|
||||
</Node>
|
||||
<Node Id="@6" Category="CodeSchema_Assembly" AssemblyTimestamp="12/14/2018 20:47:51" Bounds="16.8152160177807,112.0001,115.97,25" CodeSchemaProperty_StrongName="IService, Version=1.6.81.0, Culture=neutral, PublicKeyToken=null" DelayedChildNodesState="NotFetched" DelayedCrossGroupLinksState="Fetched" FilePath="$(c9c45b72-05a3-4962-bc13-a78b1f4b1925.OutputPath)" Group="Collapsed" Label="IService.dll" UseManualLocation="True" />
|
||||
<Node Id="@8" Category="CodeSchema_Assembly" AssemblyTimestamp="12/14/2018 20:47:53" Bounds="-108.312854522531,9.99999999999996,235.42,25" CodeSchemaProperty_StrongName="DTS.Common.SerializationPlus, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" DelayedChildNodesState="NotFetched" DelayedCrossGroupLinksState="Fetched" FilePath="$(b9d1ac5b-7a6f-4b14-9ff8-3a1fc03519e2.OutputPath)" Group="Collapsed" Label="DTS.Common.SerializationPlus.dll">
|
||||
<Category Ref="FileSystem.Category.FileOfType.dll" />
|
||||
</Node>
|
||||
</Nodes>
|
||||
<Links>
|
||||
<Link Source="@10" Target="@6" Category="References" Bounds="100.659720139206,35,105.979304486067,71.9451157790153" IsSourceVirtualized="True" IsTargetVirtualized="True" Weight="531">
|
||||
<Category Ref="CodeMap_ProjectReference" />
|
||||
<Category Ref="CodeSchema_Calls" />
|
||||
<Category Ref="CodeSchema_FieldWrite" />
|
||||
<Category Ref="CodeSchema_ReturnTypeLink" />
|
||||
</Link>
|
||||
<Link Source="@2" Target="@10" Category="References" Bounds="105.427124017414,-20.0001,75.960668386819,26.987107416101" IsSourceVirtualized="True" IsTargetVirtualized="True" Weight="62">
|
||||
<Category Ref="CodeMap_ProjectReference" />
|
||||
<Category Ref="CodeSchema_Calls" />
|
||||
</Link>
|
||||
<Link Source="@2" Target="@4" Category="References" Bounds="-132.670010733127,-20.1761540568882,142.008236411045,28.7348875631092" IsSourceVirtualized="True" IsTargetVirtualized="True" Weight="8288">
|
||||
<Category Ref="CodeMap_ProjectReference" />
|
||||
<Category Ref="CodeSchema_Calls" />
|
||||
<Category Ref="CodeSchema_ReturnTypeLink" />
|
||||
</Link>
|
||||
<Link Source="@2" Target="@6" Category="References" Bounds="87.149772644043,-20.0000991821289,50.0915908813477,124.323356628418" IsSourceVirtualized="True" IsTargetVirtualized="True" Weight="7433">
|
||||
<Category Ref="CodeMap_ProjectReference" />
|
||||
<Category Ref="CodeSchema_Calls" />
|
||||
<Category Ref="CodeSchema_FieldWrite" />
|
||||
<Category Ref="CodeSchema_ReturnTypeLink" />
|
||||
</Link>
|
||||
<Link Source="@2" Target="@8" Category="References" Bounds="29.9024203846777,-20.0001,26.5122700189787,23.9649715612015" IsSourceVirtualized="True" IsTargetVirtualized="True" Weight="810">
|
||||
<Category Ref="CodeMap_ProjectReference" />
|
||||
<Category Ref="CodeSchema_Calls" />
|
||||
<Category Ref="CodeSchema_ReturnTypeLink" />
|
||||
</Link>
|
||||
<Link Source="@4" Target="@6" Category="References" Bounds="-167.699339376527,35,200.187639918939,73.8839036730438" IsSourceVirtualized="True" IsTargetVirtualized="True" Weight="44">
|
||||
<Category Ref="CodeMap_ProjectReference" />
|
||||
<Category Ref="CodeSchema_Calls" />
|
||||
<Category Ref="CodeSchema_ReturnTypeLink" />
|
||||
</Link>
|
||||
<Link Source="@8" Target="@6" Category="References" Bounds="17.4122197936108,35,44.5149587216657,69.4238084480633" IsSourceVirtualized="True" IsTargetVirtualized="True" Weight="398">
|
||||
<Category Ref="CodeMap_ProjectReference" />
|
||||
<Category Ref="CodeSchema_Calls" />
|
||||
</Link>
|
||||
</Links>
|
||||
<Categories>
|
||||
<Category Id="CodeMap_ProjectReference" Label="Project Reference" CanBeDataDriven="True" CanLinkedNodesBeDataDriven="True" IncomingActionLabel="Referenced By" OutgoingActionLabel="References" />
|
||||
<Category Id="CodeMap_WpfProject" Label="WPF Project" CanBeDataDriven="True" IsProviderRoot="False" NavigationActionLabel="WPF Projects" />
|
||||
<Category Id="CodeSchema_Assembly" Label="Assembly" BasedOn="File" CanBeDataDriven="True" DefaultAction="Microsoft.Contains" Icon="CodeSchema_Assembly" NavigationActionLabel="Assemblies" />
|
||||
<Category Id="CodeSchema_Calls" Label="Calls" CanBeDataDriven="True" CanLinkedNodesBeDataDriven="True" IncomingActionLabel="Called By" OutgoingActionLabel="Calls" />
|
||||
<Category Id="CodeSchema_FieldReference" Label="Field Reference" CanBeDataDriven="True" CanLinkedNodesBeDataDriven="True" IncomingActionLabel="Referenced By" OutgoingActionLabel="References Fields" />
|
||||
<Category Id="CodeSchema_FieldWrite" Label="Field Write" BasedOn="CodeSchema_FieldReference" CanBeDataDriven="True" CanLinkedNodesBeDataDriven="True" IncomingActionLabel="Written By" OutgoingActionLabel="Writes Fields" />
|
||||
<Category Id="CodeSchema_ReturnTypeLink" Label="Return" CanBeDataDriven="True" CanLinkedNodesBeDataDriven="True" IncomingActionLabel="Return types" OutgoingActionLabel="Return types" />
|
||||
<Category Id="File" Label="File" CanBeDataDriven="True" DefaultAction="Microsoft.Contains" Icon="File" NavigationActionLabel="Files" />
|
||||
<Category Id="FileSystem.Category.FileOfType.dll" BasedOn="CodeSchema_Assembly" CanBeDataDriven="True" IsProviderRoot="False" />
|
||||
<Category Id="FileSystem.Category.FileOfType.exe" BasedOn="CodeSchema_Assembly" CanBeDataDriven="True" IsProviderRoot="False" />
|
||||
<Category Id="References" Label="References" CanBeDataDriven="True" CanLinkedNodesBeDataDriven="True" IncomingActionLabel="Referenced By" OutgoingActionLabel="References" />
|
||||
</Categories>
|
||||
<Properties>
|
||||
<Property Id="AssemblyTimestamp" DataType="System.DateTime" />
|
||||
<Property Id="Bounds" DataType="System.Windows.Rect" />
|
||||
<Property Id="CanBeDataDriven" Label="CanBeDataDriven" Description="CanBeDataDriven" DataType="System.Boolean" />
|
||||
<Property Id="CanLinkedNodesBeDataDriven" Label="CanLinkedNodesBeDataDriven" Description="CanLinkedNodesBeDataDriven" DataType="System.Boolean" />
|
||||
<Property Id="CodeSchemaProperty_StrongName" Label="StrongName" Description="StrongName" DataType="System.String" />
|
||||
<Property Id="DataVirtualized" Label="Data Virtualized" Description="If true, the graph can contain nodes and links that represent data for virtualized nodes/links (i.e. not actually created in the graph)." DataType="System.Boolean" />
|
||||
<Property Id="DefaultAction" Label="DefaultAction" Description="DefaultAction" DataType="System.String" />
|
||||
<Property Id="DelayedChildNodesState" Label="Delayed Child Nodes State" Description="Unspecified if the delayed child nodes state is not specified. NotFetched if the group contains child nodes that are not fetched into the graph yet. Fetched if the group has all its delayed child nodes already fetched." DataType="Microsoft.VisualStudio.GraphModel.DelayedDataState" />
|
||||
<Property Id="DelayedCrossGroupLinksState" Label="Delayed Cross-Group Links State" Description="Unspecified if the delayed cross-group links state is not specified. NotFetched if delayed cross-group links on this node are not fetched into the graph yet. Fetched if all delayed cross-group links have already fetched." DataType="Microsoft.VisualStudio.GraphModel.DelayedDataState" />
|
||||
<Property Id="Expression" DataType="System.String" />
|
||||
<Property Id="FilePath" Label="File Path" Description="File Path" DataType="System.String" />
|
||||
<Property Id="Group" Label="Group" Description="Display the node as a group" DataType="Microsoft.VisualStudio.GraphModel.GraphGroupStyle" />
|
||||
<Property Id="GroupLabel" DataType="System.String" />
|
||||
<Property Id="Icon" Label="Icon" Description="Icon" DataType="System.String" />
|
||||
<Property Id="IncomingActionLabel" Label="IncomingActionLabel" Description="IncomingActionLabel" DataType="System.String" />
|
||||
<Property Id="IsEnabled" DataType="System.Boolean" />
|
||||
<Property Id="IsProviderRoot" Label="IsProviderRoot" Description="IsProviderRoot" DataType="System.Boolean" />
|
||||
<Property Id="IsSourceVirtualized" Label="Link Source Virtualized" Description="If true, the link source end contains data for virtualized nodes/links (i.e. not actually created in the graph)." DataType="System.Boolean" />
|
||||
<Property Id="IsTargetVirtualized" Label="Link Target Virtualized" Description="If true, the link target end contains data for virtualized nodes/links (i.e. not actually created in the graph)." DataType="System.Boolean" />
|
||||
<Property Id="Label" Label="Label" Description="Displayable label of an Annotatable object" DataType="System.String" />
|
||||
<Property Id="Layout" DataType="System.String" />
|
||||
<Property Id="NavigationActionLabel" Label="NavigationActionLabel" Description="NavigationActionLabel" DataType="System.String" />
|
||||
<Property Id="OutgoingActionLabel" Label="OutgoingActionLabel" Description="OutgoingActionLabel" DataType="System.String" />
|
||||
<Property Id="TargetType" DataType="System.Type" />
|
||||
<Property Id="UseManualLocation" DataType="System.Boolean" />
|
||||
<Property Id="Value" DataType="System.String" />
|
||||
<Property Id="ValueLabel" DataType="System.String" />
|
||||
<Property Id="Visibility" Label="Visibility" Description="Defines whether a node in the graph is visible or not" DataType="System.Windows.Visibility" />
|
||||
<Property Id="Weight" Label="Weight" Description="Weight" DataType="System.Double" />
|
||||
<Property Id="ZoomLevel" DataType="System.String" />
|
||||
</Properties>
|
||||
<QualifiedNames>
|
||||
<Name Id="Assembly" Label="Assembly" ValueType="Uri" />
|
||||
</QualifiedNames>
|
||||
<IdentifierAliases>
|
||||
<Alias n="1" Uri="Assembly=$(8baa9433-8034-4fde-822c-537c59d3a7ec.OutputPathUri)" />
|
||||
<Alias n="2" Id="(@1)" />
|
||||
<Alias n="3" Uri="Assembly=$(444ef10c-046e-47ad-a9a5-17318d488723.OutputPathUri)" />
|
||||
<Alias n="4" Id="(@3)" />
|
||||
<Alias n="5" Uri="Assembly=$(c9c45b72-05a3-4962-bc13-a78b1f4b1925.OutputPathUri)" />
|
||||
<Alias n="6" Id="(@5)" />
|
||||
<Alias n="7" Uri="Assembly=$(b9d1ac5b-7a6f-4b14-9ff8-3a1fc03519e2.OutputPathUri)" />
|
||||
<Alias n="8" Id="(@7)" />
|
||||
<Alias n="9" Uri="Assembly=$(02eeba8c-7b22-4bc3-bf3a-8de23eaf2e61.OutputPathUri)" />
|
||||
<Alias n="10" Id="(@9)" />
|
||||
</IdentifierAliases>
|
||||
<Styles>
|
||||
<Style TargetType="Node" GroupLabel="Results" ValueLabel="True">
|
||||
<Condition Expression="HasCategory('QueryResult')" />
|
||||
<Setter Property="Background" Value="#FFBCFFBE" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Test Project" ValueLabel="Test Project">
|
||||
<Condition Expression="HasCategory('CodeMap_TestProject')" />
|
||||
<Setter Property="Icon" Value="CodeMap_TestProject" />
|
||||
<Setter Property="Background" Value="#FF307A69" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Web Project" ValueLabel="Web Project">
|
||||
<Condition Expression="HasCategory('CodeMap_WebProject')" />
|
||||
<Setter Property="Icon" Value="CodeMap_WebProject" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Windows Store Project" ValueLabel="Windows Store Project">
|
||||
<Condition Expression="HasCategory('CodeMap_WindowsStoreProject')" />
|
||||
<Setter Property="Icon" Value="CodeMap_WindowsStoreProject" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Phone Project" ValueLabel="Phone Project">
|
||||
<Condition Expression="HasCategory('CodeMap_PhoneProject')" />
|
||||
<Setter Property="Icon" Value="CodeMap_PhoneProject" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Portable Library" ValueLabel="Portable Library">
|
||||
<Condition Expression="HasCategory('CodeMap_PortableLibraryProject')" />
|
||||
<Setter Property="Icon" Value="CodeMap_PortableLibraryProject" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="WPF Project" ValueLabel="WPF Project">
|
||||
<Condition Expression="HasCategory('CodeMap_WpfProject')" />
|
||||
<Setter Property="Icon" Value="CodeMap_WpfProject" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="VSIX Project" ValueLabel="VSIX Project">
|
||||
<Condition Expression="HasCategory('CodeMap_VsixProject')" />
|
||||
<Setter Property="Icon" Value="CodeMap_VsixProject" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Modeling Project" ValueLabel="Modeling Project">
|
||||
<Condition Expression="HasCategory('CodeMap_ModelingProject')" />
|
||||
<Setter Property="Icon" Value="CodeMap_ModelingProject" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Assembly" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Assembly')" />
|
||||
<Setter Property="Background" Value="#FF094167" />
|
||||
<Setter Property="Stroke" Value="#FF094167" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Assembly" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Namespace" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Namespace')" />
|
||||
<Setter Property="Background" Value="#FF0E619A" />
|
||||
<Setter Property="Stroke" Value="#FF0E619A" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Namespace" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Interface" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Interface')" />
|
||||
<Setter Property="Background" Value="#FF1382CE" />
|
||||
<Setter Property="Stroke" Value="#FF1382CE" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Interface" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Struct" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Struct')" />
|
||||
<Setter Property="Background" Value="#FF1382CE" />
|
||||
<Setter Property="Stroke" Value="#FF1382CE" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Struct" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Enumeration" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Enum')" />
|
||||
<Setter Property="Background" Value="#FF1382CE" />
|
||||
<Setter Property="Stroke" Value="#FF1382CE" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Enum" />
|
||||
<Setter Property="LayoutSettings" Value="List" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Delegate" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Delegate')" />
|
||||
<Setter Property="Background" Value="#FF1382CE" />
|
||||
<Setter Property="Stroke" Value="#FF1382CE" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Delegate" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Class" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Type')" />
|
||||
<Setter Property="Background" Value="#FF0E70C0" />
|
||||
<Setter Property="Stroke" Value="#FF0E70C0" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Class" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Property" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Property')" />
|
||||
<Setter Property="Background" Value="#FFE0E0E0" />
|
||||
<Setter Property="Stroke" Value="#FFE0E0E0" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Property" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Method" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Method') Or HasCategory('CodeSchema_CallStackUnresolvedMethod')" />
|
||||
<Setter Property="Background" Value="#FFE0E0E0" />
|
||||
<Setter Property="Stroke" Value="#FFE0E0E0" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Method" />
|
||||
<Setter Property="LayoutSettings" Value="List" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Event" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Event')" />
|
||||
<Setter Property="Background" Value="#FFE0E0E0" />
|
||||
<Setter Property="Stroke" Value="#FFE0E0E0" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Event" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Field" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Field')" />
|
||||
<Setter Property="Background" Value="#FFE0E0E0" />
|
||||
<Setter Property="Stroke" Value="#FFE0E0E0" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Field" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Out Parameter" ValueLabel="Has category">
|
||||
<Condition Expression="CodeSchemaProperty_IsOut = 'True'" />
|
||||
<Setter Property="Icon" Value="CodeSchema_OutParameter" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Parameter" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_Parameter')" />
|
||||
<Setter Property="Icon" Value="CodeSchema_Parameter" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Local Variable" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('CodeSchema_LocalExpression')" />
|
||||
<Setter Property="Icon" Value="CodeSchema_LocalExpression" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Externals" ValueLabel="Has category">
|
||||
<Condition Expression="HasCategory('Externals')" />
|
||||
<Setter Property="Background" Value="#FF424242" />
|
||||
<Setter Property="Stroke" Value="#FF424242" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Inherits From" ValueLabel="True">
|
||||
<Condition Expression="HasCategory('InheritsFrom')" />
|
||||
<Setter Property="Stroke" Value="#FF00A600" />
|
||||
<Setter Property="StrokeDashArray" Value="2 0" />
|
||||
<Setter Property="DrawArrow" Value="true" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Implements" ValueLabel="True">
|
||||
<Condition Expression="HasCategory('Implements')" />
|
||||
<Setter Property="Stroke" Value="#8000A600" />
|
||||
<Setter Property="StrokeDashArray" Value="2 2" />
|
||||
<Setter Property="DrawArrow" Value="true" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Calls" ValueLabel="True">
|
||||
<Condition Expression="HasCategory('CodeSchema_Calls')" />
|
||||
<Setter Property="Stroke" Value="#FFFF00FF" />
|
||||
<Setter Property="StrokeDashArray" Value="2 0" />
|
||||
<Setter Property="DrawArrow" Value="true" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Function Pointer" ValueLabel="True">
|
||||
<Condition Expression="HasCategory('CodeSchema_FunctionPointer')" />
|
||||
<Setter Property="Stroke" Value="#FFFF00FF" />
|
||||
<Setter Property="StrokeDashArray" Value="2 2" />
|
||||
<Setter Property="DrawArrow" Value="true" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Field Read" ValueLabel="True">
|
||||
<Condition Expression="HasCategory('CodeSchema_FieldRead')" />
|
||||
<Setter Property="Stroke" Value="#FF00AEEF" />
|
||||
<Setter Property="StrokeDashArray" Value="2 2" />
|
||||
<Setter Property="DrawArrow" Value="true" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Field Write" ValueLabel="True">
|
||||
<Condition Expression="HasCategory('CodeSchema_FieldWrite')" />
|
||||
<Setter Property="Stroke" Value="#FF00AEEF" />
|
||||
<Setter Property="DrawArrow" Value="true" />
|
||||
<Setter Property="IsHidden" Value="false" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Inherits From" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="HasCategory('InheritsFrom') And Target.HasCategory('CodeSchema_Class')" />
|
||||
<Setter Property="TargetDecorator" Value="OpenArrow" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Implements" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="HasCategory('Implements') And Target.HasCategory('CodeSchema_Interface')" />
|
||||
<Setter Property="TargetDecorator" Value="OpenArrow" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Comment Link" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="Source.HasCategory('Comment')" />
|
||||
<Setter Property="Stroke" Value="#FFE5C365" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Cursor Location Changed" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="IsCursorLocation" />
|
||||
<Setter Property="IndicatorWest" Value="WestIndicator" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Disabled Breakpoint Location Changed" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="DisabledBreakpointCount" />
|
||||
<Setter Property="IndicatorWest" Value="WestIndicator" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Enabled Breakpoint Location Changed" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="EnabledBreakpointCount" />
|
||||
<Setter Property="IndicatorWest" Value="WestIndicator" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Instruction Pointer Location Changed" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="IsInstructionPointerLocation" />
|
||||
<Setter Property="IndicatorWest" Value="WestIndicator" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Current Callstack Changed" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="IsCurrentCallstackFrame" />
|
||||
<Setter Property="IndicatorWest" Value="WestIndicator" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Return" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="HasCategory('CodeSchema_ReturnTypeLink')" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="References" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="HasCategory('References')" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Uses Attribute" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="HasCategory('CodeSchema_AttributeUse')" />
|
||||
</Style>
|
||||
<Style TargetType="Node" GroupLabel="Solution Folder" ValueLabel="True" Visibility="Hidden">
|
||||
<Condition Expression="HasCategory('CodeMap_SolutionFolder')" />
|
||||
<Setter Property="Background" Value="#FFDEBA83" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="Project Reference" ValueLabel="Project Reference">
|
||||
<Condition Expression="HasCategory('CodeMap_ProjectReference')" />
|
||||
<Setter Property="Stroke" Value="#9A9A9A" />
|
||||
<Setter Property="StrokeDashArray" Value="2 2" />
|
||||
<Setter Property="DrawArrow" Value="true" />
|
||||
</Style>
|
||||
<Style TargetType="Link" GroupLabel="External Reference" ValueLabel="External Reference">
|
||||
<Condition Expression="HasCategory('CodeMap_ExternalReference')" />
|
||||
<Setter Property="Stroke" Value="#9A9A9A" />
|
||||
<Setter Property="StrokeDashArray" Value="2 2" />
|
||||
<Setter Property="DrawArrow" Value="true" />
|
||||
</Style>
|
||||
</Styles>
|
||||
<Paths>
|
||||
<Path Id="02eeba8c-7b22-4bc3-bf3a-8de23eaf2e61.OutputPath" Value="C:\Users\robert.nelsen\Desktop\DataPro\SourceCode\DataPro_Diagraming\DataPRO\DASFactory\bin\Debug\DASFactory.dll" />
|
||||
<Path Id="02eeba8c-7b22-4bc3-bf3a-8de23eaf2e61.OutputPathUri" Value="file:///C:/Users/robert.nelsen/Desktop/DataPro/SourceCode/DataPro_Diagraming/DataPRO/DASFactory/bin/Debug/DASFactory.dll" />
|
||||
<Path Id="444ef10c-046e-47ad-a9a5-17318d488723.OutputPath" Value="C:\Users\robert.nelsen\Desktop\DataPro\SourceCode\DataPro_Diagraming\DataPRO\SensorDB\bin\Debug\SensorDB.dll" />
|
||||
<Path Id="444ef10c-046e-47ad-a9a5-17318d488723.OutputPathUri" Value="file:///C:/Users/robert.nelsen/Desktop/DataPro/SourceCode/DataPro_Diagraming/DataPRO/SensorDB/bin/Debug/SensorDB.dll" />
|
||||
<Path Id="8baa9433-8034-4fde-822c-537c59d3a7ec.OutputPath" Value="C:\Users\robert.nelsen\Desktop\DataPro\SourceCode\DataPro_Diagraming\DataPRO\DataPRO\bin\Debug\DataPRO.exe" />
|
||||
<Path Id="8baa9433-8034-4fde-822c-537c59d3a7ec.OutputPathUri" Value="file:///C:/Users/robert.nelsen/Desktop/DataPro/SourceCode/DataPro_Diagraming/DataPRO/DataPRO/bin/Debug/DataPRO.exe" />
|
||||
<Path Id="b9d1ac5b-7a6f-4b14-9ff8-3a1fc03519e2.OutputPath" Value="C:\Users\robert.nelsen\Desktop\DataPro\SourceCode\DataPro_Diagraming\Common\DTS.Common.SerializationPlus\bin\Debug\DTS.Common.SerializationPlus.dll" />
|
||||
<Path Id="b9d1ac5b-7a6f-4b14-9ff8-3a1fc03519e2.OutputPathUri" Value="file:///C:/Users/robert.nelsen/Desktop/DataPro/SourceCode/DataPro_Diagraming/Common/DTS.Common.SerializationPlus/bin/Debug/DTS.Common.SerializationPlus.dll" />
|
||||
<Path Id="c9c45b72-05a3-4962-bc13-a78b1f4b1925.OutputPath" Value="C:\Users\robert.nelsen\Desktop\DataPro\SourceCode\DataPro_Diagraming\DataPRO\IService\bin\Debug\IService.dll" />
|
||||
<Path Id="c9c45b72-05a3-4962-bc13-a78b1f4b1925.OutputPathUri" Value="file:///C:/Users/robert.nelsen/Desktop/DataPro/SourceCode/DataPro_Diagraming/DataPRO/IService/bin/Debug/IService.dll" />
|
||||
</Paths>
|
||||
</DirectedGraph>
|
||||
@@ -0,0 +1,21 @@
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public interface IDASState
|
||||
{
|
||||
Status Status { get; }
|
||||
IDASFactory DASFactory { get; set; }
|
||||
Action OnEntry { get; }
|
||||
Action OnExit { get; }
|
||||
State State { get; }
|
||||
void OnEnterState();
|
||||
void OnExitState();
|
||||
}
|
||||
|
||||
public interface IDASStateWithSelector : IDASState
|
||||
{
|
||||
IDASState StateSelector();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,359 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
|
||||
namespace DTS.Slice.Service
|
||||
{
|
||||
public class EventAttribute : Attribute
|
||||
{
|
||||
// public enum TypeValues
|
||||
// {
|
||||
// EventNumber = 0x01, EventName, EventDescription, SampleRate,
|
||||
// TotalSamples, TriggerSampleNumber, StartRecordSampleNumber,
|
||||
// EventTime, FilterFrequency, TotalChannels, PreScaleFactors, PostScaleFactors, Offsets,
|
||||
// Excitation, ConfigAttributes
|
||||
// }
|
||||
|
||||
// public UInt16 EventNumber
|
||||
// {
|
||||
// get { return _storenumber; }
|
||||
// set { _storenumber = value; }
|
||||
// }
|
||||
|
||||
// public EventAttribute()
|
||||
// : base()
|
||||
// {
|
||||
// _store = AttributeStore.Event;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventNumber: EventAttribute
|
||||
//{
|
||||
// public UInt32 Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// UInt32 tmp;
|
||||
// ByteConvertor.Convert (Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray (value); }
|
||||
// }
|
||||
|
||||
// public EventNumber ()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventNumber";
|
||||
// _typevalue = (byte)TypeValues.EventNumber;
|
||||
// _datatype = AttributeTypes.AttributeDataTypes.UInt16;
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
//public class EventName : EventAttribute
|
||||
//{
|
||||
// public string Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// string tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public EventName()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventName";
|
||||
// _typevalue = (byte)TypeValues.EventName;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.Ascii;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventSampleRate : EventAttribute
|
||||
//{
|
||||
// public UInt32 Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// UInt32 tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public EventSampleRate()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventSampleRate";
|
||||
// _typevalue = (byte)TypeValues.SampleRate;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.UInt32;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventDescription : EventAttribute
|
||||
//{
|
||||
// public string Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// string tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public EventDescription()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventDescription";
|
||||
// _typevalue = (byte)TypeValues.EventDescription;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.Ascii;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventTotalSamples: EventAttribute
|
||||
//{
|
||||
// public UInt64 Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// UInt64 tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public EventTotalSamples()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventTotalSamples";
|
||||
// _typevalue = (byte)TypeValues.TotalSamples;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.UInt64;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventTriggerSampleNumber: EventAttribute
|
||||
//{
|
||||
// public UInt64 Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// UInt64 tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public EventTriggerSampleNumber()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventTriggerSampleNumber";
|
||||
// _typevalue = (byte)TypeValues.TriggerSampleNumber;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.UInt64;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventStartRecordSampleNumber: EventAttribute
|
||||
//{
|
||||
// public UInt64 Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// UInt64 tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public EventStartRecordSampleNumber()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventStartRecordSampleNumber";
|
||||
// _typevalue = (byte)TypeValues.StartRecordSampleNumber;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.UInt64;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventTotalChannels: EventAttribute
|
||||
//{
|
||||
// public byte Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// byte tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public EventTotalChannels()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventTotalChannels";
|
||||
// _typevalue = (byte)TypeValues.TotalChannels;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.UInt8;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventFilterFrequency: EventAttribute
|
||||
//{
|
||||
// public double Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// double tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public EventFilterFrequency()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventFilterFrequency";
|
||||
// _typevalue = (byte)TypeValues.FilterFrequency;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.Float64;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventStartTime: EventAttribute
|
||||
//{
|
||||
// public DateTime Value
|
||||
// {
|
||||
// // the time stamp will be returned as 2 numbers
|
||||
// // one UInt32 for seconds since 1970 00:00 UTC
|
||||
// // and one UInt32 for milliseconds
|
||||
// get
|
||||
// {
|
||||
// UInt32 seconds;
|
||||
// ByteConvertor.Convert(Data, 0, out seconds);
|
||||
// UInt32 fractions;
|
||||
// ByteConvertor.Convert(Data, 4, out fractions);
|
||||
// DateTime eventTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
// eventTime.AddSeconds((double)seconds + ((double)fractions / 1000.0));
|
||||
// return eventTime;
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// DateTime baseTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
// TimeSpan leftOver = value.Subtract(baseTime);
|
||||
// UInt32 seconds = (UInt32)leftOver.TotalSeconds;
|
||||
// UInt32 fractions = (UInt32)(leftOver.TotalSeconds - (double)seconds);
|
||||
// byte[] first = ByteConvertor.ToByteArray(seconds);
|
||||
// byte[] second = ByteConvertor.ToByteArray(fractions);
|
||||
// Data = new byte[first.Length + second.Length];
|
||||
// Array.Copy(first, Data, first.Length);
|
||||
// Array.Copy(second, 0, Data, first.Length, second.Length);
|
||||
// }
|
||||
// }
|
||||
|
||||
// public EventStartTime()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventStartTime";
|
||||
// _typevalue = (byte)TypeValues.EventTime;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.UInt32Star;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventExcitation: EventAttribute
|
||||
//{
|
||||
// public double Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// double tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public EventExcitation()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventExcitation";
|
||||
// _typevalue = (byte)TypeValues.Excitation;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.Float64;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class PreEventScaleFactors: EventAttribute
|
||||
//{
|
||||
// public Dictionary<byte, double> Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// return ByteArrayToDict(Data);
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// Data = DictToByteArray(value);
|
||||
// }
|
||||
// }
|
||||
|
||||
// public PreEventScaleFactors()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "PreEventScaleFactors";
|
||||
// _typevalue = (byte)TypeValues.PreScaleFactors;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.DoubleDict;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class PostEventScaleFactors: EventAttribute
|
||||
//{
|
||||
// public Dictionary<byte, double> Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// return ByteArrayToDict(Data);
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// Data = DictToByteArray(value);
|
||||
// }
|
||||
// }
|
||||
|
||||
// public PostEventScaleFactors()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "PostEventScaleFactors";
|
||||
// _typevalue = (byte)TypeValues.PostScaleFactors;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.DoubleDict;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class EventConfigAttributes: EventAttribute
|
||||
//{
|
||||
// public string Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// string tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public EventConfigAttributes()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "EventConfigAttributes";
|
||||
// _typevalue = (byte)TypeValues.ConfigAttributes;
|
||||
// _datatype = QueryArmAttribute.AttributeDataTypes.Ascii;
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
// Custom comparer for the IDASCommunication class.
|
||||
public class AnalogInputDASChannelComparer : IEqualityComparer<AnalogInputDASChannel>
|
||||
{
|
||||
// GainInfo are equal if their Gain is equal.
|
||||
public bool Equals(AnalogInputDASChannel x, AnalogInputDASChannel y)
|
||||
{
|
||||
// Check whether the compared objects reference the same data.
|
||||
if (ReferenceEquals(x, y))
|
||||
return true;
|
||||
|
||||
// Check whether any of the compared objects is null.
|
||||
if (x is null || y is null)
|
||||
return false;
|
||||
|
||||
if (x.OwningModule == null || y.OwningModule == null)
|
||||
return false;
|
||||
|
||||
if (x.OwningModule.OwningDAS == null || y.OwningModule.OwningDAS == null)
|
||||
return false;
|
||||
|
||||
if (string.IsNullOrEmpty(x.OwningModule.OwningDAS.SerialNumber) ||
|
||||
string.IsNullOrEmpty(y.OwningModule.OwningDAS.SerialNumber))
|
||||
return false;
|
||||
|
||||
// Check whether they are equal.
|
||||
return x.ModuleChannelNumber == y.ModuleChannelNumber &&
|
||||
x.OwningModule.ModuleArrayIndex == y.OwningModule.ModuleArrayIndex &&
|
||||
x.OwningModule.OwningDAS.SerialNumber == y.OwningModule.OwningDAS.SerialNumber &&
|
||||
x.AbsoluteDisplayOrder == y.AbsoluteDisplayOrder &&
|
||||
x.UnitConverision == y.UnitConverision;
|
||||
}
|
||||
|
||||
// If Equals() returns true for a pair of objects,
|
||||
// GetHashCode must return the same value for these objects.
|
||||
|
||||
public int GetHashCode(AnalogInputDASChannel analog)
|
||||
{
|
||||
// Check whether the object is null.
|
||||
|
||||
if (string.IsNullOrEmpty(analog.OwningModule?.OwningDAS?.SerialNumber))
|
||||
return 0;
|
||||
|
||||
// Get the hash code for the fields
|
||||
return analog.ModuleChannelNumber.GetHashCode() ^
|
||||
analog.OwningModule.ModuleArrayIndex.GetHashCode() ^
|
||||
analog.OwningModule.OwningDAS.SerialNumber.GetHashCode() ^
|
||||
analog.AbsoluteDisplayOrder.GetHashCode() ^
|
||||
analog.UnitConverision.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using DASFactoryDb;
|
||||
using DASFactoryDb.Config;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// An instance of InfoResult is populated and filled when a DASFactory object discovers a DAS.
|
||||
/// It contains information about the DAS hardware as well as the coinciding modules and channels.
|
||||
/// It also has some functions to help translate between different numbering systems used
|
||||
/// during DAS communications, such as Module numbers, Channel numbers and DASChannel numbers.
|
||||
/// </summary>
|
||||
public class InfoResult : IInfoResult
|
||||
{
|
||||
public string MACAddress { get; set; }
|
||||
/// <summary>
|
||||
/// Describes one module in this DAS.
|
||||
/// </summary>
|
||||
public class Module : IInfoResultModule
|
||||
{
|
||||
/// <summary>
|
||||
/// Serial number of this module
|
||||
/// </summary>
|
||||
public string SerialNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Firmware version in this module
|
||||
/// </summary>
|
||||
public string FirmwareVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// who does this module belong to?
|
||||
/// </summary>
|
||||
public InfoResult OwningInfoResult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of this Module as it would be indexed in an array of Modules.
|
||||
/// </summary>
|
||||
public int ModuleArrayIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many channels are connected to this Module.
|
||||
/// </summary>
|
||||
public uint NumberOfChannels { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What sample rates does it support (in samples per second).
|
||||
/// </summary>
|
||||
public uint[] SupportedSampleRates { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An associative list (Dictionary) of sample rates and corresponding
|
||||
/// Anti-Aliasing filter frequencies.
|
||||
/// </summary>
|
||||
public Dictionary<uint, float> SampleRate2AAFrequency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many bytes of sample storage is available in this module? This is null
|
||||
/// if it's specified per DAS instead.
|
||||
/// </summary>
|
||||
public UInt64? MaxEventStorageSpaceInBytes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many bytes are stored for all channels at each sample interval? This is
|
||||
/// null if it's specified per DAS instead.
|
||||
/// </summary>
|
||||
public uint? NumberOfBytesPerSampleClock { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many samples can you record in this module?
|
||||
/// </summary>
|
||||
public double MaxRecordingSamples { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="System.DateTime"/> of this module's last calibration.
|
||||
/// </summary>
|
||||
public DateTime? CalibrationDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if a TDAS rack is armed and doesn't respond to some queries.
|
||||
/// </summary>
|
||||
public bool RackIsUnreadable { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// What type of module is this?
|
||||
/// </summary>
|
||||
public DFConstantsAndEnums.ModuleType TypeOfModule { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What recording modes does this Module support.
|
||||
/// </summary>
|
||||
public DFConstantsAndEnums.RecordingMode[] SupportedModes { get; set; }
|
||||
|
||||
public bool IsProgrammable { get; set; } = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An array of the modules in this DAS.
|
||||
/// </summary>
|
||||
public IInfoResultModule[] Modules { get; set; }
|
||||
|
||||
public List<Common.Classes.Hardware.ExternalTilt> ActiveExternalTilts { get; set; } = new List<Common.Classes.Hardware.ExternalTilt>();
|
||||
|
||||
[XmlIgnore]
|
||||
public IDASCommunication OwningDAS { get; set; }
|
||||
|
||||
public uint MaxNumberOfModules { get; set; }
|
||||
public InfoResult()
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// How many bytes of sample storage is available in this DAS? This is null if
|
||||
/// it's specified per module instead.
|
||||
/// </summary>
|
||||
public UInt64? MaxEventStorageSpaceInBytes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many bytes are stored for all channels at each sample interval? This is
|
||||
/// null if it's specified per module instead.
|
||||
/// </summary>
|
||||
public uint? NumberOfBytesPerSampleClock { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// FB15353 Is this device hardware configured for streaming only?
|
||||
/// null if device doesn't support a streaming-only configuration
|
||||
/// </summary>
|
||||
public bool? DeviceStreamingOnly { get; set; }
|
||||
|
||||
// temporary constant
|
||||
public int NumberOfBridgeChannels { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the battery.
|
||||
/// </summary>
|
||||
public IEID BatteryID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// TRUE if a battery is present in the hardware unit.
|
||||
/// </summary>
|
||||
public bool HasBattery
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BatteryID == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (string.IsNullOrEmpty(BatteryID.ID))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (EIDReader.IsBlankID(BatteryID.ID)) { return false; }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public byte MapDASChannelNumber2RealtimeChannelNumber(int channelNumber)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (Modules[0].TypeOfModule)
|
||||
{
|
||||
case DFConstantsAndEnums.ModuleType.G5Digital:
|
||||
// This case is never hit because of the use of Modules.First(), but left for clarity.
|
||||
return Convert.ToByte(32);
|
||||
case DFConstantsAndEnums.ModuleType.G5Analog:
|
||||
return (byte)channelNumber;
|
||||
case DFConstantsAndEnums.ModuleType.ProDIM:
|
||||
return Convert.ToByte(channelNumber);
|
||||
//return MapDASChannelNumber2ModuleChannelNumber(channelNumber);
|
||||
case DFConstantsAndEnums.ModuleType.ProSIM:
|
||||
return Convert.ToByte(channelNumber);
|
||||
//return MapDASChannelNumber2ModuleChannelNumber(channelNumber);
|
||||
case DFConstantsAndEnums.ModuleType.SLICEPro_TOM:
|
||||
return Convert.ToByte(channelNumber);
|
||||
case DFConstantsAndEnums.ModuleType.ProTOM:
|
||||
return Convert.ToByte(channelNumber);
|
||||
//return MapDASChannelNumber2ModuleChannelNumber(channelNumber);
|
||||
case DFConstantsAndEnums.ModuleType.RibeyeLED:
|
||||
return Convert.ToByte(channelNumber);
|
||||
case DFConstantsAndEnums.ModuleType.SliceARS:
|
||||
return Convert.ToByte(channelNumber);
|
||||
case DFConstantsAndEnums.ModuleType.SliceBridge:
|
||||
return Convert.ToByte(channelNumber);
|
||||
case DFConstantsAndEnums.ModuleType.SLICEIEPE:
|
||||
return Convert.ToByte(channelNumber);
|
||||
default:
|
||||
return Convert.ToByte(channelNumber);
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex) { APILogger.Log("MapDASChannelNumber2RealtimeChannelNumber failed", ex); }
|
||||
return Convert.ToByte(channelNumber);
|
||||
}
|
||||
/// <summary>
|
||||
/// Convert a DASChannel number (0..29) to a module array index (0..9).
|
||||
/// A DASChannel number is a channel's identifier global within this DAS.
|
||||
/// A Module array index is a Module identifier as it would be indexed in an array.
|
||||
/// </summary>
|
||||
/// <param name="channelNumber">The DAS channel number to convert</param>
|
||||
/// <returns>The module array index</returns>
|
||||
public byte MapDASChannelNumber2ModuleArrayIndex(int channelNumber)
|
||||
{
|
||||
foreach (var module in Modules)
|
||||
{
|
||||
int numChannels = Convert.ToInt32(module.NumberOfChannels);
|
||||
if (channelNumber >= numChannels) { channelNumber -= numChannels; }
|
||||
else { return (byte)module.ModuleArrayIndex; }
|
||||
}
|
||||
return (byte)(Modules.Length - 1);
|
||||
//return (byte)(channelNumber / NumberOfBridgeChannels);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a DAS channel number (0..29) to a module device id (1..10)
|
||||
/// A DASChannel number is a channel's identifier global within this DAS.
|
||||
/// A Module deviceID is an identifier for the corresponding channel that starts at 1 for the first Module.
|
||||
/// </summary>
|
||||
/// <param name="channelNumber">The DAS channel number to convert</param>
|
||||
/// <returns>The module device id</returns>
|
||||
public byte MapDASChannelNumber2ModuleDeviceID(int channelNumber)
|
||||
{
|
||||
return (byte)(channelNumber / NumberOfBridgeChannels + 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a DAS channel number (0..29) to a module channel number (0..2)
|
||||
/// A DASChannel number is a channel's identifier global within this DAS.
|
||||
/// A moduleChannel number is the channel's identifier relative only to it's parent Module.
|
||||
/// </summary>
|
||||
/// <param name="channelNumber">The DAS channel number to convert</param>
|
||||
/// <returns>The channel number within the module</returns>
|
||||
public byte MapDASChannelNumber2ModuleChannelNumber(int channelNumber)
|
||||
{
|
||||
if (OwningDAS is EthernetTDAS)
|
||||
{
|
||||
var ch = Convert.ToUInt32(channelNumber);
|
||||
foreach (var m in Modules)
|
||||
{
|
||||
if (m.NumberOfChannels <= ch)
|
||||
{
|
||||
ch -= m.NumberOfChannels;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (byte)ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (byte)(channelNumber % NumberOfBridgeChannels);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a module array index (0..9) and a module channel number (0..2) to a DAS channel number (0..29)
|
||||
/// A Module array index is a Module identifier as it would be indexed in an array.
|
||||
/// A moduleChannel number is the channel's identifier relative only to it's parent Module.
|
||||
/// A DASChannel number is a channel's identifier global within this DAS.
|
||||
/// </summary>
|
||||
/// <param name="moduleArrayIdx">The module array index (0..9)</param>
|
||||
/// <param name="channelNumber">The module channel number (0..2)</param>
|
||||
/// <returns>The DAS channel number within the DAS (0..29)</returns>
|
||||
public byte MapModuleArrayIndexAndChannelNum2DASChannel(int moduleArrayIdx, int channelNumber)
|
||||
{
|
||||
uint channel = 0;
|
||||
foreach (var module in Modules)
|
||||
{
|
||||
//30429 Invalidate/fail sooner than Arm step if DAS doesn't have streaming capability/channel (TSR AIR may or may not)
|
||||
if (module == null) { break; }
|
||||
if (module.ModuleArrayIndex < moduleArrayIdx) { channel += module.NumberOfChannels; }
|
||||
else if (module.ModuleArrayIndex > moduleArrayIdx) { break; }
|
||||
else
|
||||
{
|
||||
channel += Convert.ToUInt32(channelNumber);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (byte)(channel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="System.DateTime"/> returns the datetime of the DAS (or the oldest module's calibration)
|
||||
/// returns 1970-01-01 is considering invalid/NA
|
||||
/// </summary>
|
||||
private DateTime? _calibrationDate;
|
||||
public DateTime? CalibrationDate
|
||||
{
|
||||
get
|
||||
{
|
||||
var dCalDate = new DateTime(1970, 1, 1);
|
||||
if (null != _calibrationDate)
|
||||
{
|
||||
dCalDate = (DateTime)_calibrationDate;
|
||||
}
|
||||
if (null != Modules)
|
||||
{
|
||||
foreach (var module in Modules)
|
||||
{
|
||||
//30429 Invalidate/fail sooner than Arm step if DAS doesn't have streaming capability/channel (TSR AIR may or may not)
|
||||
if (module == null) { continue; }
|
||||
if (module.SerialNumber.ToLower().Contains("empty")) { continue; }
|
||||
if (null != module.CalibrationDate)
|
||||
{
|
||||
var mCalDate = (DateTime)module.CalibrationDate;
|
||||
if (mCalDate < dCalDate || dCalDate.Year == 1970) { dCalDate = mCalDate; }
|
||||
}
|
||||
}
|
||||
}
|
||||
return dCalDate;
|
||||
}
|
||||
set => _calibrationDate = value;
|
||||
}
|
||||
|
||||
public static void SetDASInfo(IDASCommunication das)
|
||||
{
|
||||
if (!DASFactoryDb.DbWrapper.Connected) { return; }
|
||||
if (das.RecordId < 0) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
Config.DASInfoClear(das.RecordId);
|
||||
InsertDASInfo(das, das.DASInfo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
public static void SetDASInfo(IDASCommunication das, IInfoResult dasInfo, bool bSetInDb = true)
|
||||
{
|
||||
das.DASInfo = dasInfo;
|
||||
if (!bSetInDb || !DASFactoryDb.DbWrapper.Connected) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
if (das.RecordId < 0)
|
||||
{
|
||||
das.RecordId = DASFactoryDb.DbWrapper.GetDeviceId(das.SerialNumber);
|
||||
if (das.RecordId < 0)
|
||||
{
|
||||
var id = DASFactoryDb.DAS.DAS.InsertDASSimple(das.SerialNumber, das.FirmwareVersion,
|
||||
((ICommunication)das).Transport.ConnectString);
|
||||
das.RecordId = id;
|
||||
}
|
||||
}
|
||||
|
||||
Config.DASInfoClear(das.RecordId);
|
||||
InsertDASInfo(das, dasInfo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InsertDASInfo(IDASCommunication das, IInfoResult dasInfo)
|
||||
{
|
||||
if (!DbWrapper.Connected) { return; }
|
||||
if (null != dasInfo && das.RecordId > 0)
|
||||
{
|
||||
var batteryId = string.Empty;
|
||||
if (null != dasInfo.BatteryID)
|
||||
{
|
||||
batteryId = dasInfo.BatteryID.ID;
|
||||
}
|
||||
Config.DASInfoInsert(das.RecordId,
|
||||
dasInfo.MACAddress,
|
||||
das.RecordId,
|
||||
dasInfo.MaxNumberOfModules,
|
||||
dasInfo.MaxEventStorageSpaceInBytes,
|
||||
dasInfo.NumberOfBytesPerSampleClock,
|
||||
batteryId,
|
||||
dasInfo.CalibrationDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class NewDataData
|
||||
{
|
||||
public short[][][] datas { get; set; }
|
||||
public ulong[] SampleNumbers { get; set; }
|
||||
|
||||
public ulong[] TimeStamps { get; set; }
|
||||
|
||||
public ulong[] SequenceNumbers { get; set; }
|
||||
public NewDataData(short[][][] data, ulong[] sns, ulong[] timeStamps, ulong[] sequenceNumbers)
|
||||
{
|
||||
datas = data;
|
||||
SampleNumbers = sns;
|
||||
TimeStamps = timeStamps;
|
||||
SequenceNumbers = sequenceNumbers;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
|
||||
namespace DTS.Slice.Service
|
||||
{
|
||||
public class SystemAttribute : Attribute
|
||||
{
|
||||
// public enum TypeValues
|
||||
// {
|
||||
// SerialNumber = 0x00, SliceType, FlashTechnology, FlashSizeInBytes,
|
||||
// FlashSerialNumber, MaximumSampleRate, TemperatureScaleFactor,
|
||||
// TemperatureOffset, TotalEventsStored,
|
||||
// }
|
||||
|
||||
// public SystemAttribute()
|
||||
// : base()
|
||||
// {
|
||||
// _store = AttributeStore.System;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class SerialNumberAttribute : SystemAttribute
|
||||
//{
|
||||
// public string Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// string tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public SerialNumberAttribute()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "SerialNumberAttribute";
|
||||
// _typevalue = (byte)TypeValues.SerialNumber;
|
||||
// _datatype = AttributeTypes.AttributeDataTypes.Ascii;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public class TotalEventsStoredAttribute : SystemAttribute
|
||||
//{
|
||||
// public UInt16 Value
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// UInt16 tmp;
|
||||
// ByteConvertor.Convert(Data, 0, out tmp);
|
||||
// return tmp;
|
||||
// }
|
||||
// set { Data = ByteConvertor.ToByteArray(value); }
|
||||
// }
|
||||
|
||||
// public TotalEventsStoredAttribute()
|
||||
// : base()
|
||||
// {
|
||||
// _description = "TotalEventsStoredAttribute";
|
||||
// _typevalue = (byte)TypeValues.TotalEventsStored;
|
||||
// _datatype = AttributeTypes.AttributeDataTypes.UInt16;
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,894 @@
|
||||
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;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Communication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.StatusAndProgressBar;
|
||||
using DTS.Common.Utilities;
|
||||
using DTS.DASLib.Command.SLICE.DownloadCommands;
|
||||
using DTS.DASLib.Command.SLICEDB;
|
||||
using DTS.Common.Constant.DASSpecific;
|
||||
using DTS.Common.Enums.Hardware;
|
||||
using DisableFaultChecking = DTS.DASLib.Command.SLICE.DisableFaultChecking;
|
||||
using DTS.Common;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class PowerPro<T> : PowerPro_Base<T>, //IDASReconfigure,
|
||||
IDASCommunication,
|
||||
IConfigurationActions,
|
||||
IDiagnosticsActions,
|
||||
ITriggerCheckActions,
|
||||
IRealTimeActions,
|
||||
IArmActions,
|
||||
IDownloadActions
|
||||
where T : IConnection, new()
|
||||
{
|
||||
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();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("failed to configure", SerialNumber, ex);
|
||||
info.Error(ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
base.AsyncConfigure(configAsyncInfo);
|
||||
}
|
||||
public override string ConvertInputVoltage2BatteryCharging(double inputVoltage)
|
||||
{
|
||||
bool isCharging;
|
||||
var SwitchQuery = new QuerySwitchImmediate(this)
|
||||
{
|
||||
DeviceID = 0,
|
||||
Switch = (byte)Switches.PowerProSwitches.ChargePower
|
||||
};
|
||||
try
|
||||
{
|
||||
SwitchQuery.SyncExecute();
|
||||
if (1 == SwitchQuery.Setting)
|
||||
{
|
||||
isCharging = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isCharging = false;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
isCharging = false;
|
||||
}
|
||||
|
||||
// If we are charging
|
||||
if (isCharging)
|
||||
{
|
||||
return Resources.Charging;
|
||||
}
|
||||
// If we aren't charging and input is valid
|
||||
else if (inputVoltage > MinimumValidInputVoltage && inputVoltage < MaximumValidInputVoltage)
|
||||
{
|
||||
return Resources.NotCharging;
|
||||
}
|
||||
// If we're off input voltage and not charging
|
||||
else
|
||||
{
|
||||
return Resources.Discharging;
|
||||
}
|
||||
}
|
||||
public override bool? ChargingEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void IDASCommunication.SetIsStreamingSupported(bool supported)
|
||||
{
|
||||
IsStreamingSupported = false;
|
||||
}
|
||||
void IDASCommunication.ReadFirstUseDate()
|
||||
{
|
||||
IsFirstUseDateSupported = false;
|
||||
FirstUseDate = null;
|
||||
}
|
||||
/// <summary>
|
||||
/// indicates date of first use
|
||||
/// null indicates the hardware has not been used since calibration
|
||||
/// only valid when IsFirstUseDateSupported is true
|
||||
/// 15524 DAS "First Use Date"
|
||||
/// </summary>
|
||||
public DateTime? FirstUseDate { get; set; } = null;
|
||||
/// <summary>
|
||||
/// returns whether the hardware supports first use or not
|
||||
/// for hardware to support first use the hardware must support
|
||||
/// storage for user attributes in firmware and also have been
|
||||
/// calibrated by software support hardware first use
|
||||
/// 15524 DAS "First Use Date"
|
||||
/// </summary>
|
||||
public bool IsFirstUseDateSupported { get; set; } = false;
|
||||
/// <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 false;
|
||||
}
|
||||
public override bool IsBattery()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override bool IsTSRAIR()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public bool IsSlice6Air()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public override bool IsScheduleEventCountSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void IConfigurationActions.SetFirstUseDate(DateTime firstUseDate, ServiceCallback callback,
|
||||
object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Error("Not supported");
|
||||
}
|
||||
/// <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 PowerProAsyncInfo(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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
void IArmActions.ReArm(ServiceCallback callback, object userData, bool autoArm, bool arm, bool repeatEnable)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(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 PowerProAsyncInfo(callback, userData);
|
||||
try
|
||||
{
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel))
|
||||
{
|
||||
var mppadc = new MeasurePowerProAllDiagnosticChannel(this);
|
||||
mppadc.SyncExecute(); // Just Log it for now
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); }
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
info.Success(); //TEMP until PowerPro Event line is not shorted
|
||||
return;
|
||||
}
|
||||
|
||||
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="whichResult"></param>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
void IDiagnosticsActions.PrepareForDiagnostics(uint diagnosticsSampleRateHz,
|
||||
float diagnosticsAAFilterFrequencyHz,
|
||||
PrePostResults whichResult,
|
||||
ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
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 PowerProAsyncInfo(callback, userData);
|
||||
DiagnosticsHasBeenRun = true;
|
||||
BaseInput = new BaseInputValues();
|
||||
GetBaseInputs(true);
|
||||
ClearChannelDiagnosticsResults(false);
|
||||
info.Success();
|
||||
}
|
||||
public override double MaximumValidInputVoltage { get; set; } = 26D;
|
||||
public void PerformArmChecks(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.PerformArmChecks", new WaitCallback(AsyncPerformArmChecks), info);
|
||||
}
|
||||
|
||||
private void AsyncPerformArmChecks(object o)
|
||||
{
|
||||
var info = o as PowerProAsyncInfo;
|
||||
var dasResults = new ArmCheckResults();
|
||||
info.Progress(25);
|
||||
if (null != ArmCheckActions)
|
||||
{
|
||||
GetBaseInputs(true);
|
||||
if (ArmCheckActions.PerformInputVoltageCheck || ArmCheckActions.PerformBatteryVoltageCheck)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel))
|
||||
{
|
||||
var mppadc = new MeasurePowerProAllDiagnosticChannel(this);
|
||||
mppadc.SyncExecute(); // Just Log it for now
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); }
|
||||
}
|
||||
if (ArmCheckActions.PerformBatteryVoltageCheck)
|
||||
{
|
||||
//if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics))
|
||||
//{
|
||||
try
|
||||
{
|
||||
dasResults.BatteryVoltage = new double?[1];
|
||||
dasResults.BatteryVoltage[0] = BaseInput.BatteryMilliVolts / 1000D;
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to get Battery voltage", ex); }
|
||||
//}
|
||||
}
|
||||
info.Progress(33);
|
||||
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); }
|
||||
//}
|
||||
}
|
||||
info.Progress(66);
|
||||
if (ArmCheckActions.PerformSquibResistanceCheck)
|
||||
{
|
||||
// No Squibs in PowerPro
|
||||
}
|
||||
if (ArmCheckActions.PerformEventLineCheck)
|
||||
{
|
||||
((ITriggerCheckActions)this).DoTriggerCheckSync();
|
||||
}
|
||||
if (ArmCheckActions.PerformSensorIdCheck)
|
||||
{
|
||||
//not needed
|
||||
}
|
||||
if (ArmCheckActions.PerformTemperatureCheck)
|
||||
{
|
||||
//// Temperature
|
||||
//dasResults.TemperaturesPre = new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN };
|
||||
|
||||
//var measure = new MeasureS6DBDiagnosticChannel(this);
|
||||
|
||||
////External sensor 1
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_2_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[0] = measure.Measurement;
|
||||
|
||||
////External sensor 2
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_3_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[1] = measure.Measurement;
|
||||
|
||||
////External sensor 3
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_4_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[2] = measure.Measurement;
|
||||
|
||||
////External sensor 4
|
||||
//measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_5_Temperature;
|
||||
//measure.SyncExecute();
|
||||
//dasResults.TemperaturesPre[3] = measure.Measurement;
|
||||
}
|
||||
}
|
||||
info.Progress(100);
|
||||
dasResults.SensorIds = null;
|
||||
dasResults.TiltSensorDataPre = null;
|
||||
dasResults.SquibResistances = null;
|
||||
ArmCheckResults = dasResults;
|
||||
info.Success();
|
||||
}
|
||||
|
||||
public void CheckAlreadyLevelTriggered(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.CheckAlreadyLevelTriggered", AsyncCheckAlreadyLevelTriggered, info);
|
||||
}
|
||||
private void AsyncCheckAlreadyLevelTriggered(object asyncInfo)
|
||||
{
|
||||
var info = asyncInfo as PowerProAsyncInfo;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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
|
||||
PowerProAsyncInfo info = null;
|
||||
if (null != callback)
|
||||
{
|
||||
info = new PowerProAsyncInfo(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, CheckStartForShort = true, CheckTriggerForShort = 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
|
||||
IsStartShorted = 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.IsStartShorted = status.IsStartShorted || oldStatus.IsStartShorted;
|
||||
//}
|
||||
|
||||
status.IsTriggerShorted = status.IsTriggered;
|
||||
//status.IsStartShorted = status.IsArmed;
|
||||
status.IsStartShorted = status.IsStartShorted;
|
||||
SetDASArmStatus(status, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
InitializeHardwareLines.Log(ex, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
void ITriggerCheckActions.PostStartTriggerCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
private class EventDiagnosticsAsyncPacket
|
||||
{
|
||||
public PowerProAsyncInfo 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 PowerProAsyncInfo(callback, userData);
|
||||
packet.EventNumber = EventNumber;
|
||||
packet.WhichResult = WhichResult;
|
||||
|
||||
packet.Info.Success();
|
||||
}
|
||||
public void PerformVoltageCheckTAOnly(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.PerformVoltageCheckTAOnly", AsyncPerformVoltageCheckTAOnly, info);
|
||||
}
|
||||
private void AsyncPerformVoltageCheckTAOnly(object o)
|
||||
{
|
||||
var info = o as PowerProAsyncInfo;
|
||||
info?.Success();
|
||||
}
|
||||
private const double SDB_ERR_VOLTAGE_REPORTING = 100000.0D;
|
||||
/// <summary>
|
||||
/// Retrieve the current arm status from the DAS
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
//void IArmActions.GetArmStatus(ServiceCallback callback, object userData, uint inputVoltageCutoff)
|
||||
//{
|
||||
// var info = new PowerProAsyncInfo(callback, userData);
|
||||
// var status = new ArmStatus { IsArmed = false };
|
||||
// try
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel))
|
||||
// {
|
||||
// var mppadc = new MeasurePowerProAllDiagnosticChannel(this);
|
||||
// mppadc.SyncExecute(); // Just Log it for now
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); }
|
||||
// if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics))
|
||||
// {
|
||||
// var batteryVoltage = 0.0;
|
||||
// try
|
||||
// {
|
||||
|
||||
// var query = new QueryBatteryVoltageMV(this, 3000);
|
||||
// query.SyncExecute();
|
||||
// var d = (double)query.BatteryVoltageMV;
|
||||
// if (d > SDB_ERR_VOLTAGE_REPORTING)
|
||||
// {
|
||||
// d /= 1000.0D;
|
||||
// }
|
||||
|
||||
// status.BatteryMilliVolts = d;
|
||||
|
||||
// batteryVoltage = Math.Round(d / 1000, 1);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// APILogger.Log("Failed to get battery mv", ex);
|
||||
// }
|
||||
|
||||
// try
|
||||
// {
|
||||
// var query = new QueryV1VoltageMV(this, 3000);
|
||||
// query.SyncExecute();
|
||||
// var d = (double)query.V1VoltageMV;
|
||||
// if (d > SDB_ERR_VOLTAGE_REPORTING)
|
||||
// {
|
||||
// d /= 1000.0D;
|
||||
// }
|
||||
|
||||
// status.InputMilliVolts = d;
|
||||
|
||||
// var inputVoltage = Math.Round(d / 1000, 1);
|
||||
|
||||
// if (batteryVoltage < MinimumValidBatteryVoltage || batteryVoltage > MaximumValidBatteryVoltage)
|
||||
// {
|
||||
// batteryVoltage = 0.0;
|
||||
// }
|
||||
|
||||
// BaseInput = new BaseInputValues();
|
||||
// var batteryVoltageStatusColor = DFConstantsAndEnums.VoltageStatusColor.Off;
|
||||
// batteryVoltageStatusColor = BaseInput.ChargeCapacityValid
|
||||
// ? ConvertBatteryCapacity2Color(batteryVoltage, BaseInput.ChargeCapacity)
|
||||
// : ConvertBatteryVoltage2Color(batteryVoltage);
|
||||
// var batteryChargingStatus = string.Empty;
|
||||
// if (batteryVoltage >= MinimumValidBatteryVoltage)
|
||||
// {
|
||||
// batteryChargingStatus = ConvertInputVoltage2BatteryCharging(inputVoltage);
|
||||
// }
|
||||
|
||||
// var statusDisplayBattery =
|
||||
// batteryVoltage < MinimumValidBatteryVoltage || batteryVoltage > MaximumValidBatteryVoltage
|
||||
// ? "---"
|
||||
// : batteryVoltage.ToString(System.Globalization.CultureInfo.InvariantCulture) + " V " +
|
||||
// batteryChargingStatus;
|
||||
// var inputVoltageStatusColor = ConvertInputVoltage2Color(inputVoltage);
|
||||
// BaseInput.InputVoltageStatusColor = inputVoltageStatusColor;
|
||||
// BaseInput.StatusDisplayInput =
|
||||
// inputVoltage < MinimumValidInputVoltage || inputVoltage > MaximumValidInputVoltage
|
||||
// ? "---"
|
||||
// : inputVoltage.ToString(System.Globalization.CultureInfo.InvariantCulture) + " V";
|
||||
// BaseInput.BatteryVoltageStatusColor = batteryVoltageStatusColor;
|
||||
// BaseInput.StatusDisplayBattery = statusDisplayBattery;
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// APILogger.Log("Failed to get input mv", ex);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// SetDASArmStatus(status, true);
|
||||
// }
|
||||
// info.Success();
|
||||
//}
|
||||
void IConfigurationActions.CheckSafetyState(bool bArmed, ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new PowerProAsyncInfo(callback, userData);
|
||||
info.Success();
|
||||
}
|
||||
|
||||
|
||||
//}
|
||||
/// <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 PowerProAsyncInfo
|
||||
{
|
||||
public ServiceCallback Callback { get; set; }
|
||||
public object UserData { get; set; }
|
||||
public object FunctionData { get; set; }
|
||||
|
||||
public PowerProAsyncInfo(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", "PowerPRO 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", "PowerPRO 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", "PowerPRO 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", "PowerPRO ERROR", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class PowerPro_Base<T> : SLICE2_Base<T> where T : IConnection, new()
|
||||
{
|
||||
protected override bool AdjustInputRange(AnalogInputDASChannel analog)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns true if device supports trigger inversion, false otherwise
|
||||
/// <inheritdoc cref="IDASCommunication"/>
|
||||
/// </summary>
|
||||
/// <returns>true if device supports trigger inversion, false otherwise</returns>
|
||||
public override bool SupportsTriggerInversion() => HardwareConstants.SupportsTriggerInversion(GetHardwareType(), ProtocolVersion);
|
||||
/// <summary>
|
||||
/// returns true if device supports start inversion, false otherwise
|
||||
/// <inheritdoc cref="IDASCommunication"/>
|
||||
/// </summary>
|
||||
/// <returns>true if device supports start inversion, false otherwise</returns>
|
||||
public override bool SupportsStartInversion() => HardwareConstants.SupportsStartInversion(GetHardwareType(), ProtocolVersion);
|
||||
|
||||
|
||||
public override bool CheckAAF(float rate) { return true; }
|
||||
public override bool SupportsTimeSynchronization
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override double[] GetNominalRanges(SensorConstants.BridgeType bridgeType)
|
||||
{
|
||||
switch (bridgeType)
|
||||
{
|
||||
case SensorConstants.BridgeType.IEPE:
|
||||
return WinUSBSlice.StaticDASIEPEInfo.NominalRanges;
|
||||
default:
|
||||
return WinUSBSlice.StaticDASBridgeInfo.NominalRanges;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> PowerPro_MinimumProtocols =
|
||||
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 6.0 DB Protocol Limitations
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryMSP430Firmware] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleEvents] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArm] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDefaultMIF] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackSensors] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.TestCommunication] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackLowPowerMode] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetRealtimeSampleRate] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.LevelTrigger] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AttributeStoreBlocks] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MaxEvents] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmDiagnosticDelay] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackChannelAutoArmDiagLevel] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleSamplesRealtime] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
|
||||
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.DiangosShuntDAC] = PowerPRO.DIAGNOS_SHUNT_DAC;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageInsertion] = PowerPRO.DIAGNOS_SHUNT_DAC;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryEthernetMacTable] = PowerPRO.MIN_PROTOCOL_QUERYMACTABLE;
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel] = PowerPRO.MIN_PROTOCOL_MEASUREPOWERPROALLDIAGNOSTICCHANNEL;
|
||||
|
||||
PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics] = PowerPRO.MIN_PROTOCOL_VER;
|
||||
|
||||
MinimumProtocols = PowerPro_MinimumProtocols;
|
||||
}
|
||||
protected override Slice<T>.ConfigAttributes GetConfigAttributes(ICommunication com)
|
||||
{
|
||||
return new SLICE6ConfigAttributes(com);
|
||||
}
|
||||
/// <summary>
|
||||
/// SLICE6 config attributes, mostly inherits from SLICE.ConfigAttributes with some functionality removed
|
||||
/// </summary>
|
||||
protected class SLICE6ConfigAttributes : Slice<T>.ConfigAttributes
|
||||
{
|
||||
public SLICE6ConfigAttributes(ICommunication _com)
|
||||
: base(_com)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// QueryEventData also is customized for SLICE6, it needs to perform SLICE6 specific data marshalling
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override QueryEventDataBase GetQueryEventData()
|
||||
{
|
||||
return new QueryEventData_SLICE6(this, QueryEventData_SLICE6.Default_IO_Timeout);
|
||||
}
|
||||
/// <summary>
|
||||
/// we can probably simplify and take common items (slice6+slice1) out of this function, but for now
|
||||
/// it's mostly a copy of SLICE1.AsyncConfigure
|
||||
/// </summary>
|
||||
/// <param name="configAsyncInfo"></param>
|
||||
protected override void AsyncConfigure(object configAsyncInfo)
|
||||
{
|
||||
var info = (SliceConfigServiceAsyncInfo)configAsyncInfo;
|
||||
|
||||
ConfigureHasBeenRun = true;
|
||||
if (info.DiscardDiagnostics) { DiagnosticsHasBeenRun = false; }
|
||||
info.Progress(100);
|
||||
info.Success();
|
||||
}
|
||||
|
||||
#region Voltage Check
|
||||
public void PerformVoltageCheck(ServiceCallback callback, object userData)
|
||||
{
|
||||
var info = new SliceServiceAsyncInfo(callback, userData);
|
||||
LaunchAsyncWorker("PowerPro.PerformVoltageCheck", AsyncPerformVoltageCheck, info);
|
||||
}
|
||||
|
||||
private void AsyncPerformVoltageCheck(object o)
|
||||
{
|
||||
var info = o as SliceServiceAsyncInfo;
|
||||
try
|
||||
{
|
||||
GetBaseInputs(true);
|
||||
info?.Success();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
info?.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// hardcoded constants right now ... maybe these belong in attributes in the firmware!
|
||||
/// </summary>
|
||||
protected override uint MaxAAFilterRateHz { get { return PowerPRO.MaxAAFilterRateHz; } }
|
||||
protected override uint MaxSampleRateHz { get { return 400000; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="DTS.Slice.Service.Attribute" Collapsed="true">
|
||||
<Position X="1.75" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AIAAAAAIAAAAAAAAIAAEAIAAAAAAACAAAAAAIQAAAAA=</HashCode>
|
||||
<FileName>Attribute.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.Slice.Service.EventAttribute" Collapsed="true">
|
||||
<Position X="2.75" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>EventAttribute.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.Slice.Service.SystemAttribute" Collapsed="true">
|
||||
<Position X="0.5" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>SystemAttribute.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
@@ -0,0 +1,226 @@
|
||||
using DTS.Common.Constant.DASSpecific;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
#pragma warning disable S101 // Types should be named in PascalCase
|
||||
public class SLICE6AIRTC<T> : SLICE6_Base<T>, IAlignUDPToPPSAware where T : IConnection, new()
|
||||
#pragma warning restore S101 // Types should be named in PascalCase
|
||||
{
|
||||
public bool AlignUDPToPPS { get; set; }
|
||||
public override bool SupportsRemoveLeapSeconds => true;
|
||||
public override bool SupportsADCSamplesPerPacket => true;
|
||||
protected override bool RequiresNon0QualificationSamples => true;
|
||||
protected override byte[] GetRTChannelIndices(RealTimeAsyncPacket packet)
|
||||
{
|
||||
return new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
|
||||
}
|
||||
public override void SetIsStreamingSupported(bool supported = false)
|
||||
{
|
||||
IsStreamingSupported = true;
|
||||
}
|
||||
///// <summary>
|
||||
///// the order of this DAS among multiple das
|
||||
///// </summary>
|
||||
//public int DASIndex { get; set; } = -1;
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 6.0 Protocol Limitations
|
||||
SLICE6AIR_TC_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ADCSamplesPerPacket] = SLICE6AIRTC.ADC_SAMPLES_PER_PACKET_VER;
|
||||
MinimumProtocols = SLICE6AIR_TC_MinimumProtocols;
|
||||
}
|
||||
|
||||
#region protocol settings/overrides
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> SLICE6AIR_TC_MinimumProtocols =
|
||||
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
protected override int MIN_PROTOCOL_TMATS_INTERVAL => SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
private uint maxSampleRateHz = 0;
|
||||
protected override uint MaxSampleRateHz
|
||||
{
|
||||
get
|
||||
{
|
||||
if (0 == maxSampleRateHz)
|
||||
{
|
||||
try
|
||||
{
|
||||
var qsa = new QuerySystemAttributeSLICE6(this)
|
||||
{
|
||||
Key = AttributeTypes.SystemAttributesSLICE6.MaximumSampleRate
|
||||
};
|
||||
qsa.SyncExecute();
|
||||
maxSampleRateHz = (uint)qsa.Value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Error getting S6A-BR max sample rate, returning 50K");
|
||||
APILogger.LogException(ex);
|
||||
return 50000;
|
||||
}
|
||||
}
|
||||
return maxSampleRateHz;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected override DASModule MakeConfigModuleFromInfoModule(InfoResult.Module infoModule)
|
||||
{
|
||||
//per LP: can stream, no IEPE
|
||||
var configModule = new DASModule(infoModule.ModuleArrayIndex, this);
|
||||
configModule.Channels = new DASChannel[infoModule.NumberOfChannels];
|
||||
|
||||
for (var i = 0; i < infoModule.NumberOfChannels; i++)
|
||||
{
|
||||
if (DFConstantsAndEnums.ModuleType.StreamOut == configModule.ModuleType())
|
||||
{
|
||||
var streamOutChannel = new StreamOutputDASChannel(configModule, i);
|
||||
configModule.Channels[i] = streamOutChannel;
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = new AnalogInputDASChannel(configModule, i);
|
||||
|
||||
channel.SupportedBridges = new SensorConstants.BridgeType[]
|
||||
{
|
||||
SensorConstants.BridgeType.FullBridge,
|
||||
SensorConstants.BridgeType.HalfBridge,
|
||||
};
|
||||
configModule.Channels[i] = channel;
|
||||
}
|
||||
}
|
||||
|
||||
return configModule;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// we can probably simplify and take common items (slice6+slice1) out of this function, but for now
|
||||
/// it's mostly a copy of SLICE1.AsyncConfigure
|
||||
/// </summary>
|
||||
/// <param name="configAsyncInfo"></param>
|
||||
protected override void AsyncConfigure(object configAsyncInfo)
|
||||
{
|
||||
var info = configAsyncInfo as SliceConfigServiceAsyncInfo;
|
||||
SetUDPAlignOnPPS();
|
||||
SetRemoveSeconds();
|
||||
SetADCSamplesPerPacket(info.StreamADCPerPacket[this]);
|
||||
|
||||
//12638 DAS does not record data in recorder mode during calibration ~ 40% of time.
|
||||
//for SLICE6 we call reseteventlist here, prior to configuring and NOT before arming
|
||||
ResetEventListPriorToConfigure();
|
||||
|
||||
int progressValue = 0;
|
||||
bool bReleased = true;
|
||||
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.ProgramStackChannels))
|
||||
{
|
||||
ReconfigureAccordingToConfig();
|
||||
}
|
||||
|
||||
PresetSampleRate();
|
||||
|
||||
SetVoltageRequirements();
|
||||
|
||||
SetPolarity();
|
||||
|
||||
SetArmDisableShortCheck();
|
||||
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
bReleased = false;
|
||||
// loop thru the modules (slices) and configure the non-UART channels
|
||||
var numChannels = DASInfo.Modules.Sum(mod => mod.NumberOfChannels);
|
||||
var numStreamingChannels = DASInfo.Modules.Sum(mod => DFConstantsAndEnums.ModuleType.StreamOut == mod.TypeOfModule ? mod.NumberOfChannels : 0);
|
||||
var rangeArray = new float[numChannels];
|
||||
//var IsHalfBridgeArray = new bool[numChannels];
|
||||
var bridgeModeArray = new byte[numChannels];
|
||||
var BridgeResistanceArray = new ushort[numChannels];
|
||||
var IsACCoupledArray = new bool[numChannels];
|
||||
//18294 Implement Bridge AC / DC coupling(fw update dependent)
|
||||
var bridgeACCouplingArray = new bool[numChannels];
|
||||
// level trigger values
|
||||
var enableLowerLevelTriggerThreshold = new bool[numChannels];
|
||||
var enableUpperLevelTriggerThreshold = new bool[numChannels];
|
||||
var lowerLevelTriggerThreshold = new float[numChannels];
|
||||
var upperLevelTriggerThreshold = new float[numChannels];
|
||||
var qualificationSamples = new int[numChannels];
|
||||
|
||||
var diagnosticChannels = new List<byte>();
|
||||
|
||||
var bModified = false;
|
||||
CommonConfigureWork(diagnosticChannels, qualificationSamples, ref bReleased,
|
||||
info, bridgeModeArray, IsACCoupledArray, BridgeResistanceArray,
|
||||
ref bModified, rangeArray, enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold,
|
||||
enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold, bridgeACCouplingArray);
|
||||
if (bReleased) { return; }
|
||||
// report progress
|
||||
progressValue = 5;
|
||||
info.Progress(progressValue);
|
||||
|
||||
StoreConfigAttributes(info, rangeArray, ref bReleased, ref progressValue, bridgeModeArray,
|
||||
IsACCoupledArray, BridgeResistanceArray, enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold,
|
||||
enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold, qualificationSamples, numChannels,
|
||||
out var config, bridgeACCouplingArray, 0, numStreamingChannels);
|
||||
|
||||
progressValue = 20;
|
||||
info.Progress(progressValue);
|
||||
|
||||
RemainingConfigWork(ref progressValue, info, diagnosticChannels, config, ref bReleased, null, null, null);
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Cancel();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Error(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
info.Progress(100);
|
||||
info.Success();
|
||||
}
|
||||
/// <summary>
|
||||
/// returns true if the device is known to be streaming
|
||||
/// does not query device, just returns a flag if it has been set
|
||||
/// </summary>
|
||||
public override bool GetIsStreaming()
|
||||
{
|
||||
if (null == DASArmStatus) { return false; }
|
||||
//18852 Cannot use Stop streaming / (Dis)Auto Arm button if one or more DAS is idle
|
||||
//can't rely on just having received invalid mode, QATS will still have a status of realtime
|
||||
//when streaming, so we'll use either for now.
|
||||
return DASArmStatus.ReceivedInvalidModeDuringSetup || DASArmStatus.IsInRealtime;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class Status
|
||||
{
|
||||
public HardwareDiscoveryParameters HardwareDiscoveryParams = new HardwareDiscoveryParameters();
|
||||
public HardwareDiscoveryStatusInfo HardwareDiscoveryStatusInfo = new HardwareDiscoveryStatusInfo();
|
||||
public GlobalStatusInformation GlobalStatusInformation = new GlobalStatusInformation();
|
||||
public GlobalStatusParameters GlobalStatusParameters = new GlobalStatusParameters();
|
||||
public ConfigureStatusInformation ConfigureStatus = new ConfigureStatusInformation();
|
||||
public ConfigureStatusParameters ConfigureParameters = new ConfigureStatusParameters();
|
||||
public RealtimeStatusInformation RealtimeStatus = new RealtimeStatusInformation();
|
||||
public RealtimeParameters RealtimeParams = new RealtimeParameters();
|
||||
public DiagnoseParameters DiagnoseParams = new DiagnoseParameters();
|
||||
public DownloadParameters DownloadParams = new DownloadParameters();
|
||||
public DownloadStatusInformation DownloadStatusInfo = new DownloadStatusInformation();
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
GlobalStatusParameters.Reset();
|
||||
GlobalStatusInformation.Reset();
|
||||
HardwareDiscoveryParams.Reset();
|
||||
HardwareDiscoveryStatusInfo.Reset();
|
||||
ConfigureStatus.Reset();
|
||||
ConfigureParameters.Reset();
|
||||
RealtimeStatus.Reset();
|
||||
RealtimeParams.Reset();
|
||||
DiagnoseParams.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,158 @@
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service.Classes.Diagnostics
|
||||
{
|
||||
public static class DiagnosticsResultActions
|
||||
{
|
||||
/// <summary>
|
||||
/// clears all diagnostics from all events and channels, and optionally clears from db
|
||||
/// </summary>
|
||||
/// <param name="unit"></param>
|
||||
/// <param name="bClearDb"></param>
|
||||
public static void ClearChannelDiagnosticsResults(IDASCommunication unit, bool bClearDb = true)
|
||||
{
|
||||
unit.ChannelDiagnosticsResults = new IDiagnosticResult[0];
|
||||
unit.ChannelDiagnostics = new IDiagnosticActions[0];
|
||||
|
||||
if (!DASFactoryDb.DbWrapper.Connected || !bClearDb) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
DASFactoryDb.Diagnostics.Diagnostics.ClearExistingDiagnosticsAllChannels(unit.RecordId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// sets the channel diagnostics, optionally writes to the db
|
||||
/// </summary>
|
||||
/// <param name="unit"></param>
|
||||
/// <param name="results"></param>
|
||||
/// <param name="setInDb"></param>
|
||||
public static void SetChannelDiagnosticsResults(IDASCommunication unit, IDiagnosticResult[] results, bool setInDb)
|
||||
{
|
||||
unit.ChannelDiagnosticsResults = results;
|
||||
if (!DASFactoryDb.DbWrapper.Connected || !setInDb) { return; }
|
||||
try
|
||||
{
|
||||
foreach (var result in results)
|
||||
{
|
||||
var moduleNumber = unit.DASInfo.MapDASChannelNumber2ModuleArrayIndex(result.DASChannelNumber);
|
||||
var channelIndex = unit.DASInfo.MapDASChannelNumber2ModuleChannelNumber(result.DASChannelNumber);
|
||||
var channel = unit.ConfigData.Modules[moduleNumber].Channels[channelIndex];
|
||||
if (channel is AnalogInputDASChannel aic)
|
||||
{
|
||||
if (aic.DigitalInputChannel)
|
||||
{
|
||||
InsertDiagnosticsResultDigital(unit, aic, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertDiagnosticsResultAnalog(unit, aic, result);
|
||||
}
|
||||
}
|
||||
else if (channel is OutputSquibChannel squib)
|
||||
{
|
||||
InsertDiagnosticsResultsSquib(unit, squib, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a single digital result to the db
|
||||
/// </summary>
|
||||
/// <param name="das"></param>
|
||||
/// <param name="aic"></param>
|
||||
/// <param name="result"></param>
|
||||
private static void InsertDiagnosticsResultDigital(IDASCommunication das, AnalogInputDASChannel aic,
|
||||
IDiagnosticResult result)
|
||||
{
|
||||
try
|
||||
{
|
||||
DASFactoryDb.Diagnostics.Diagnostics.InsertDigitalDiagnosticResult(das.RecordId,
|
||||
result.DASChannelNumber,
|
||||
result.EventNumber,
|
||||
result.DigitalInputActiveState);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a single analog result to the db
|
||||
/// </summary>
|
||||
/// <param name="das"></param>
|
||||
/// <param name="aic"></param>
|
||||
/// <param name="result"></param>
|
||||
private static void InsertDiagnosticsResultAnalog(IDASCommunication das, AnalogInputDASChannel aic,
|
||||
IDiagnosticResult result)
|
||||
{
|
||||
try
|
||||
{
|
||||
DASFactoryDb.Diagnostics.Diagnostics.InsertAnalogDiagnosticResult(
|
||||
das.RecordId,
|
||||
result.DASChannelNumber,
|
||||
result.EventNumber,
|
||||
result.ScalefactorMilliVoltsPerADC,
|
||||
result.ExpectedExcitationMilliVolts,
|
||||
result.MeasuredExcitationMilliVolts,
|
||||
result.NegativeExcitation,
|
||||
result.MeasuredOffsetMilliVolts,
|
||||
result.MeasuredInternalOffsetMilliVolts,
|
||||
result.AutoZeroPercentDeviation,
|
||||
result.FinalOffsetADC,
|
||||
result.RemovedOffsetADC,
|
||||
result.RemovedInternalOffsetADC,
|
||||
result.NoisePercentFullScale,
|
||||
result.ShuntDeflectionFailed,
|
||||
result.CalSignalCheckFailed,
|
||||
result.MeasuredShuntDeflectionMv,
|
||||
result.MeasuredCalSignalMv,
|
||||
result.TargetCalSignalMv,
|
||||
result.TargetGain,
|
||||
result.MeasuredGain,
|
||||
result.QueriedGain,
|
||||
result.TargetShuntDeflectionMv,
|
||||
result.BridgeResistance,
|
||||
result.ZeroMVInADC,
|
||||
result.WindowAverageADC);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a single squib diagnostic to the db
|
||||
/// </summary>
|
||||
/// <param name="das"></param>
|
||||
/// <param name="squib"></param>
|
||||
/// <param name="result"></param>
|
||||
private static void InsertDiagnosticsResultsSquib(IDASCommunication das, OutputSquibChannel squib,
|
||||
IDiagnosticResult result)
|
||||
{
|
||||
try
|
||||
{
|
||||
DASFactoryDb.Diagnostics.Diagnostics.InsertSquibDiagnosticResult(das.RecordId,
|
||||
result.DASChannelNumber, result.EventNumber, result.SquibFireCurrentData,
|
||||
result.SquibFireVoltageData, result.SquibFireTimeAxis, result.MeasuredDurationMS,
|
||||
result.MeasuredDelayMS, result.SquibFirePassed, result.SquibDurationPassed, result.SquibDelayPassed,
|
||||
result.SquibThreshold, result.SquibVoltageScaler, result.SquibCurrentScaler);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//for now just skip the logging
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Base class for output channels.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class OutputDASChannel : DASChannel
|
||||
{
|
||||
public OutputDASChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
}
|
||||
|
||||
public OutputDASChannel()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using System.Xml;
|
||||
using System.IO.Ports;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for storing/applying CAN settings as a channel
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class CANInputDASChannel : InputDASChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// CTOR to populate a channel's owning module and channel WRT that module. Calls
|
||||
/// base class CTOR.
|
||||
/// </summary>
|
||||
/// <param name="owner">Module that contains this channel.</param>
|
||||
/// <param name="channelNumber">ChannelNumber of this channel WRT owning module.</param>
|
||||
public CANInputDASChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
SerialNumber = owner.SerialNumber();
|
||||
}
|
||||
|
||||
public CANInputDASChannel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Serial number of the sensor.
|
||||
/// </summary>
|
||||
public string SerialNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the hardware channel
|
||||
/// </summary>
|
||||
public string HardwareChannelName { get; set; }
|
||||
|
||||
public bool IsFD { get; set; }
|
||||
public int ArbBaseBitrate { get; set; }
|
||||
public int ArbBaseSJW { get; set; }
|
||||
public int DataBitrate { get; set; }
|
||||
public int DataSJW { get; set; }
|
||||
public string FileType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the channel has a serial number in the SerialNumber field, it is "Configured".
|
||||
/// </summary>
|
||||
public override bool IsConfigured()
|
||||
{
|
||||
return !string.IsNullOrEmpty(SerialNumber);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"CAN{ModuleChannelNumber}";
|
||||
}
|
||||
public override void WriteXml(XmlWriter writer)
|
||||
{
|
||||
base.WriteXml(writer);
|
||||
|
||||
// SerialNumber
|
||||
XMLHelper.PutString(writer, "SerialNumber", SerialNumber);
|
||||
XMLHelper.PutString(writer, "HardwareChannelName", HardwareChannelName);
|
||||
XMLHelper.PutString(writer, "IsFD", IsFD.ToString());
|
||||
XMLHelper.PutString(writer, "ArbBaseBitrate", ArbBaseBitrate.ToString());
|
||||
XMLHelper.PutString(writer, "ArbBaseSJW", ArbBaseSJW.ToString());
|
||||
XMLHelper.PutString(writer, "DataBitrate", DataBitrate.ToString());
|
||||
XMLHelper.PutString(writer, "DataSJW", DataSJW.ToString());
|
||||
XMLHelper.PutString(writer, "FileType", FileType);
|
||||
}
|
||||
private const string SERIALNUMBER_TAG = "SerialNumber";
|
||||
private const string HARDWARECHANNELNAME_TAG = "HardwareChannelName";
|
||||
private const string ISFD_TAG = "IsFD";
|
||||
private const string ARBBASEBITRATE_TAG = "ArbBaseBitrate";
|
||||
private const string ARBBASESJW_TAG = "ArbBaseSJW";
|
||||
private const string DATABITRATE_TAG = "DataBitrate";
|
||||
private const string DATASJW_TAG = "DataSJW";
|
||||
private const string FILETYPE_TAG = "FileType";
|
||||
protected override void HandleElement(XmlReader reader)
|
||||
{
|
||||
base.HandleElement(reader);
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case SERIALNUMBER_TAG:
|
||||
SerialNumber = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case HARDWARECHANNELNAME_TAG:
|
||||
HardwareChannelName = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case ISFD_TAG:
|
||||
IsFD = Convert.ToBoolean(XMLHelper.GetString(reader));
|
||||
break;
|
||||
case ARBBASEBITRATE_TAG:
|
||||
ArbBaseBitrate = Convert.ToInt32(XMLHelper.GetString(reader));
|
||||
break;
|
||||
case ARBBASESJW_TAG:
|
||||
ArbBaseSJW = Convert.ToInt32(XMLHelper.GetString(reader));
|
||||
break;
|
||||
case DATABITRATE_TAG:
|
||||
DataBitrate = Convert.ToInt32(XMLHelper.GetString(reader));
|
||||
break;
|
||||
case DATASJW_TAG:
|
||||
DataSJW = Convert.ToInt32(XMLHelper.GetString(reader));
|
||||
break;
|
||||
case FILETYPE_TAG:
|
||||
FileType = XMLHelper.GetString(reader);
|
||||
break;
|
||||
default:
|
||||
// let child handle it
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.StatusAndProgressBar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums;
|
||||
using System.IO.Ports;
|
||||
using DTS.Common.Classes.DSP;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public interface IConfigurationActions
|
||||
{
|
||||
/// <summary>
|
||||
/// for DAS that support setting channel types and auto detecting attached sensor types
|
||||
/// this sets the channels back into auto detect configuration and out of a forced
|
||||
/// configuration.
|
||||
/// an example of this is SLICE 2 which supports forced IEPE and forced bridge (and autodect)
|
||||
/// this sets the bridge type and queries each channel for channel type and stores the result in ConfigData channels
|
||||
/// [(c as AnalogInputDASChannel).IEPEChannel]
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
/// <param name="userData"></param>
|
||||
void AutoDetect(bool bQueryConfiguration, ServiceCallback callback, object userData);
|
||||
/// <summary>
|
||||
/// Verify that the ConfigData property is correctly constructed
|
||||
/// </summary>
|
||||
/// <param name="DoStrictCheck">Set to true if your're arming</param>
|
||||
void VerifyConfig(bool DoStrictCheck);
|
||||
void VerifyConfig(bool DoStrictCheck, ErrorCallback FailedChallengeFunc);
|
||||
|
||||
/// <summary>
|
||||
/// sets the user attributes for first use date to the given date
|
||||
/// to unset the date the firstUseDate should be set to MsqlDateTime.MinValue
|
||||
/// </summary>
|
||||
/// <param name="firstUseDate"></param>
|
||||
/// <param name="callback"></param>
|
||||
/// <param name="userData"></param>
|
||||
void SetFirstUseDate(DateTime firstUseDate, ServiceCallback callback, object userData);
|
||||
/// <summary>
|
||||
/// resets trigger/start line attributes in SLICE,
|
||||
/// calls ArmOff for TDAS
|
||||
/// </summary>
|
||||
void StoreTestSetupXML(ServiceCallback callback, object userData, string testSetupXML);
|
||||
void ResetHardwareLines(ServiceCallback callback, object userData);
|
||||
void CheckAAFilterRate(ServiceCallback callback, object userData);
|
||||
|
||||
void QueryTestSetup(ServiceCallback callback,
|
||||
object userData);
|
||||
/// <summary>
|
||||
/// Apply the data in the ConfigData property to the DAS
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
/// <param name="MaxAAF">array of double for Max AAF, 0 is TDAS, 1 is G5, not needed for slice, so not used</param>
|
||||
/// <param name="tmatsIntervals">lookup with interval between sending TMATS while streaming
|
||||
/// key is unit and value is time in ms</param>
|
||||
void Configure(ServiceCallback callback,
|
||||
object userData,
|
||||
bool bEventConfig,
|
||||
bool DummyConfig,
|
||||
double[] MaxAAF,
|
||||
bool configureDigitalOutputs,
|
||||
uint crc,
|
||||
bool turnOffAAFRealtime,
|
||||
IStreamingFilterProfile dspFilterType,
|
||||
bool discardDiagnostics, Dictionary<IDASCommunication, ushort> timeChannelIds, Dictionary<IDASCommunication, ushort> dataChannelIds,
|
||||
Dictionary<IDASCommunication, UDPStreamProfile> streamProfiles, Dictionary<IDASCommunication, int> streamADCPerPacket, Dictionary<IDASCommunication, ushort> irigTDPIntervals,
|
||||
Dictionary<IDASCommunication, string> addresses, Dictionary<IDASCommunication, uint[]> tmnsConfigs,
|
||||
Dictionary<IDASCommunication, uint> baudRates, Dictionary<IDASCommunication, uint> dataBits, Dictionary<IDASCommunication, StopBits> stopBits,
|
||||
Dictionary<IDASCommunication, Parity> parities, Dictionary<IDASCommunication, Handshake> flowControls, Dictionary<IDASCommunication, UartDataFormat> dataFormats,
|
||||
Dictionary<IDASCommunication, ushort> tmatsIntervals
|
||||
);
|
||||
/// <summary>
|
||||
/// Apply level triggers only [no other configuration actions]
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
/// <param name="userData"></param>
|
||||
void ApplyLevelTriggers(ServiceCallback callback, object userData);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve configuration from DAS 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>
|
||||
void QueryConfiguration(ServiceCallback callback, object userData, uint crc, string strConfig, bool bReadIds, bool bDeviceScaleFactors = true, bool sourceDASStorageList = false);
|
||||
|
||||
/// <summary>
|
||||
/// updates the configuration on the units using a file as input data
|
||||
/// 17872 Use DASConfig XMLs on disk when performing an emergency download with DAS that have blank filestore(s)
|
||||
/// </summary>
|
||||
void UpdateConfigurationFromFile(ServiceCallback callback, object userData, string filePath);
|
||||
/// <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>
|
||||
void UpdateIDs(ServiceCallback callback, object userData);
|
||||
|
||||
void UpdateId(ServiceCallback callback, object userData, DASModule module, DASChannel channel);
|
||||
|
||||
void CheckSafetyState(bool bArmed, ServiceCallback callback, object userData);
|
||||
|
||||
/// <summary>
|
||||
/// Reboot a device
|
||||
/// FB15335: Move UART and ClockProfile sets to RunTest -> Hardware NavStep, add Reboot
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
void Reboot(ServiceCallback callback, object userData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
using DTS.Common.Constant.DASSpecific;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class SLICE6AIRBR<T> : SLICE6_Base<T>, IAlignUDPToPPSAware where T : IConnection, new()
|
||||
{
|
||||
public bool AlignUDPToPPS { get; set; }
|
||||
public override bool SupportsRemoveLeapSeconds => true;
|
||||
public override bool SupportsADCSamplesPerPacket => true;
|
||||
protected override bool RequiresNon0QualificationSamples => true;
|
||||
protected override byte[] GetRTChannelIndices(RealTimeAsyncPacket packet)
|
||||
{
|
||||
return new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
|
||||
}
|
||||
public override void SetIsStreamingSupported(bool supported)
|
||||
{
|
||||
IsStreamingSupported = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// the order of this DAS among multiple das
|
||||
/// </summary>
|
||||
public int DASIndex { get; set; } = -1;
|
||||
|
||||
public override void InitMinProto()
|
||||
{
|
||||
// SLICE 6.0 Protocol Limitations
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArm] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmRepeatEnable] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDefaultMIF] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackSensors] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.TestCommunication] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackLowPowerMode] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetRealtimeSampleRate] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.LevelTrigger] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AttributeStoreBlocks] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MaxEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmDiagnosticDelay] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackChannelAutoArmDiagLevel] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FlashClear] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleSamplesRealtime] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.DiangosShuntDAC] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageInsertion] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPTimestamp] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRecDelayInSecond] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryTiltSensorData] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InSliceTiltSensorADCPre] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StartRealtimeStream] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.UDPRealtimeStream] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.GenerateEvent] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPSyncStatus] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetClockSyncConfig] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDSPFilterSettings] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.PTPDomainID] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ActiveRAM] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.RecordAndStreamSubSample] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.RemoveLeapSeconds] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.RecordOnBoot] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.UDPAlignOnPPS] = SLICE6AIRBR.UDPALIGNONPPS_PROTOCOL;
|
||||
SLICE6AIR_BR_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ADCSamplesPerPacket] = SLICE6AIRBR.ADC_SAMPLES_PER_PACKET_VER;
|
||||
MinimumProtocols = SLICE6AIR_BR_MinimumProtocols;
|
||||
}
|
||||
|
||||
#region protocol settings/overrides
|
||||
private readonly Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte> SLICE6AIR_BR_MinimumProtocols =
|
||||
new Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>();
|
||||
|
||||
protected override int MIN_PROTOCOL_TMATS_INTERVAL => SLICE6AIRBR.MIN_PROTOCOL_VER;
|
||||
|
||||
private uint maxSampleRateHz = 0;
|
||||
protected override uint MaxSampleRateHz
|
||||
{
|
||||
get
|
||||
{
|
||||
if (0 == maxSampleRateHz)
|
||||
{
|
||||
try
|
||||
{
|
||||
var qsa = new QuerySystemAttributeSLICE6(this)
|
||||
{
|
||||
Key = AttributeTypes.SystemAttributesSLICE6.MaximumSampleRate
|
||||
};
|
||||
qsa.SyncExecute();
|
||||
maxSampleRateHz = (uint)qsa.Value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Error getting S6A-BR max sample rate, returning 50K");
|
||||
APILogger.LogException(ex);
|
||||
return 50000;
|
||||
}
|
||||
}
|
||||
return maxSampleRateHz;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected override DASModule MakeConfigModuleFromInfoModule(InfoResult.Module infoModule)
|
||||
{
|
||||
//per LP: can stream, no IEPE
|
||||
var configModule = new DASModule(infoModule.ModuleArrayIndex, this);
|
||||
configModule.Channels = new DASChannel[infoModule.NumberOfChannels];
|
||||
|
||||
for (var i = 0; i < infoModule.NumberOfChannels; i++)
|
||||
{
|
||||
if (DFConstantsAndEnums.ModuleType.StreamOut == configModule.ModuleType())
|
||||
{
|
||||
var streamOutChannel = new StreamOutputDASChannel(configModule, i);
|
||||
configModule.Channels[i] = streamOutChannel;
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = new AnalogInputDASChannel(configModule, i);
|
||||
|
||||
channel.SupportedBridges = new SensorConstants.BridgeType[]
|
||||
{
|
||||
SensorConstants.BridgeType.FullBridge,
|
||||
SensorConstants.BridgeType.HalfBridge,
|
||||
};
|
||||
configModule.Channels[i] = channel;
|
||||
}
|
||||
}
|
||||
|
||||
return configModule;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// we can probably simplify and take common items (slice6+slice1) out of this function, but for now
|
||||
/// it's mostly a copy of SLICE1.AsyncConfigure
|
||||
/// </summary>
|
||||
/// <param name="configAsyncInfo"></param>
|
||||
protected override void AsyncConfigure(object configAsyncInfo)
|
||||
{
|
||||
var info = configAsyncInfo as SliceConfigServiceAsyncInfo;
|
||||
SetUDPAlignOnPPS();
|
||||
SetRemoveSeconds();
|
||||
if ((info.StreamADCPerPacket != null) && info.StreamADCPerPacket.ContainsKey(this))
|
||||
{
|
||||
SetADCSamplesPerPacket(info.StreamADCPerPacket[this]);
|
||||
}
|
||||
|
||||
//12638 DAS does not record data in recorder mode during calibration ~ 40% of time.
|
||||
//for SLICE6 we call reseteventlist here, prior to configuring and NOT before arming
|
||||
ResetEventListPriorToConfigure();
|
||||
|
||||
int progressValue = 0;
|
||||
bool bReleased = true;
|
||||
|
||||
if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.ProgramStackChannels))
|
||||
{
|
||||
ReconfigureAccordingToConfig();
|
||||
}
|
||||
|
||||
PresetSampleRate();
|
||||
|
||||
SetVoltageRequirements();
|
||||
|
||||
SetPolarity();
|
||||
|
||||
SetArmDisableShortCheck();
|
||||
|
||||
try
|
||||
{
|
||||
Lock();
|
||||
bReleased = false;
|
||||
// loop thru the modules (slices) and configure the non-UART channels
|
||||
var numChannels = DASInfo.Modules.Sum(mod => mod.NumberOfChannels);
|
||||
var numStreamingChannels = DASInfo.Modules.Sum(mod => DFConstantsAndEnums.ModuleType.StreamOut == mod.TypeOfModule ? mod.NumberOfChannels : 0);
|
||||
var rangeArray = new float[numChannels];
|
||||
//var IsHalfBridgeArray = new bool[numChannels];
|
||||
var bridgeModeArray = new byte[numChannels];
|
||||
var BridgeResistanceArray = new ushort[numChannels];
|
||||
var IsACCoupledArray = new bool[numChannels];
|
||||
//18294 Implement Bridge AC / DC coupling(fw update dependent)
|
||||
var bridgeACCouplingArray = new bool[numChannels];
|
||||
// level trigger values
|
||||
var enableLowerLevelTriggerThreshold = new bool[numChannels];
|
||||
var enableUpperLevelTriggerThreshold = new bool[numChannels];
|
||||
var lowerLevelTriggerThreshold = new float[numChannels];
|
||||
var upperLevelTriggerThreshold = new float[numChannels];
|
||||
var qualificationSamples = new int[numChannels];
|
||||
|
||||
var diagnosticChannels = new List<byte>();
|
||||
|
||||
var bModified = false;
|
||||
CommonConfigureWork(diagnosticChannels, qualificationSamples, ref bReleased,
|
||||
info, bridgeModeArray, IsACCoupledArray, BridgeResistanceArray,
|
||||
ref bModified, rangeArray, enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold,
|
||||
enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold, bridgeACCouplingArray);
|
||||
if (bReleased) { return; }
|
||||
// report progress
|
||||
progressValue = 5;
|
||||
info.Progress(progressValue);
|
||||
|
||||
StoreConfigAttributes(info, rangeArray, ref bReleased, ref progressValue, bridgeModeArray,
|
||||
IsACCoupledArray, BridgeResistanceArray, enableLowerLevelTriggerThreshold, lowerLevelTriggerThreshold,
|
||||
enableUpperLevelTriggerThreshold, upperLevelTriggerThreshold, qualificationSamples, numChannels,
|
||||
out var config, bridgeACCouplingArray, 0, numStreamingChannels);
|
||||
|
||||
progressValue = 20;
|
||||
info.Progress(progressValue);
|
||||
|
||||
RemainingConfigWork(ref progressValue, info, diagnosticChannels, config, ref bReleased, null, null, null);
|
||||
}
|
||||
catch (CanceledException)
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Cancel();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
|
||||
info.Error(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!bReleased)
|
||||
{
|
||||
bReleased = true;
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
info.Progress(100);
|
||||
info.Success();
|
||||
}
|
||||
/// <summary>
|
||||
/// returns true if the device is known to be streaming
|
||||
/// does not query device, just returns a flag if it has been set
|
||||
/// </summary>
|
||||
public override bool GetIsStreaming()
|
||||
{
|
||||
if (null == DASArmStatus) { return false; }
|
||||
//18852 Cannot use Stop streaming / (Dis)Auto Arm button if one or more DAS is idle
|
||||
//can't rely on just having received invalid mode, QATS will still have a status of realtime
|
||||
//when streaming, so we'll use either for now.
|
||||
return DASArmStatus.ReceivedInvalidModeDuringSetup || DASArmStatus.IsInRealtime;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using System.Xml;
|
||||
using System.IO.Ports;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for storing/applying UART settings as a channel
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class UARTInputDASChannel : InputDASChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// CTOR to populate a channel's owning module and channel WRT that module. Calls
|
||||
/// base class CTOR.
|
||||
/// </summary>
|
||||
/// <param name="owner">Module that contains this channel.</param>
|
||||
/// <param name="channelNumber">ChannelNumber of this channel WRT owning module.</param>
|
||||
public UARTInputDASChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
}
|
||||
|
||||
public UARTInputDASChannel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Serial number of the sensor.
|
||||
/// </summary>
|
||||
public string SerialNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the hardware channel
|
||||
/// </summary>
|
||||
public string HardwareChannelName { get; set; }
|
||||
|
||||
public uint BaudRate { get; set; }
|
||||
|
||||
public uint DataBits { get; set; }
|
||||
|
||||
public StopBits StopBits { get; set; }
|
||||
|
||||
public Parity Parity { get; set; }
|
||||
|
||||
public Handshake FlowControl { get; set; }
|
||||
|
||||
public UartDataFormat DataFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the channel has a serial number in the SerialNumber field, it is "Configured".
|
||||
/// </summary>
|
||||
public override bool IsConfigured()
|
||||
{
|
||||
return !string.IsNullOrEmpty(SerialNumber);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"UART{ModuleChannelNumber}";
|
||||
}
|
||||
public override void WriteXml(XmlWriter writer)
|
||||
{
|
||||
base.WriteXml(writer);
|
||||
|
||||
// SerialNumber
|
||||
XMLHelper.PutString(writer, "SerialNumber", SerialNumber);
|
||||
XMLHelper.PutString(writer, "HardwareChannelName", HardwareChannelName);
|
||||
XMLHelper.PutString(writer, "BaudRate", BaudRate.ToString());
|
||||
XMLHelper.PutString(writer, "DataBits", DataBits.ToString());
|
||||
XMLHelper.PutString(writer, "StopBits", StopBits.ToString());
|
||||
XMLHelper.PutString(writer, "Parity", Parity.ToString());
|
||||
XMLHelper.PutString(writer, "FlowControl", FlowControl.ToString());
|
||||
XMLHelper.PutString(writer, "DataFormat", DataFormat.ToString());
|
||||
|
||||
}
|
||||
private const string SERIALNUMBER_TAG = "SerialNumber";
|
||||
private const string HARDWARECHANNELNAME_TAG = "HardwareChannelName";
|
||||
private const string BAUDRATE_TAG = "BaudRate";
|
||||
private const string DATABITS_TAG = "DataBits";
|
||||
private const string STOPBITS_TAG = "StopBits";
|
||||
private const string PARITY_TAG = "Parity";
|
||||
private const string FLOWCONTROL_TAG = "FlowControl";
|
||||
private const string DATAFORMAT_TAG = "DataFormat";
|
||||
protected override void HandleElement(XmlReader reader)
|
||||
{
|
||||
base.HandleElement(reader);
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
var value = string.Empty;
|
||||
switch (reader.Name)
|
||||
{
|
||||
case SERIALNUMBER_TAG:
|
||||
SerialNumber = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case HARDWARECHANNELNAME_TAG:
|
||||
HardwareChannelName = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case BAUDRATE_TAG:
|
||||
BaudRate = Convert.ToUInt32(XMLHelper.GetString(reader));
|
||||
break;
|
||||
case DATABITS_TAG:
|
||||
DataBits = Convert.ToUInt32(XMLHelper.GetString(reader));
|
||||
break;
|
||||
case STOPBITS_TAG:
|
||||
try
|
||||
{
|
||||
StopBits = (StopBits)Enum.Parse(typeof(StopBits), XMLHelper.GetString(reader));
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
break;
|
||||
case PARITY_TAG:
|
||||
try
|
||||
{
|
||||
Parity = (Parity)Enum.Parse(typeof(Parity), XMLHelper.GetString(reader));
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
break;
|
||||
case FLOWCONTROL_TAG:
|
||||
try
|
||||
{
|
||||
FlowControl = (Handshake)Enum.Parse(typeof(Handshake), XMLHelper.GetString(reader));
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
break;
|
||||
case DATAFORMAT_TAG:
|
||||
try
|
||||
{
|
||||
DataFormat = (UartDataFormat)Enum.Parse(typeof(UartDataFormat), XMLHelper.GetString(reader));
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
break;
|
||||
default:
|
||||
// let child handle it
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// this attribute controls whether a gain is disabled or not
|
||||
/// this was done for
|
||||
/// http://fogbugz/fogbugz/default.asp?10080
|
||||
/// to prevent the higher range gains which were considered just not useful
|
||||
/// this attribute is optional, it is assume the gain is not disabled
|
||||
/// unless it's explicitly marked as disabled
|
||||
/// </summary>
|
||||
public class GainDisabledAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// returns whether the gain is disabled or not
|
||||
/// http://fogbugz/fogbugz/default.asp?10080
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsGainDisabled(object o)
|
||||
{
|
||||
if (o == null) return false;
|
||||
var mi = o.GetType().GetMember(o.ToString());
|
||||
if (mi.Length <= 0) return false;
|
||||
return GetCustomAttribute(mi[0], typeof(GainDisabledAttribute)) is GainDisabledAttribute attr && attr._bDisabled;
|
||||
}
|
||||
|
||||
private readonly bool _bDisabled;
|
||||
public GainDisabledAttribute(bool disabled)
|
||||
{
|
||||
_bDisabled = disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Utilities;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.DASLib.Command.SLICE;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class EIDReader
|
||||
{
|
||||
/// <summary>
|
||||
/// returns true if the device supports QueryOneWireID
|
||||
/// false otherwise.
|
||||
/// this is a bit strange, since QueryOneWireID is a SLICE Command
|
||||
/// and only slice devices should support it, and only some slice
|
||||
/// devices at that, however the current code doesn't care so this is
|
||||
/// just a helper for
|
||||
/// 22296 No need to query for system ID when querying a TSR AIR device
|
||||
/// really a lot of devices probably belong in here, but I'm keeping the
|
||||
/// existing behavior for now...
|
||||
/// </summary>
|
||||
/// <param name="comm"></param>
|
||||
/// <returns>true if device supports QueryOneWireID, false otherwise</returns>
|
||||
public static bool SupportsQueryOneWireID(ICommunication comm)
|
||||
{
|
||||
switch (comm)
|
||||
{
|
||||
case EthernetTsrAir _:
|
||||
case WinUSBTsrAir _:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private static EID[] Retrive_EIDs(ICommunication comm, byte DASChannelNumber, int idType)
|
||||
{
|
||||
if (!SupportsQueryOneWireID(comm)) { return null; }
|
||||
var idList = new List<EID>();
|
||||
try
|
||||
{
|
||||
var IDQuery = new QueryOneWireID(comm);
|
||||
IDQuery.StackChannel = DASChannelNumber;
|
||||
IDQuery.IdType = (QueryOneWireID.IdTypes)idType;
|
||||
IDQuery.SyncExecute();
|
||||
if (IDQuery.IDs.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < IDQuery.IDs.Count; i++)
|
||||
{
|
||||
idList.Add(new EID(HexEncoding.ToString(IDQuery.IDs[i])));
|
||||
}
|
||||
return idList.ToArray();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to retrieve ids", comm.SerialNumber, ex);
|
||||
}
|
||||
// no id's
|
||||
return null;
|
||||
}
|
||||
|
||||
private static EID[] Retrive_EIDs(ICommunication comm, int moduleIndex)
|
||||
{
|
||||
if (!SupportsQueryOneWireID(comm)) { return null; }
|
||||
|
||||
var idList = new List<EID>();
|
||||
Command.TDAS.ReadSensorIDs rsi = new Command.TDAS.ReadSensorIDs(comm);
|
||||
rsi.ModuleIndex = moduleIndex;
|
||||
rsi.SyncExecute();
|
||||
if (rsi.IDs != null && rsi.IDs.Count > 0)
|
||||
{
|
||||
foreach (string id in rsi.IDs)
|
||||
{
|
||||
idList.Add(new EID(id));
|
||||
}
|
||||
|
||||
return idList.ToArray();
|
||||
}
|
||||
else { return null; }
|
||||
}
|
||||
public static IEID[] RetriveEIDs(ICommunication comm, byte DASChannelNumber, int idType)
|
||||
{
|
||||
//don't return empty set as calstation indexes it if it's not null :/
|
||||
if (!SupportsQueryOneWireID(comm)) { return null; }
|
||||
//I have to return null here rather than empty set as there's a consumer that automatically index 0 if it's not null
|
||||
//and it's in calstation code, so I want to avoid breaking that
|
||||
if (RunTestVariables.BypassEIDRead) { return null; }
|
||||
|
||||
for (int RetryCounter = 0; RetryCounter < 3; RetryCounter++)
|
||||
{
|
||||
var ids = Retrive_EIDs(comm, DASChannelNumber, idType);
|
||||
if (ids != null && ids.Length > 0)
|
||||
{
|
||||
bool bValid = true;
|
||||
foreach (var id in ids)
|
||||
{
|
||||
if (!id.IsValid())
|
||||
{
|
||||
bValid = false;
|
||||
string target = "<unknown>";
|
||||
if (comm is IDASCommunication)
|
||||
{
|
||||
target = (comm as IDASCommunication).ToString();
|
||||
}
|
||||
APILogger.LogString(string.Format("EIDReader.RetriveEIDs: Retry for {0} on channel {1}, ID({2})", target, DASChannelNumber, id.ID));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if we made it here, they're all valid
|
||||
if (bValid) { return ids; }
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// blank EID returned by some command queries (TDAS IDX for example)
|
||||
/// </summary>
|
||||
public const string BLANK_ID = "0000000000000000";
|
||||
/// <summary>
|
||||
/// returns true if the EID is blank
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns>true if is blank, false otherwise</returns>
|
||||
public static bool IsBlankID(string id)
|
||||
{
|
||||
return id.Equals(BLANK_ID);
|
||||
}
|
||||
public static EID[][] RetrieveEIDsG5(ICommunication comm)
|
||||
{
|
||||
if (RunTestVariables.BypassEIDRead)
|
||||
{
|
||||
return new EID[0][];
|
||||
}
|
||||
|
||||
var eids = new List<EID[]>();
|
||||
try
|
||||
{
|
||||
var idx = new Command.TDAS.RackIDX(comm);
|
||||
idx.SyncExecute();
|
||||
foreach (var channelIDs in idx.IDs)
|
||||
{
|
||||
var ids = new List<EID>();
|
||||
foreach (var channelID in channelIDs)
|
||||
{
|
||||
if (IsBlankID(channelID)) { ids.Add(new EID()); }
|
||||
else { ids.Add(new EID(channelID)); }
|
||||
}
|
||||
eids.Add(ids.ToArray());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("RetrieveEIDsG5 failed", ex);
|
||||
}
|
||||
return eids.ToArray();
|
||||
}
|
||||
public static EID[] RetriveEIDs(ICommunication comm, int moduleIndex)
|
||||
{
|
||||
if (!SupportsQueryOneWireID(comm)) { return null; }
|
||||
for (int RetryCounter = 0; RetryCounter < 3; RetryCounter++)
|
||||
{
|
||||
var ids = Retrive_EIDs(comm, moduleIndex);
|
||||
if (null != ids && ids.Length > 0)
|
||||
{
|
||||
for (int i = 0; i < ids.Length; i++)
|
||||
{
|
||||
if (!ids[i].IsValid())
|
||||
{
|
||||
string target = "<unknown>";
|
||||
if (comm is IDASCommunication)
|
||||
{
|
||||
target = (comm as IDASCommunication).ToString();
|
||||
}
|
||||
APILogger.LogString(string.Format("EIDReader.RetreiveEIDS: ID invalid for {0} on module {1}, ID({2})", target, moduleIndex, ids[i].ID));
|
||||
break; ;
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using DTS.Common;
|
||||
|
||||
namespace DTS.DASLib.Service.Interfaces
|
||||
{
|
||||
public interface IClockSyncActions
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve the current clock source & sync status from the DAS
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
///
|
||||
void GetClockSyncStatus(ServiceCallback callback, object userData);
|
||||
//- Command Parameter: uint8[4]. Default = 0.
|
||||
//- Response data payload byte stream:
|
||||
//Byte 0: Input Synchronization Clock Source
|
||||
//---- Bit_0: PTP
|
||||
//---- Bit_1: IRIG-B122
|
||||
//---- Bit_2: GPS
|
||||
//---- Bit_3: 1PPS
|
||||
//---- Bit_7:4: RSV
|
||||
|
||||
//Byte 1: Output Synchronization Clock Source
|
||||
//---- Bit_1:0: = 0 disable.
|
||||
// 1 = PTP Master
|
||||
// 2 = PTP Boundary
|
||||
// 3 = Reserved
|
||||
//---- Bit_2: E2E(0)/P2P(1)
|
||||
//---- Bit_3: 1PPS
|
||||
//---- Bit_7:4: Reserved
|
||||
|
||||
//Byte 2: Synchronization Status.
|
||||
//---- Bit_0: PTP
|
||||
//---- Bit_1: IRIG-B122
|
||||
//---- Bit_2: GPS
|
||||
//---- Bit_3: 1PPS
|
||||
//---- Bit_7:4: RSV
|
||||
// Bit set = true.Clear = false.
|
||||
|
||||
//Byte 3: Current Arm State.
|
||||
|
||||
//Byte[7:4] = 32bit for seconds when sync is locked. --
|
||||
|
||||
//Byte[11:8] = 32bit for nanoseconds when sync is locked. – 64-bit PTP format to keep track of sync status
|
||||
|
||||
//Byte[15:12] = 32bit for seconds when sync is lost. --
|
||||
|
||||
//Byte[19:16] = 32bit for nanoseconds when sync is lost. – 64-bit PTP format to keep track of sync status
|
||||
|
||||
//Byte[31:20] = 12 bytes reserved for future usage.
|
||||
|
||||
// Total data response = 32B in payload.
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set the input and output clock configuration for the DAS
|
||||
/// </summary>
|
||||
/// <param name="callback">The function to call with information</param>
|
||||
/// <param name="userData">Whatever you want to pass along</param>
|
||||
/// <param name="profile">Whatever you want to pass along</param>
|
||||
///
|
||||
void SetClockSyncConfig(ServiceCallback callback, object userData, ClockSyncProfile profile);
|
||||
//SLICE6 AIR has various input clock synchronization methods such as PTP, GPS/1PPS, or IRIG.In addition, it can also be acting as PTP boundary/master on the Ethernet output.
|
||||
//Currently supported inputs:
|
||||
//1. 1588 PTP
|
||||
//2. IRIG-B122
|
||||
//3. GPS/1PPS
|
||||
// Note that 1PPS can be a standalone feature in addition to GPS, IRIGB or even 1588. For Clock Synchronization commands, we are adding set/query clocksync as following:
|
||||
|
||||
//(Command Class of SYNC1588)
|
||||
//Set Clocksync config: CMD_CLOCKSYNC_SET_CONFIG(0x0D)
|
||||
// - Command Parameter: uint8[4].
|
||||
|
||||
//Byte 0: Input Synchronization Clock Source
|
||||
//---- Bit_0: PTP
|
||||
//---- Bit_1: IRIG-B122
|
||||
//---- Bit_2: GPS
|
||||
//---- Bit_3: 1PPS
|
||||
//---- Bit_7:4: RSV
|
||||
|
||||
//Byte 1: Output Synchronization Clock Source
|
||||
//---- Bit_1:0: = 0 disable.
|
||||
// 1 = PTP Master
|
||||
// 2 = PTP Boundary
|
||||
// 3 = Reserved
|
||||
//---- Bit_2: E2E(0)/P2P(1)
|
||||
//---- Bit_3: 1PPS
|
||||
//---- Bit_7:4: Reserved
|
||||
//Byte 2: Reserved
|
||||
// Byte 3: Reserved
|
||||
|
||||
//- Response with Status Code Success(0) or Error Code(non-zero)
|
||||
//No payload.
|
||||
void GetPTPDomainID(ServiceCallback callback, object userData);
|
||||
void SetPTPDomainID(ServiceCallback callback, object userData, byte domainID);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,142 @@
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class GlobalStatusInformation : IStatusInfo
|
||||
{
|
||||
private static readonly object MyLock = new object();
|
||||
|
||||
private List<IDASCommunication> _unitsInRealtime = new List<IDASCommunication>();
|
||||
/// <summary>
|
||||
/// returns an array of all devices that are known to be in realtime
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IDASCommunication[] GetUnitsInRealtime()
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
return _unitsInRealtime.ToArray();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// adds a device to the list of units known to be in realtime
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
public void AddUnitInRealtime(IDASCommunication device)
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (_unitsInRealtime.Contains(device)) { return; }
|
||||
|
||||
_unitsInRealtime.Add(device);
|
||||
}
|
||||
}
|
||||
|
||||
private List<IDASCommunication> _unitsInArm = new List<IDASCommunication>();
|
||||
/// <summary>
|
||||
/// returns an array of units known to be in arm
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IDASCommunication[] GetUnitsInArm()
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
return _unitsInArm.ToArray();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// adds a device to the list of devices known to be in arm
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
public void AddUnitInArm(IDASCommunication device)
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (_unitsInArm.Contains(device))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_unitsInArm.Add(device);
|
||||
}
|
||||
}
|
||||
|
||||
private List<IDASCommunication> _unitsAtLowPower = new List<IDASCommunication>();
|
||||
/// <summary>
|
||||
/// returns an array of all known devices that are at low power
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IDASCommunication[] GetUnitsAtLowPower()
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
return _unitsAtLowPower.ToArray();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// adds a unit to the list of units currently at low power
|
||||
/// removes from high power list if present in it
|
||||
/// </summary>
|
||||
/// <param name="das"></param>
|
||||
public void AddUnitAtLowPower(IDASCommunication das)
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (_unitsAtLowPower.Contains(das)) { return; }
|
||||
_unitsAtLowPower.Add(das);
|
||||
if (!_unitsAtHighPower.Contains(das)) { return; }
|
||||
|
||||
_unitsAtHighPower.Remove(das);
|
||||
}
|
||||
}
|
||||
private List<IDASCommunication> _unitsAtHighPower = new List<IDASCommunication>();
|
||||
/// <summary>
|
||||
/// returns an array of all units that are known to be at high power
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IDASCommunication[] GetUnitsAtHighPower()
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
return _unitsAtHighPower.ToArray();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// adds unit to the list of devices known to be at high power
|
||||
/// removes from the low power list if present
|
||||
/// </summary>
|
||||
/// <param name="das"></param>
|
||||
public void AddUnitAtHighPower(IDASCommunication das)
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
if (_unitsAtHighPower.Contains(das)) { return; }
|
||||
_unitsAtHighPower.Add(das);
|
||||
if (!_unitsAtLowPower.Contains(das)) { return; }
|
||||
_unitsAtLowPower.Remove(das);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// whether excitation is on or off, currently this is just
|
||||
/// controlled by Configure->TurnOffExcitation and Configure->PrepareForDiagnostics
|
||||
/// the status is only changed currently if all units successfully switch to low power or vice versa
|
||||
/// </summary>
|
||||
public bool ExcitationOn { get; set; } = false;
|
||||
/// <summary>
|
||||
/// resets all status back to defaults
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
ExcitationOn = false;
|
||||
lock (MyLock)
|
||||
{
|
||||
_unitsAtHighPower.Clear();
|
||||
_unitsAtLowPower.Clear();
|
||||
_unitsInRealtime.Clear();
|
||||
_unitsInArm.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
using DASFactoryDb.Diagnostics;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This class holds instructions about how a single channel
|
||||
/// is to be diagnosed. The results from these tests will populate the
|
||||
/// DiagnosticsResults[] object in the IDASCommunication object. The results
|
||||
/// can then be compared against the hardware specifications for a sensor to
|
||||
/// determine if the channel is set up correctly before arming and recording.
|
||||
/// </summary>
|
||||
public class DiagnosticsActions : IDiagnosticActions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Which DAS Channel (CH# WRT entire DAS unit) are these diagnostic test
|
||||
/// instructions for?
|
||||
/// </summary>
|
||||
public int DASChannelNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should we measure the excitation volatge being applied to this sensor?
|
||||
/// </summary>
|
||||
public bool MeasureExcitation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should we measure the sensor's offset from 0? (If measured, the returned offset can
|
||||
/// be checked against the high and low offset limits that are properties of the
|
||||
/// AnalogInputDasChannel object corresponding to this sensor.)
|
||||
/// </summary>
|
||||
public bool MeasureOffset { get; set; }
|
||||
/// <summary>
|
||||
/// should we check the open/closed/low/high nature of a digital input channel?
|
||||
/// </summary>
|
||||
public bool CheckDigitalState { get; set; }
|
||||
|
||||
public bool MeasureInternalOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should the firmware compensate for the offset from 0 of this sensor?
|
||||
/// </summary>
|
||||
public bool RemoveOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should we measure the noise floor as a percentage of full scale readings?
|
||||
/// </summary>
|
||||
public bool MeasureNoise { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should an emulated shunt-check be performed on this sensor.
|
||||
/// </summary>
|
||||
public bool PerformShuntCheck { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// should run a squib fire check on channel
|
||||
/// </summary>
|
||||
public bool SquibFireCheck { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// perform a voltage insertion gain check (SLICE Pro)
|
||||
/// </summary>
|
||||
public bool PerformVoltageInsertCheck { get; set; }
|
||||
/// <summary>
|
||||
/// Should a Calibration signal-check be performed on this sensor.
|
||||
/// </summary>
|
||||
public bool PerformCalSignalCheck { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should the resistance of the bridge be measured?
|
||||
/// </summary>
|
||||
public bool MeasureBridgeResistance { get; set; }
|
||||
|
||||
public DiagnosticsActions()
|
||||
{
|
||||
DASChannelNumber = 0;
|
||||
MeasureExcitation = false;
|
||||
MeasureOffset = false;
|
||||
RemoveOffset = false;
|
||||
MeasureNoise = false;
|
||||
PerformShuntCheck = false;
|
||||
PerformCalSignalCheck = false;
|
||||
PerformVoltageInsertCheck = false;
|
||||
MeasureInternalOffset = false;
|
||||
CheckDigitalState = false;
|
||||
}
|
||||
|
||||
public bool AllActionsDisabled()
|
||||
{
|
||||
return !MeasureExcitation && !MeasureOffset && !RemoveOffset && !MeasureNoise && !PerformShuntCheck &&
|
||||
!MeasureBridgeResistance
|
||||
&& !PerformCalSignalCheck && !PerformVoltageInsertCheck && !MeasureInternalOffset && !SquibFireCheck &&
|
||||
!CheckDigitalState;
|
||||
}
|
||||
|
||||
public static void SetChannelDiagnosticActions(IDASCommunication unit, IDiagnosticActions[] actions,
|
||||
bool setInDb)
|
||||
{
|
||||
unit.ChannelDiagnostics = actions;
|
||||
if (!DASFactoryDb.DbWrapper.Connected || !setInDb) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
Diagnostics.ClearDiagnosticActionsAllChannels(unit.RecordId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
|
||||
if (null != actions)
|
||||
{
|
||||
foreach (var action in actions)
|
||||
{
|
||||
InsertAction(unit.RecordId, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void InsertAction(int dasRecordId, IDiagnosticActions action)
|
||||
{
|
||||
try
|
||||
{
|
||||
Diagnostics.InsertDiagnosticAction(dasRecordId,
|
||||
action.DASChannelNumber,
|
||||
action.MeasureExcitation,
|
||||
action.MeasureOffset,
|
||||
action.CheckDigitalState,
|
||||
action.MeasureInternalOffset,
|
||||
action.RemoveOffset,
|
||||
action.MeasureNoise,
|
||||
action.PerformShuntCheck,
|
||||
action.SquibFireCheck,
|
||||
action.PerformVoltageInsertCheck,
|
||||
action.PerformCalSignalCheck,
|
||||
action.MeasureBridgeResistance);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// this attribute controls the minimum input range for a gain
|
||||
/// note that we could calculate this, but this allows us some flexibility
|
||||
/// in real life there are calibration and other factors that can affect what actually
|
||||
/// is achievable at a given gain step, so this minimum input could be a theoretical one
|
||||
/// http://fogbugz/fogbugz/default.asp?10080
|
||||
/// </summary>
|
||||
public class MinInputRangeAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// returns the minimum input range for a gain
|
||||
/// http://fogbugz/fogbugz/default.asp?10080
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
/// <returns></returns>
|
||||
public static double GetMinInputRangemV(object o)
|
||||
{
|
||||
if (o == null) return 0D;
|
||||
var mi = o.GetType().GetMember(o.ToString());
|
||||
if (mi.Length <= 0) return 0D;
|
||||
return GetCustomAttribute(mi[0], typeof(MinInputRangeAttribute)) is MinInputRangeAttribute attr ? attr._minimumInputRangemV : 0D;
|
||||
}
|
||||
|
||||
private readonly double _minimumInputRangemV;
|
||||
public MinInputRangeAttribute(double minInputRangemV)
|
||||
{
|
||||
_minimumInputRangemV = minInputRangemV;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
internal class Arming : DASState
|
||||
{
|
||||
public override State State => State.Arming;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public interface IStatusParameters
|
||||
{
|
||||
void Reset();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
using DTS.Common.Classes.DSP;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Interface.Channels;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.Interface.StatusAndProgressBar;
|
||||
using DTS.Common.Interface.TestSetups.TestSetupsList;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class ConfigureStatusParameters : IStatusParameters
|
||||
{
|
||||
#region ResolveChannels
|
||||
public bool RequireIdFoundForSensorsWithIds { get; set; } = true;
|
||||
public bool AllowMissingSensors { get; set; } = false;
|
||||
public bool AllowSensorsOutOfPosition { get; set; } = true;
|
||||
|
||||
public ITestSetup TestSetupConfiguration { get; set; }
|
||||
public delegate ISensorData GetSensorDelegate(IGroupChannel groupChannel);
|
||||
|
||||
public delegate ISensorCalibration GetSensorCalibrationDelegate(ISensorData sensor,
|
||||
ExcitationVoltageOptions.ExcitationVoltageOption excitation);
|
||||
/// <summary>
|
||||
/// delegate allowing us to retrieve the latest sensor calibration given a sensor and an excitation
|
||||
/// </summary>
|
||||
public GetSensorCalibrationDelegate GetCalibrationAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// retrieves a sensor given a group channel
|
||||
/// this is handled in DataPRO by DataModel.TestTemplate
|
||||
/// but since that exists in UI land, we'll just define a delegate
|
||||
/// and allow it to be provided by the consumer by whatever mechanism it chooses
|
||||
/// for run test this should be testtemplate, but for testing it could equally
|
||||
/// just come from the db or directly provided
|
||||
/// </summary>
|
||||
public GetSensorDelegate GetSensorAction { get; set; }
|
||||
public bool AllowSensorIdToBlankChannel { get; set; }
|
||||
|
||||
public delegate int GetDatabaseIdDelegate(IDASCommunication das);
|
||||
public GetDatabaseIdDelegate GetDatabaseIdAction { get; set; }
|
||||
|
||||
public delegate void SetSensorCalibrationDelegate(ISensorData sd, ISensorCalibration sc);
|
||||
public SetSensorCalibrationDelegate SetSensorCalibrationAction { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Configure
|
||||
/// <summary>
|
||||
/// Excitation should be turned off, this flag is reverted as soon as the process to turn off excitation starts
|
||||
/// </summary>
|
||||
public bool TurnOffExcitation { get; set; } = false;
|
||||
/// <summary>
|
||||
/// defines an array of units which configuration should be applied to
|
||||
/// </summary>
|
||||
public IDASCommunication[] UnitsToConfigure { get; set; } = new IDASCommunication[0];
|
||||
/// <summary>
|
||||
/// whether strict check should be used when applying configuration
|
||||
/// </summary>
|
||||
public bool DoStrictCheck { get; set; } = true;
|
||||
/// <summary>
|
||||
/// whether configuration should be written to even or diagnostic file stores
|
||||
/// (this is a legacy feature of sliceware, not all units support it, but SLICE units have multiple file stores
|
||||
/// so configuration could be written to different ones (diagnostic/event)
|
||||
/// </summary>
|
||||
public bool EventConfig { get; set; } = true;
|
||||
/// <summary>
|
||||
/// whether we are configuring units for data collection or just dummy collection (not collecting data)
|
||||
/// </summary>
|
||||
public bool DummyConfig { get; set; } = false;
|
||||
/// <summary>
|
||||
/// the MAX AAF for SLICE and TDAS
|
||||
/// </summary>
|
||||
public double[] MaxAAF { get; set; } = new double[0];
|
||||
/// <summary>
|
||||
/// whether digital outputs should be applied or not when applying configuration
|
||||
/// this allows digital outputs to not be configured for say trigger check
|
||||
/// </summary>
|
||||
public bool ConfigureDigitalOutputs { get; set; } = true;
|
||||
/// <summary>
|
||||
/// the current configure process can occasionally require user input
|
||||
/// [probably to acknowledge AAF errors?] this allows a method of interacting
|
||||
/// during this process
|
||||
/// </summary>
|
||||
public ErrorCallback ErrorRequiringActionAction { get; set; }
|
||||
/// <summary>
|
||||
/// whether AAF should be turned off for realtime or not
|
||||
/// AAF takes up a lot of time for slice realtime, so it's usually desirable to turn off
|
||||
/// </summary>
|
||||
public bool TurnOffAAFRealtime { get; set; } = true;
|
||||
/// <summary>
|
||||
/// whether to reset the hardware event lines before setting the config
|
||||
/// </summary>
|
||||
public bool ResetHardwareEventLines { get; set; } = false;
|
||||
/// <summary>
|
||||
/// whether to prepare for diagnostics (turn on excitation, switches)
|
||||
/// </summary>
|
||||
public bool PrepareForDiagnostics { get; set; } = false;
|
||||
/// <summary>
|
||||
/// lookup serial number to data collection rate
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, double> SampleRateLookup { get; set; } = new Dictionary<string, double>();
|
||||
/// <summary>
|
||||
/// lookup serial number to Anti Alias Filter rate
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, float> AAFRateLookup { get; set; } = new Dictionary<string, float>();
|
||||
/// <summary>
|
||||
/// whether turning on power should be skipped or not
|
||||
/// this can allow excitation to remain off which is sometimes used to keep the units in low power state
|
||||
/// until the user explicitly turns on power
|
||||
/// </summary>
|
||||
public bool SkipTurnOnPower { get; set; } = false;
|
||||
/// <summary>
|
||||
/// whether to apply configuration or not
|
||||
/// </summary>
|
||||
public bool SetConfiguration { get; set; } = true;
|
||||
public DSPFilterType DSPFilterType { get; set; }
|
||||
/// <summary>
|
||||
/// whether to discard diagnostics when setting configuration
|
||||
/// </summary>
|
||||
public bool DiscardDiagnostics { get; set; } = true;
|
||||
#endregion
|
||||
|
||||
public ConfigureStatusParameters()
|
||||
{
|
||||
ResetDSPFilterType();
|
||||
}
|
||||
private void ResetDSPFilterType()
|
||||
{
|
||||
var dsp = DSPFilterCollection.GetDSPFilterCollection();
|
||||
DSPFilterType = dsp.GetFilter(string.Empty);
|
||||
}
|
||||
/// <summary>
|
||||
/// resets all parameters back to defaults
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
RequireIdFoundForSensorsWithIds = true;
|
||||
AllowMissingSensors = false;
|
||||
AllowSensorsOutOfPosition = true;
|
||||
DoStrictCheck = true;
|
||||
EventConfig = true;
|
||||
DummyConfig = false;
|
||||
MaxAAF = new double[0];
|
||||
ConfigureDigitalOutputs = true;
|
||||
ErrorRequiringActionAction = null;
|
||||
TestSetupConfiguration = null;
|
||||
GetSensorAction = null;
|
||||
AllowSensorIdToBlankChannel = false;
|
||||
ResetHardwareEventLines = false;
|
||||
PrepareForDiagnostics = false;
|
||||
UnitsToConfigure = new IDASCommunication[0];
|
||||
SampleRateLookup = new Dictionary<string, double>();
|
||||
AAFRateLookup = new Dictionary<string, float>();
|
||||
SkipTurnOnPower = false;
|
||||
SetConfiguration = true;
|
||||
TurnOffExcitation = false;
|
||||
DiscardDiagnostics = true;
|
||||
ResetDSPFilterType();
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"RequireIdFoundForSensorsWithIds={RequireIdFoundForSensorsWithIds.ToString()}");
|
||||
sb.AppendLine($"AllowMissingSensors={AllowMissingSensors.ToString()}");
|
||||
sb.AppendLine($"AllowSensorsOutOfPosition={AllowSensorsOutOfPosition.ToString()}");
|
||||
sb.AppendLine($"DoStrictCheck={DoStrictCheck.ToString()}");
|
||||
sb.AppendLine($"EventConfig={EventConfig.ToString()}");
|
||||
sb.AppendLine($"DummyConfig={DummyConfig.ToString()}");
|
||||
sb.Append("MaxAAF=");
|
||||
for (int i = 0; i < MaxAAF.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Append(MaxAAF[i].ToString());
|
||||
}
|
||||
sb.AppendLine();
|
||||
sb.AppendLine($"ConfigureDigitalOutputs={ConfigureDigitalOutputs.ToString()}");
|
||||
sb.AppendLine($"AllowSensorIdToBlankChannel={AllowSensorIdToBlankChannel.ToString()}");
|
||||
sb.AppendLine($"ResetHardwareEventLines={ResetHardwareEventLines.ToString()}");
|
||||
sb.AppendLine($"PrepareForDiagnostics={PrepareForDiagnostics.ToString()}");
|
||||
sb.Append("UnitsToConfigure=");
|
||||
for (var i = 0; i < UnitsToConfigure.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Append(UnitsToConfigure[i].SerialNumber);
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
sb.Append("SampleRateLookup=");
|
||||
var first = true;
|
||||
using (var enumSampleRate = SampleRateLookup.GetEnumerator())
|
||||
{
|
||||
while (enumSampleRate.MoveNext())
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Append($"{enumSampleRate.Current.Key}={enumSampleRate.Current.Value.ToString()}");
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
sb.AppendLine();
|
||||
|
||||
sb.Append("AAFLookup=");
|
||||
first = true;
|
||||
using (var enumAAF = AAFRateLookup.GetEnumerator())
|
||||
{
|
||||
while (enumAAF.MoveNext())
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
|
||||
sb.Append($"{enumAAF.Current.Key}={enumAAF.Current.Value.ToString()}");
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine($"SkipTurnOnPower={SkipTurnOnPower.ToString()}");
|
||||
|
||||
sb.Append("ErrorRequiringActionAction=");
|
||||
sb.AppendLine(null == ErrorRequiringActionAction ? "[null]" : "[defined]");
|
||||
sb.AppendLine($"SetConfiguration={SetConfiguration.ToString()}");
|
||||
sb.AppendLine($"TurnOffExcitation={TurnOffExcitation.ToString()}");
|
||||
sb.AppendLine($"DiscardDiagnostics={DiscardDiagnostics.ToString()}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
internal class Prepare : DASState
|
||||
{
|
||||
private void PrepareDASFactory()
|
||||
{
|
||||
OnEnterState();
|
||||
if (null != DASFactory)
|
||||
{
|
||||
DASFactory.DetachAllDevices();
|
||||
DASFactory.TDASHostNames = new string[0];
|
||||
DASFactory.SliceDBHostNames = new string[0];
|
||||
}
|
||||
}
|
||||
public override State State => State.Prepare;
|
||||
public override Action OnEntry
|
||||
{
|
||||
get => PrepareDASFactory;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,361 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using DTS.Common.DAS.Concepts;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Base class for all DAS channels.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class DASChannel : IDASChannel, IXmlSerializable // (subset of sensor class)
|
||||
{
|
||||
public DFConstantsAndEnums.ConfigMode ConfigurationMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// whether the channel should be put in Diagnostics mode or not
|
||||
/// </summary>
|
||||
public bool DiagnosticsMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Channel number with respect to it's containing module <see cref="OwningModule"/>
|
||||
/// </summary>
|
||||
public int ModuleChannelNumber { get; set; }
|
||||
|
||||
public int AbsoluteDisplayOrder { get; set; } = 1;
|
||||
|
||||
public double UnitConverision { get; set; } = 1D;
|
||||
|
||||
public bool AtCapacity { get; set; } = false;
|
||||
|
||||
public double CapacityOutputIsBasedOn { get; set; } = 1D;
|
||||
|
||||
public SensorConstants.SensUnits SensitivityUnits { get; set; } =
|
||||
SensorConstants.SensUnits.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// A link back to the Module that contains this channel.
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public DASModule OwningModule { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The "stack channel number" of this channel with respect to the owning
|
||||
/// DAS (0 based).
|
||||
/// </summary>
|
||||
public byte Number
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return OwningModule.OwningDAS.DASInfo.MapModuleArrayIndexAndChannelNum2DASChannel(OwningModule.ModuleArrayIndex, ModuleChannelNumber);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ApplicationException("encountered problem getting " + GetType().FullName + ".Number property value", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Array of (string, byte[]) for EID
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public IEID[] IDs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// time stamp of this event
|
||||
/// </summary>
|
||||
public DateTime EventStartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="bool"/> value indicating whether or not this channel has registered a level trigger.
|
||||
/// </summary>
|
||||
public bool LevelTriggerSeen { get; set; }
|
||||
|
||||
public string IsoChannelName { get; set; }
|
||||
public string ChannelGroupName { get; set; }
|
||||
public string UserCode { get; set; }
|
||||
public string UserChannelName { get; set; }
|
||||
public string LinearSensorCalibration { get; set; }
|
||||
/// <summary>
|
||||
/// the number of samples to qualify over
|
||||
/// </summary>
|
||||
public int QualificationSamples { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// Number of samples that T0 on DASes that did not directly experience the level trigger must be shifted
|
||||
///// to time align with this channel's directly level triggered T0. A null value indicates that this channel
|
||||
///// did not directly receive a level trigger.
|
||||
///// </summary>
|
||||
public int? LevelTriggerT0AdjustmentSamples { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ModuleChannelNumber.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this channel configured? 'Configured' means a sensor is connected and/or there is
|
||||
/// information in the containg device's ConfigData object, put there with a call to
|
||||
/// ConfigureService.Configure(...) in the API.
|
||||
/// </summary>
|
||||
/// <returns>True if it is configured, False otherwise.</returns>
|
||||
public virtual bool IsConfigured()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CTOR to populate a channel's owning module and channel WRT that module.
|
||||
/// </summary>
|
||||
/// <param name="owner">Module that contains this channel.</param>
|
||||
/// <param name="channelNumber">ChannelNumber of this channel WRT owning module.</param>
|
||||
public DASChannel(DASModule owner, int channelNumber)
|
||||
{
|
||||
ConfigurationMode = DFConstantsAndEnums.ConfigMode.Normal;
|
||||
ModuleChannelNumber = channelNumber;
|
||||
OwningModule = owner;
|
||||
IDs = null;
|
||||
EventStartTime = DateTime.Now;
|
||||
DiagnosticsMode = false;
|
||||
}
|
||||
|
||||
public DASChannel()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void WriteElementStart(XmlWriter writer)
|
||||
{
|
||||
writer.WriteStartElement("DASChannel");
|
||||
//writer.WriteStartAttribute("type", "xsi");
|
||||
var tgt = GetType();
|
||||
writer.WriteAttributeString("xsi", "type", null, tgt.Name);
|
||||
}
|
||||
|
||||
public virtual void WriteElementEnd(XmlWriter writer)
|
||||
{
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
public virtual void WriteXmlCRC32(XmlWriter writer)
|
||||
{
|
||||
// ConfigurationMode
|
||||
XMLHelper.PutString(writer, "ConfigurationMode", ConfigurationMode.ToString());
|
||||
|
||||
// ModuleChannelNumber
|
||||
XMLHelper.PutInt(writer, "ModuleChannelNumber", ModuleChannelNumber);
|
||||
XMLHelper.PutInt(writer, "AbsoluteDisplayOrder", AbsoluteDisplayOrder);
|
||||
XMLHelper.PutBool(writer, "DiagnosticsMode", DiagnosticsMode);
|
||||
XMLHelper.PutDouble(writer, "UnitConversion", UnitConverision);
|
||||
// EventStartTime
|
||||
//XMLHelper.PutString(writer, "EventStartTime", EventStartTime.ToString("o", XMLHelper.InvariantCulture));
|
||||
}
|
||||
public virtual void WriteXml(XmlWriter writer)
|
||||
{
|
||||
// ConfigurationMode
|
||||
XMLHelper.PutString(writer, "ConfigurationMode", ConfigurationMode.ToString());
|
||||
|
||||
// ModuleChannelNumber
|
||||
XMLHelper.PutInt(writer, "ModuleChannelNumber", ModuleChannelNumber);
|
||||
|
||||
XMLHelper.PutInt(writer, "AbsoluteDisplayOrder", AbsoluteDisplayOrder);
|
||||
// EventStartTime
|
||||
XMLHelper.PutString(writer, "EventStartTime", EventStartTime.ToString("o", XMLHelper.InvariantCulture));
|
||||
|
||||
//XMLHelper.PutString(writer, "QualificationSamples", QualificationSamples.ToString());
|
||||
XMLHelper.PutInt(writer, "QualificationSamples", QualificationSamples);
|
||||
|
||||
XMLHelper.PutBool(writer, "DiagnosticsMode", DiagnosticsMode);
|
||||
|
||||
XMLHelper.PutDouble(writer, "UnitConversion", UnitConverision);
|
||||
|
||||
XMLHelper.PutBool(writer, "AtCapacity", AtCapacity);
|
||||
|
||||
XMLHelper.PutDouble(writer, "CapacityOutputIsBasedOn", CapacityOutputIsBasedOn);
|
||||
|
||||
XMLHelper.PutString(writer, "SensitivityUnits", SensitivityUnits.ToString());
|
||||
|
||||
XMLHelper.PutString(writer, "IsoChannelName", IsoChannelName);
|
||||
XMLHelper.PutString(writer, "UserCode", UserCode);
|
||||
XMLHelper.PutString(writer, "UserChannelName", UserChannelName);
|
||||
XMLHelper.PutString(writer, "LinearSensorCalibration", LinearSensorCalibration);
|
||||
if (!string.IsNullOrEmpty(UserValue1))
|
||||
{
|
||||
XMLHelper.PutString(writer, "UserValue1", UserValue1);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(UserValue2))
|
||||
{
|
||||
XMLHelper.PutString(writer, "UserValue2", UserValue2);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(UserValue3))
|
||||
{
|
||||
XMLHelper.PutString(writer, "UserValue3", UserValue3);
|
||||
}
|
||||
|
||||
/*XMLHelper.PutInt(writer, "IdType", IdType);*/
|
||||
}
|
||||
private const string CONFIGUARATIONMODE_TAG = "ConfigurationMode";
|
||||
private const string MODULECHANNELNUMBER_TAG = "ModuleChannelNumber";
|
||||
private const string EVENTSTARTTIME_TAG = "EventStartTime";
|
||||
private const string QUALIFICATIONSAMPLES_TAG = "QualificationSamples";
|
||||
private const string DIAGNOSTICSMODE_TAG = "DiagnosticsMode";
|
||||
private const string ABSOLUTEDISPLAYORDER_TAG = "AbsoluteDisplayOrder";
|
||||
private const string UNITCONVERSION_TAG = "UnitConversion";
|
||||
private const string ATCAPACITY_TAG = "AtCapacity";
|
||||
private const string LINEARSENSORCALIBRATION_TAG = "LinearSensorCalibration";
|
||||
private const string USERCHANNELNAME_TAG = "UserChannelName";
|
||||
private const string USERCODE_TAG = "UserCode";
|
||||
private const string ISOCHANNELNAME_TAG = "IsoChannelName";
|
||||
private const string CAPACITYOUTPUTISBASEDON_TAG = "CapacityOutputIsBasedOn";
|
||||
private const string SENSITIVITYUNITS_TAG = "SensitivityUnits";
|
||||
private const string USERVALUE1_TAG = "UserValue1";
|
||||
private const string USERVALUE2_TAG = "UserValue2";
|
||||
private const string USERVALUE3_TAG = "UserValue3";
|
||||
protected virtual void HandleElement(XmlReader reader)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case CONFIGUARATIONMODE_TAG:
|
||||
var confMode = XMLHelper.GetString(reader);
|
||||
ConfigurationMode = (DFConstantsAndEnums.ConfigMode)Enum.Parse(typeof(DFConstantsAndEnums.ConfigMode), confMode);
|
||||
break;
|
||||
case MODULECHANNELNUMBER_TAG:
|
||||
ModuleChannelNumber = XMLHelper.GetInt(reader);
|
||||
break;
|
||||
case EVENTSTARTTIME_TAG:
|
||||
var est = XMLHelper.GetString(reader);
|
||||
EventStartTime = DateTime.Parse(est);
|
||||
break;
|
||||
case QUALIFICATIONSAMPLES_TAG:
|
||||
QualificationSamples = XMLHelper.GetInt(reader);
|
||||
break;
|
||||
case DIAGNOSTICSMODE_TAG:
|
||||
DiagnosticsMode = XMLHelper.GetBool(reader);
|
||||
break;
|
||||
case ABSOLUTEDISPLAYORDER_TAG:
|
||||
try { AbsoluteDisplayOrder = XMLHelper.GetInt(reader); }
|
||||
catch (Exception) { }
|
||||
break;
|
||||
case UNITCONVERSION_TAG:
|
||||
try { UnitConverision = XMLHelper.GetDouble(reader); }
|
||||
catch (Exception) { }
|
||||
break;
|
||||
case ATCAPACITY_TAG:
|
||||
try { AtCapacity = XMLHelper.GetBool(reader); }
|
||||
catch (Exception) { }
|
||||
break;
|
||||
case LINEARSENSORCALIBRATION_TAG:
|
||||
LinearSensorCalibration = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case USERCHANNELNAME_TAG:
|
||||
UserChannelName = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case USERCODE_TAG:
|
||||
UserCode = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case ISOCHANNELNAME_TAG:
|
||||
IsoChannelName = XMLHelper.GetString(reader);
|
||||
break;
|
||||
case CAPACITYOUTPUTISBASEDON_TAG:
|
||||
try { CapacityOutputIsBasedOn = XMLHelper.GetDouble(reader); }
|
||||
catch (Exception) { }
|
||||
break;
|
||||
case SENSITIVITYUNITS_TAG:
|
||||
var su = XMLHelper.GetString(reader);
|
||||
SensitivityUnits = (SensorConstants.SensUnits)Enum.Parse(typeof(SensorConstants.SensUnits), su);
|
||||
break;
|
||||
case USERVALUE1_TAG:
|
||||
try { UserValue1 = XMLHelper.GetString(reader); }
|
||||
catch (Exception) { }
|
||||
break;
|
||||
case USERVALUE2_TAG:
|
||||
try { UserValue2 = XMLHelper.GetString(reader); }
|
||||
catch (Exception) { }
|
||||
break;
|
||||
case USERVALUE3_TAG:
|
||||
try { UserValue3 = XMLHelper.GetString(reader); }
|
||||
catch (Exception) { }
|
||||
break;
|
||||
|
||||
default:
|
||||
// let child handle it
|
||||
return;
|
||||
}
|
||||
}
|
||||
public virtual void ReadXml(XmlReader reader)
|
||||
{
|
||||
// it must be an Element
|
||||
if (reader.NodeType != XmlNodeType.Element)
|
||||
{
|
||||
throw new XmlException("DASChannel.ReadXml: Unknown input: " + reader.NodeType.ToString());
|
||||
}
|
||||
|
||||
// skip our start tag
|
||||
if (reader.Name == "DASChannel")
|
||||
{
|
||||
reader.Read();
|
||||
}
|
||||
|
||||
// try to find our data
|
||||
do
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
HandleElement(reader);
|
||||
}
|
||||
if (!reader.Read())
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (!(reader.Name.Equals("DASChannel") && reader.NodeType == XmlNodeType.EndElement));
|
||||
|
||||
// we're going to end with an EndElement, so clean up
|
||||
if (reader.Name.Equals("DASChannel") && reader.NodeType == XmlNodeType.EndElement)
|
||||
{
|
||||
reader.Read();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns true if the channel is re-programable [can be switched from IEPE to analog]
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool CanReProgram()
|
||||
{
|
||||
if (null == OwningModule) { return false; }
|
||||
if (null == OwningModule.OwningDAS) { return false; }
|
||||
if (null == OwningModule.OwningDAS.DASInfo) { return false; }
|
||||
if (null == OwningModule.OwningDAS.DASInfo.Modules) { return false; }
|
||||
if (0 == OwningModule.OwningDAS.DASInfo.Modules.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return OwningModule.OwningDAS.DASInfo.Modules[0].IsProgrammable;
|
||||
}
|
||||
public XmlSchema GetSchema()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public const int DEFAULT_ID_TYPE = 0;
|
||||
public const int BRIDGE_ID_TYPE = 1;
|
||||
public const int IEPE_ID_TYPE = 2;
|
||||
public const int BRIDGE_G5_ID_TYPE = 3;
|
||||
|
||||
public int IdType { get; set; } = DEFAULT_ID_TYPE;
|
||||
|
||||
public string UserValue1 { get; set; } = "";
|
||||
public string UserValue2 { get; set; } = "";
|
||||
public string UserValue3 { get; set; } = "";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class ArmCheckResults : IArmCheckResults
|
||||
{
|
||||
/// <summary>
|
||||
/// sensor EIDs, key is index of channel, value is an array of ids
|
||||
/// </summary>
|
||||
public Dictionary<int, string[]> SensorIds { get; set; }
|
||||
public Dictionary<int, double> SquibResistances { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// some DAS (TDAS Pro rack) can have multiple battery voltages for modules ...
|
||||
/// </summary>
|
||||
public double?[] BatteryVoltage { get; set; }
|
||||
public double? InputVoltage { get; set; }
|
||||
public bool? StartLineShorted { get; set; }
|
||||
public bool? EventLineShorted { get; set; }
|
||||
public short[] TiltSensorDataPre { get; set; }
|
||||
public double[] TiltDegrees { get; set; }
|
||||
public Dictionary<byte, short[]> IndexedTiltSensorDataPre { get; set; } = new Dictionary<byte, short[]>();
|
||||
public Dictionary<byte, double[]> IndexedTiltDegrees { get; set; } = new Dictionary<byte, double[]>();
|
||||
public float[] TemperaturesPre { get; set; }
|
||||
public double[] Gains { get; set; }
|
||||
public double[] ZeroData { get; set; }
|
||||
public IDictionary<InputClockSource, bool> InputClockLocks { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// This exception gets thrown when you call a service and it's already busy.
|
||||
/// </summary>
|
||||
public class BusyException : Exception
|
||||
{
|
||||
public BusyException(string msg) : base(msg) { }
|
||||
}
|
||||
|
||||
public class TriggerShortedException : Exception
|
||||
{
|
||||
public TriggerShortedException(String msg) : base(msg) { }
|
||||
}
|
||||
public class StartShortedException : Exception
|
||||
{
|
||||
public StartShortedException(String msg) : base(msg) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Representation of an attempt to access a channel's diagnostic information
|
||||
/// when said information isn't available (which can happen, if diagnostics has
|
||||
/// not yet been run on this particular channel this session).
|
||||
/// </summary>
|
||||
public class NoDiagnosticsAvailable : ApplicationException
|
||||
{
|
||||
public NoDiagnosticsAvailable() { }
|
||||
public NoDiagnosticsAvailable(string msg) : base(msg) { }
|
||||
public NoDiagnosticsAvailable(string msg, Exception ex) : base(msg, ex) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Representation of an attempt to access a channel's diagnostic information
|
||||
/// that results in several different diagnostic results (which should never happen,
|
||||
/// but is theoretically supported by the list-y nature of the generic culling
|
||||
/// code).
|
||||
/// </summary>
|
||||
public class TooManyDiagnosticsAvailable : ApplicationException
|
||||
{
|
||||
public TooManyDiagnosticsAvailable() { }
|
||||
public TooManyDiagnosticsAvailable(string msg) : base(msg) { }
|
||||
public TooManyDiagnosticsAvailable(string msg, Exception ex) : base(msg, ex) { }
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,260 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
public class CANModuleConfig : IXmlSerializable
|
||||
{
|
||||
public string SerialNumber { get; set; } = "";
|
||||
public string TestId { get; set; } = "";
|
||||
public string TestDescription { get; set; } = "";
|
||||
|
||||
public DFConstantsAndEnums.RecordingMode RecordingMode { get; set; } = DFConstantsAndEnums.RecordingMode.InvalidArmMode;
|
||||
public float AAFilterRateHz { get; set; } = 0;
|
||||
public double PreTriggerSeconds { get; set; } = 0;
|
||||
public double PostTriggerSeconds { get; set; } = 0;
|
||||
|
||||
private readonly Dictionary<int, DASChannel> _channels = new Dictionary<int, DASChannel>();
|
||||
|
||||
private readonly string _fileName;
|
||||
public string FileName { get { return _fileName; } }
|
||||
|
||||
public string FirmwareVersion { get; set; } = "";
|
||||
public UInt64? MaxEventStorageSpaceInBytes { get; set; } = 0;
|
||||
public int ModuleArrayIndex { get; set; } = 0;
|
||||
|
||||
public CANModuleConfig()
|
||||
{
|
||||
}
|
||||
|
||||
public CANModuleConfig(string fileName)
|
||||
{
|
||||
const string dasConfigs = "DASConfigs";
|
||||
var location = Path.Combine(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), dasConfigs), fileName);
|
||||
_fileName = location;
|
||||
if (File.Exists(_fileName))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (StreamReader sr = new StreamReader(_fileName))
|
||||
{
|
||||
ReadXml(System.Xml.XmlReader.Create(sr));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Problem reading ", _fileName, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void SetChannel(CANInputDASChannel channel)
|
||||
{
|
||||
if (_channels.ContainsKey(channel.ModuleChannelNumber)) { _channels[channel.ModuleChannelNumber] = channel; }
|
||||
else { _channels.Add(channel.ModuleChannelNumber, channel); }
|
||||
}
|
||||
public CANInputDASChannel GetChannel(CANInputDASChannel channel)
|
||||
{
|
||||
if (_channels.ContainsKey(channel.ModuleChannelNumber)) { return _channels[channel.ModuleChannelNumber] as CANInputDASChannel; }
|
||||
else
|
||||
{
|
||||
_channels.Add(channel.ModuleChannelNumber, channel);
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
public XmlSchema GetSchema()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
//
|
||||
// Summary:
|
||||
// Generates an object from its XML representation.
|
||||
//
|
||||
// Parameters:
|
||||
// reader:
|
||||
// The System.Xml.XmlReader stream from which the object is deserialized.
|
||||
public void ReadXml(XmlReader reader)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
reader.ReadStartElement("CANModule");
|
||||
reader.ReadStartElement("SerialNumber");
|
||||
SerialNumber = reader.ReadString();
|
||||
reader.ReadEndElement();
|
||||
reader.ReadStartElement("TestId");
|
||||
TestId = reader.ReadString();
|
||||
reader.ReadEndElement();
|
||||
reader.ReadStartElement("TestDescription");
|
||||
TestDescription = reader.ReadString();
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("RecordingMode");
|
||||
string recordingMode = reader.ReadString();
|
||||
try
|
||||
{
|
||||
RecordingMode = (DFConstantsAndEnums.RecordingMode)Enum.Parse(typeof(DFConstantsAndEnums.RecordingMode), recordingMode);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to load RecordingMode ", recordingMode, ex); }
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("AAFilterRateHz");
|
||||
string aaFilterRateHz = reader.ReadString();
|
||||
try
|
||||
{
|
||||
AAFilterRateHz = (float)Convert.ToDouble(aaFilterRateHz);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to load AAFilterRateHz ", aaFilterRateHz, ex); }
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("PreTriggerSeconds");
|
||||
string preTriggerSeconds = reader.ReadString();
|
||||
try
|
||||
{
|
||||
PreTriggerSeconds = Convert.ToDouble(preTriggerSeconds);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to load PreTriggerSeconds ", preTriggerSeconds, ex); }
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("PostTriggerSeconds");
|
||||
string postTriggerSeconds = reader.ReadString();
|
||||
try
|
||||
{
|
||||
PostTriggerSeconds = Convert.ToDouble(postTriggerSeconds);
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log("Failed to load PostTriggerSeconds ", postTriggerSeconds, ex); }
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("FirmwareVersion");
|
||||
FirmwareVersion = reader.ReadString();
|
||||
reader.ReadEndElement();
|
||||
|
||||
reader.ReadStartElement("MaxEventStorageSpaceInBytes");
|
||||
string maxEventStorageSpaceInBytes = reader.ReadString();
|
||||
|
||||
double d;
|
||||
if (double.TryParse(maxEventStorageSpaceInBytes, out d))
|
||||
{
|
||||
if (d >= 0 && d < ulong.MaxValue) { MaxEventStorageSpaceInBytes = Convert.ToUInt64(d); }
|
||||
else { APILogger.Log("Failed to load MaxEventStorageSpaceInBytes ", maxEventStorageSpaceInBytes); }
|
||||
}
|
||||
else { APILogger.Log("Failed to load MaxEventStorageSpaceInBytes ", maxEventStorageSpaceInBytes); }
|
||||
|
||||
reader.ReadEndElement();
|
||||
ReadModuleArray(reader);
|
||||
|
||||
reader.ReadStartElement("Channels");
|
||||
|
||||
while (reader.MoveToContent() == XmlNodeType.Element)
|
||||
{
|
||||
CANInputDASChannel cic = new CANInputDASChannel();
|
||||
cic.ReadXml(reader);
|
||||
SetChannel(cic);
|
||||
}
|
||||
|
||||
reader.ReadEndElement();
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
//FB 45086 sonarqube - reduce cyclomatic complexity
|
||||
private void ReadModuleArray(XmlReader reader)
|
||||
{
|
||||
try
|
||||
{
|
||||
reader.ReadStartElement("ModuleArrayIndex");
|
||||
string moduleArrayIndex = reader.ReadString();
|
||||
|
||||
int m;
|
||||
if (int.TryParse(moduleArrayIndex, out m))
|
||||
{
|
||||
if (m >= 0 && m < int.MaxValue) { ModuleArrayIndex = Convert.ToInt32(m); }
|
||||
else { APILogger.Log("Failed to load ModuleArrayIndex ", moduleArrayIndex); }
|
||||
}
|
||||
else { APILogger.Log("Failed to load ModuleArrayIndex ", moduleArrayIndex); }
|
||||
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
catch
|
||||
{
|
||||
//This must be an old config file
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Summary:
|
||||
// Converts an object into its XML representation.
|
||||
//
|
||||
// Parameters:
|
||||
// writer:
|
||||
// The System.Xml.XmlWriter stream to which the object is serialized.
|
||||
public void WriteXml(XmlWriter writer)
|
||||
{
|
||||
//writer.WriteStartElement ( attributeExtractor.ExtractAttachedAttributeFromObject ( this
|
||||
writer.WriteStartElement("CANModule");
|
||||
writer.WriteStartElement("SerialNumber");
|
||||
writer.WriteString(SerialNumber);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteStartElement("TestId");
|
||||
writer.WriteString(TestId);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteStartElement("TestDescription");
|
||||
writer.WriteString(TestDescription);
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("RecordingMode");
|
||||
writer.WriteString(RecordingMode.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("AAFilterRateHz");
|
||||
writer.WriteString(AAFilterRateHz.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("PreTriggerSeconds");
|
||||
writer.WriteString(PreTriggerSeconds.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("PostTriggerSeconds");
|
||||
writer.WriteString(PostTriggerSeconds.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("FirmwareVersion");
|
||||
writer.WriteString(FirmwareVersion);
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("MaxEventStorageSpaceInBytes");
|
||||
writer.WriteString(MaxEventStorageSpaceInBytes.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("ModuleArrayIndex");
|
||||
writer.WriteString(ModuleArrayIndex.ToString());
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteStartElement("Channels");
|
||||
writer.Flush();
|
||||
|
||||
foreach (DASChannel channel in _channels.Values)
|
||||
{
|
||||
channel.WriteElementStart(writer);
|
||||
channel.WriteXml(writer);
|
||||
channel.WriteElementEnd(writer);
|
||||
writer.Flush();
|
||||
}
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement();
|
||||
writer.Flush();
|
||||
}
|
||||
public virtual void WriteElementStart(XmlWriter writer)
|
||||
{
|
||||
writer.WriteStartElement("CANModule");
|
||||
var tgt = GetType();
|
||||
writer.WriteAttributeString("xsi", "type", null, tgt.Name);
|
||||
}
|
||||
|
||||
public virtual void WriteElementEnd(XmlWriter writer)
|
||||
{
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using DTS.Common.Interface.Channels;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine.StatusAndParameters.Configure
|
||||
{
|
||||
/// <summary>
|
||||
/// helper class for use when resolving channels
|
||||
/// </summary>
|
||||
internal class GroupChannelWithMeta
|
||||
{
|
||||
public bool ChannelConflict { get; set; }
|
||||
public IGroupChannel ConflictingChannel { get; set; }
|
||||
public IGroupChannel Channel { get; set; }
|
||||
public IGroup Group { get; set; }
|
||||
public bool MissingID { get; set; }
|
||||
public bool MissingSensor { get; set; }
|
||||
public bool EIDOutOfPlace { get; set; }
|
||||
public bool HWNotFound { get; set; }
|
||||
public bool HWChannelIncompatible { get; set; }
|
||||
public IDASChannel DASChannel { get; set; }
|
||||
public bool AssignedByEID { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class DownloadStart : DASStateSelector
|
||||
{
|
||||
private void Start()
|
||||
{
|
||||
OnEnterState();
|
||||
Status.DownloadStatusInfo.Download();
|
||||
}
|
||||
|
||||
private bool CanTransitToPrepare()
|
||||
{
|
||||
return Status.DownloadParams.ProceedWhenDone && (Status.DownloadStatusInfo.AllDASFinished || !Status.DownloadParams.RequireAllDASFinish);
|
||||
}
|
||||
|
||||
public override IDASState StateSelector()
|
||||
{
|
||||
if (CanTransitToPrepare())
|
||||
{
|
||||
return States.Instance.Prepare;
|
||||
}
|
||||
return States.Instance.Download;
|
||||
}
|
||||
|
||||
public override Action OnEntry
|
||||
{
|
||||
get => Start;
|
||||
}
|
||||
|
||||
public override State State => State.DownloadStart;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class HardwareDiscoveryStart : DASStateSelector
|
||||
{
|
||||
private void Start()
|
||||
{
|
||||
OnEnterState();
|
||||
if (null != Status.HardwareDiscoveryParams.RequeryDevice)
|
||||
{
|
||||
Status.HardwareDiscoveryStatusInfo.RequeryDevice();
|
||||
}
|
||||
else { Status.HardwareDiscoveryStatusInfo.Ping(); }
|
||||
}
|
||||
|
||||
private bool CanTransitToDownload()
|
||||
{
|
||||
return CanTransitToConfigure() && Status.HardwareDiscoveryParams.GoToDownload;
|
||||
}
|
||||
|
||||
private bool CanTransitToConfigure()
|
||||
{
|
||||
return Status.HardwareDiscoveryParams.ProceedWhenDone && (Status.HardwareDiscoveryStatusInfo.AllDASFound || !Status.HardwareDiscoveryParams.RequireAllDASFound);
|
||||
}
|
||||
private bool CanTransitToArm()
|
||||
{
|
||||
return Status.HardwareDiscoveryParams.ProceedWhenDone && Status.HardwareDiscoveryStatusInfo.SomeUnitsInArmState;
|
||||
}
|
||||
|
||||
public override IDASState StateSelector()
|
||||
{
|
||||
if (CanTransitToDownload())
|
||||
return States.Instance.Download;
|
||||
|
||||
if (CanTransitToConfigure())
|
||||
return States.Instance.Configure;
|
||||
|
||||
if (CanTransitToArm())
|
||||
return States.Instance.Arm;
|
||||
|
||||
return States.Instance.HardwareDiscovery;
|
||||
}
|
||||
public override Action OnEntry
|
||||
{
|
||||
get => Start;
|
||||
}
|
||||
|
||||
public override State State => State.HardwareDiscoveryStart;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user