init
This commit is contained in:
1401
DataPRO/IService/Classes/Channels/AnalogInputDASChannel.cs
Normal file
1401
DataPRO/IService/Classes/Channels/AnalogInputDASChannel.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
21
DataPRO/IService/Classes/Channels/AnalogOutputDASChannel.cs
Normal file
21
DataPRO/IService/Classes/Channels/AnalogOutputDASChannel.cs
Normal file
@@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
122
DataPRO/IService/Classes/Channels/CANInputDASChannel.cs
Normal file
122
DataPRO/IService/Classes/Channels/CANInputDASChannel.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
377
DataPRO/IService/Classes/Channels/DASChannel.cs
Normal file
377
DataPRO/IService/Classes/Channels/DASChannel.cs
Normal file
@@ -0,0 +1,377 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.DASFactory.Config;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Base class for all DAS channels.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class DASChannel : IDASChannel, IXmlSerializable // (subset of sensor class)
|
||||
{
|
||||
|
||||
public string SetupEID { get; set; } = string.Empty;
|
||||
public string DataCollectionEID { get; set; } = string.Empty;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(SetupEID))
|
||||
{
|
||||
XMLHelper.PutString(writer, SETUPEID_TAG, SetupEID);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(DataCollectionEID))
|
||||
{
|
||||
XMLHelper.PutString(writer, DATACOLLECTIONEID_TAG, DataCollectionEID);
|
||||
}
|
||||
}
|
||||
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";
|
||||
private const string SETUPEID_TAG = "SetupEID";
|
||||
private const string DATACOLLECTIONEID_TAG = "DataCollectionEID";
|
||||
|
||||
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:
|
||||
AbsoluteDisplayOrder = XMLHelper.TryGetInt(reader, 1);
|
||||
break;
|
||||
case UNITCONVERSION_TAG:
|
||||
UnitConverision = XMLHelper.TryGetDouble(reader, 1D);
|
||||
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:
|
||||
CapacityOutputIsBasedOn = XMLHelper.TryGetDouble(reader, 1D);
|
||||
break;
|
||||
case SENSITIVITYUNITS_TAG:
|
||||
var su = XMLHelper.GetString(reader);
|
||||
SensitivityUnits = (SensorConstants.SensUnits)Enum.Parse(typeof(SensorConstants.SensUnits), su);
|
||||
break;
|
||||
case USERVALUE1_TAG:
|
||||
UserValue1 = XMLHelper.TryGetString(reader, "");
|
||||
break;
|
||||
case USERVALUE2_TAG:
|
||||
UserValue2 = XMLHelper.TryGetString(reader, "");
|
||||
break;
|
||||
case USERVALUE3_TAG:
|
||||
UserValue3 = XMLHelper.TryGetString(reader, "");
|
||||
break;
|
||||
case SETUPEID_TAG:
|
||||
try { SetupEID = XMLHelper.GetString(reader); }
|
||||
catch(Exception ex) { APILogger.Log(ex); }
|
||||
break;
|
||||
case DATACOLLECTIONEID_TAG:
|
||||
try { DataCollectionEID = XMLHelper.GetString(reader); }
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
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; } = "";
|
||||
|
||||
}
|
||||
}
|
||||
21
DataPRO/IService/Classes/Channels/DigitalOutputDASChannel.cs
Normal file
21
DataPRO/IService/Classes/Channels/DigitalOutputDASChannel.cs
Normal file
@@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
27
DataPRO/IService/Classes/Channels/InputDASChannel.cs
Normal file
27
DataPRO/IService/Classes/Channels/InputDASChannel.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Base class for input channels.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class InputDASChannel : DASChannel
|
||||
{
|
||||
/// <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 InputDASChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
}
|
||||
|
||||
public InputDASChannel()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
21
DataPRO/IService/Classes/Channels/OutputDASChannel.cs
Normal file
21
DataPRO/IService/Classes/Channels/OutputDASChannel.cs
Normal file
@@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
360
DataPRO/IService/Classes/Channels/OutputSquibChannel.cs
Normal file
360
DataPRO/IService/Classes/Channels/OutputSquibChannel.cs
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
111
DataPRO/IService/Classes/Channels/OutputTOMDigitalChannel.cs
Normal file
111
DataPRO/IService/Classes/Channels/OutputTOMDigitalChannel.cs
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
87
DataPRO/IService/Classes/Channels/StreamInputDASChannel.cs
Normal file
87
DataPRO/IService/Classes/Channels/StreamInputDASChannel.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.DASLib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for storing/applying Streaming output settings as a channel
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class StreamInputDASChannel : 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 StreamInputDASChannel(DASModule owner, int channelNumber)
|
||||
: base(owner, channelNumber)
|
||||
{
|
||||
}
|
||||
|
||||
public StreamInputDASChannel()
|
||||
{
|
||||
}
|
||||
/// <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 UDPAddress { get; set; } = string.Empty;
|
||||
|
||||
/// <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, "UDPAddress", UDPAddress.ToString());
|
||||
|
||||
}
|
||||
private const string SERIALNUMBER_TAG = "SerialNumber";
|
||||
private const string HARDWARECHANNELNAME_TAG = "HardwareChannelName";
|
||||
private const string UDPADDRESS_TAG = "UDPAddress";
|
||||
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 UDPADDRESS_TAG:
|
||||
UDPAddress = XMLHelper.GetString(reader);
|
||||
break;
|
||||
default:
|
||||
// let child handle it
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
130
DataPRO/IService/Classes/Channels/StreamOutputDASChannel.cs
Normal file
130
DataPRO/IService/Classes/Channels/StreamOutputDASChannel.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
73
DataPRO/IService/Classes/Channels/TimestampDASChannel.cs
Normal file
73
DataPRO/IService/Classes/Channels/TimestampDASChannel.cs
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
144
DataPRO/IService/Classes/Channels/UARTInputDASChannel.cs
Normal file
144
DataPRO/IService/Classes/Channels/UARTInputDASChannel.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user