init
This commit is contained in:
@@ -0,0 +1,731 @@
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.Interface.Sensors.SoftwareFilters;
|
||||
using DTS.Common.Interface.Tags;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Data;
|
||||
using System.Data.SqlTypes;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
/// <summary>
|
||||
/// represents a record of an analog sensor in the db
|
||||
/// <inheritdoc cref="IAnalogDbRecord"/>
|
||||
/// </summary>
|
||||
public class AnalogDbRecord : TagAwareBase, IAnalogDbRecord
|
||||
{
|
||||
public override TagTypes TagType => TagTypes.SensorModels;
|
||||
protected int _id = -1;
|
||||
/// <summary>
|
||||
/// the database id of the sensor
|
||||
/// </summary>
|
||||
[Key]
|
||||
public int Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value, "Id");
|
||||
}
|
||||
protected string _serialNumber = "";
|
||||
/// <summary>
|
||||
/// Serial number of sensor
|
||||
/// [required to be unique]
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string SerialNumber
|
||||
{
|
||||
get => _serialNumber;
|
||||
set => SetProperty(ref _serialNumber, value, "SerialNumber");
|
||||
}
|
||||
protected short _axisNumber = 0;
|
||||
/// <summary>
|
||||
/// deprecated
|
||||
/// which axis the record is for when the sensor is multi-axis
|
||||
/// </summary>
|
||||
public short AxisNumber
|
||||
{
|
||||
get => _axisNumber;
|
||||
set => SetProperty(ref _axisNumber, value, "AxisNumber");
|
||||
}
|
||||
|
||||
protected short _bridgeLegMode;
|
||||
/// <summary>
|
||||
/// deprecated
|
||||
/// </summary>
|
||||
public short BridgeLegMode
|
||||
{
|
||||
get => _bridgeLegMode;
|
||||
set => SetProperty(ref _bridgeLegMode, value, "BridgeLegMode");
|
||||
}
|
||||
protected double _bridgeResistance = 350D;
|
||||
/// <summary>
|
||||
/// the expected resistance in Ohms if applicable for the sensor
|
||||
/// </summary>
|
||||
public double BridgeResistance
|
||||
{
|
||||
get => _bridgeResistance;
|
||||
set => SetProperty(ref _bridgeResistance, value, "BridgeResistance");
|
||||
}
|
||||
|
||||
protected SensorConstants.BridgeType _bridge = SensorConstants.BridgeType.FullBridge;
|
||||
/// <summary>
|
||||
/// the type of bridge or sensor
|
||||
/// [DO NOT USE BITMASKED VALUE WHEN READING/WRITING TO DB]
|
||||
/// </summary>
|
||||
public SensorConstants.BridgeType Bridge
|
||||
{
|
||||
get => _bridge;
|
||||
set => SetProperty(ref _bridge, value, "Bridge");
|
||||
}
|
||||
protected void SetBridge(SensorConstants.BridgeType bridge)
|
||||
{
|
||||
_bridge = bridge;
|
||||
}
|
||||
protected bool _broken = false;
|
||||
/// <summary>
|
||||
/// Whether the sensor has been marked as broken by a user
|
||||
/// </summary>
|
||||
public bool Broken
|
||||
{
|
||||
get => _broken;
|
||||
set => SetProperty(ref _broken, value, "Broken");
|
||||
}
|
||||
protected bool _bypassFilter = false;
|
||||
/// <summary>
|
||||
/// whether the sensor has it's own filtering or should otherwise bypass
|
||||
/// hardware filters when collecting data
|
||||
/// (not supported on all hardware)
|
||||
/// </summary>
|
||||
public bool BypassFilter
|
||||
{
|
||||
get => _bypassFilter;
|
||||
set => SetProperty(ref _bypassFilter, value, "BypassFilter");
|
||||
}
|
||||
protected bool _calibrationSignal;
|
||||
/// <summary>
|
||||
/// deprecated?
|
||||
/// </summary>
|
||||
public bool CalibrationSignal
|
||||
{
|
||||
get => _calibrationSignal;
|
||||
set => SetProperty(ref _calibrationSignal, value, "CalibrationSignal");
|
||||
}
|
||||
protected int _calInterval = 365;
|
||||
/// <summary>
|
||||
/// calibration interval in days, used in determining when sensor is out of cal
|
||||
/// </summary>
|
||||
public int CalInterval
|
||||
{
|
||||
get => _calInterval;
|
||||
set => SetProperty(ref _calInterval, value, "CalInterval");
|
||||
}
|
||||
protected double _capacity = 2400D;
|
||||
/// <summary>
|
||||
/// capacity of the sensor in EU
|
||||
/// </summary>
|
||||
public double Capacity
|
||||
{
|
||||
get => _capacity;
|
||||
set => SetProperty(ref _capacity, value, "Capacity");
|
||||
}
|
||||
protected bool _checkOffset = true;
|
||||
/// <summary>
|
||||
/// Whether to check the sensor output in mV against thresholds in diagnostics
|
||||
/// </summary>
|
||||
public bool CheckOffset
|
||||
{
|
||||
get => _checkOffset;
|
||||
set => SetProperty(ref _checkOffset, value, "CheckOffset");
|
||||
}
|
||||
protected string _comment = "";
|
||||
/// <summary>
|
||||
/// user supplied descriptive comment on sensor
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Comment
|
||||
{
|
||||
get => _comment;
|
||||
set => SetProperty(ref _comment, value, "Comment");
|
||||
}
|
||||
protected SensorConstants.CouplingModes _couplingMode = SensorConstants.CouplingModes.AC;
|
||||
/// <summary>
|
||||
/// IEPE coupling mode to use for data collection if applicable
|
||||
/// </summary>
|
||||
public SensorConstants.CouplingModes CouplingMode
|
||||
{
|
||||
get => _couplingMode;
|
||||
set => SetProperty(ref _couplingMode, value, "CouplingMode");
|
||||
}
|
||||
protected DateTime _created;
|
||||
/// <summary>
|
||||
/// date sensor record was created (if available)
|
||||
/// </summary>
|
||||
[Column(TypeName = "datetime")]
|
||||
public DateTime Created
|
||||
{
|
||||
get => _created;
|
||||
set => SetProperty(ref _created, value, "Created");
|
||||
}
|
||||
protected bool _diagnosticsMode = false;
|
||||
/// <summary>
|
||||
/// Whether this sensor should only record internal resistance and record no external signal
|
||||
/// [generally only useful for testing purposes]
|
||||
/// </summary>
|
||||
public bool DiagnosticsMode
|
||||
{
|
||||
get => _diagnosticsMode;
|
||||
set => SetProperty(ref _diagnosticsMode, value, "DiagnosticsMode");
|
||||
}
|
||||
|
||||
protected string _displayUnit = "";
|
||||
/// <summary>
|
||||
/// engineering units collected data should be displayed in
|
||||
/// note that calibration records are also tied against a specific engineering unit that should be used
|
||||
/// the sensor db value is not used
|
||||
/// </summary>
|
||||
public string DisplayUnit
|
||||
{
|
||||
get => _displayUnit;
|
||||
set => SetProperty(ref _displayUnit, value, "DisplayUnit");
|
||||
}
|
||||
protected bool _doNotUse = false;
|
||||
/// <summary>
|
||||
/// whether this sensor has been marked not to be used by user
|
||||
/// </summary>
|
||||
public bool DoNotUse
|
||||
{
|
||||
get => _doNotUse;
|
||||
set => SetProperty(ref _doNotUse, value, "DoNotUse");
|
||||
}
|
||||
protected string _eId = "";
|
||||
/// <summary>
|
||||
/// Electronic Identification tag
|
||||
/// [DALLAS or TEDS ID TAG]
|
||||
/// if present required to be unique
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Column("eId")]
|
||||
[StringLength(50)]
|
||||
public string EId
|
||||
{
|
||||
get => _eId;
|
||||
set => SetProperty(ref _eId, value, "EId");
|
||||
}
|
||||
protected double _externalShuntResistance;
|
||||
/// <summary>
|
||||
/// TDAS supports external resistance when measuring shunt resistance
|
||||
/// this is the value of external resistance applied
|
||||
/// </summary>
|
||||
public double ExternalShuntResistance
|
||||
{
|
||||
get => _externalShuntResistance;
|
||||
set => SetProperty(ref _externalShuntResistance, value, "ExternalShuntResistance");
|
||||
}
|
||||
|
||||
private IFilterClass _filter= new FilterClass(FilterClassType.CFC1000);
|
||||
/// <summary>
|
||||
/// The default software filter class to apply to data channel when viewing
|
||||
/// filtered EU data
|
||||
/// </summary>
|
||||
public IFilterClass Filter
|
||||
{
|
||||
get => _filter;
|
||||
set => SetProperty(ref _filter, value, "Filter");
|
||||
}
|
||||
private double? _initialEU;
|
||||
/// <summary>
|
||||
/// Amount of EU to add in when EU is calculated
|
||||
/// Used to offset EU readings by a specific amount
|
||||
/// Note that analog sensor calibration records
|
||||
/// can contain a more sophisticated EU offset
|
||||
/// </summary>
|
||||
[Column("InitialEU")]
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public double? InitialEu
|
||||
{
|
||||
get => _initialEU;
|
||||
set => SetProperty(ref _initialEU, value, "InitialEu");
|
||||
}
|
||||
protected double _internalShuntResistance;
|
||||
/// <summary>
|
||||
/// TDAS supports performing external and internal resistance when measuring shunt resistance
|
||||
/// This is the value to use when internal shunt resistance is used
|
||||
/// </summary>
|
||||
public double InternalShuntResistance
|
||||
{
|
||||
get => _internalShuntResistance;
|
||||
set => SetProperty(ref _internalShuntResistance, value, "InternalShuntResistance");
|
||||
}
|
||||
protected bool _invert = false;
|
||||
/// <summary>
|
||||
/// whether output of the sensor in EU should be inverted or not
|
||||
/// </summary>
|
||||
public bool Invert
|
||||
{
|
||||
get => _invert;
|
||||
set => SetProperty(ref _invert, value, "Invert");
|
||||
}
|
||||
private string _isoChannelName = string.Empty;
|
||||
/// <summary>
|
||||
/// ISO 13499 channel name to apply to a data channel when a data channel is
|
||||
/// created using the sensor
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(255)]
|
||||
public string ISOChannelName
|
||||
{
|
||||
get => _isoChannelName;
|
||||
set => SetProperty(ref _isoChannelName, value, "ISOChannelName");
|
||||
}
|
||||
private string _isoCode = string.Empty;
|
||||
/// <summary>
|
||||
/// ISO 13499 code to apply to a data channel when a data channel is created
|
||||
/// using the sensor
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string ISOCode
|
||||
{
|
||||
get => _isoCode;
|
||||
set => SetProperty(ref _isoCode, value, "ISOCode");
|
||||
}
|
||||
private DateTime _lastModified = (DateTime)SqlDateTime.MinValue;
|
||||
/// <summary>
|
||||
/// when the sensor was last modified
|
||||
/// </summary>
|
||||
[Column(TypeName = "datetime")]
|
||||
public DateTime LastModified
|
||||
{
|
||||
get => _lastModified;
|
||||
set => SetProperty(ref _lastModified, value, "LastModified");
|
||||
}
|
||||
protected bool _localOnly = false;
|
||||
/// <summary>
|
||||
/// deprecated, used to determine which sensors should not propagate up to central database
|
||||
/// </summary>
|
||||
public bool LocalOnly
|
||||
{
|
||||
get => _localOnly;
|
||||
set => SetProperty(ref _localOnly, value, "LocalOnly");
|
||||
}
|
||||
protected string _manufacturer = "";
|
||||
/// <summary>
|
||||
/// Maker of sensor
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string Manufacturer
|
||||
{
|
||||
get => _manufacturer;
|
||||
set => SetProperty(ref _manufacturer, value, "Manufacturer");
|
||||
}
|
||||
protected string _model = "";
|
||||
/// <summary>
|
||||
/// model of sensor
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string Model
|
||||
{
|
||||
get => _model;
|
||||
set => SetProperty(ref _model, value, "Model");
|
||||
}
|
||||
private string _modifiedBy = "";
|
||||
/// <summary>
|
||||
/// who last modified the sensor record
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string ModifiedBy
|
||||
{
|
||||
get => _modifiedBy;
|
||||
set => SetProperty(ref _modifiedBy, value, "ModifiedBy");
|
||||
}
|
||||
private short _numberOfAxes = 1;
|
||||
/// <summary>
|
||||
/// deprecated/reserved
|
||||
/// number of axes associated with this serial number
|
||||
/// </summary>
|
||||
public short NumberOfAxes
|
||||
{
|
||||
get => _numberOfAxes;
|
||||
set => SetProperty(ref _numberOfAxes, value, "NumberOfAxes");
|
||||
}
|
||||
protected double _offsetToleranceHigh = SensorConstants.DefaultBridgeOffsetMVTolHigh;
|
||||
/// <summary>
|
||||
/// allowable tolerance in mV on the high side for an idle reading of sensor
|
||||
/// used to determine if the sensor output is too high in diagnostics
|
||||
/// </summary>
|
||||
public double OffsetToleranceHigh
|
||||
{
|
||||
get => _offsetToleranceHigh;
|
||||
set => SetProperty(ref _offsetToleranceHigh, value, "OffsetToleranceHigh");
|
||||
}
|
||||
protected double _offsetToleranceLow = SensorConstants.DefaultBridgeOffsetMVTolLow;
|
||||
/// <summary>
|
||||
/// allowable tolerance in mV on the low side for an idle reading of sensor
|
||||
/// used to determine if the sensor output is too low in diagnostics
|
||||
/// </summary>
|
||||
public double OffsetToleranceLow
|
||||
{
|
||||
get => _offsetToleranceLow;
|
||||
set => SetProperty(ref _offsetToleranceLow, value, "OffsetToleranceLow");
|
||||
}
|
||||
private double _rangeMedium;
|
||||
/// <summary>
|
||||
/// typical medium range for sensor in applications
|
||||
/// </summary>
|
||||
public double RangeMedium
|
||||
{
|
||||
get => 0 == _rangeMedium ? Capacity : _rangeMedium;
|
||||
set => SetProperty(ref _rangeMedium, value, "RangeMedium");
|
||||
}
|
||||
private double _rangeHigh;
|
||||
/// <summary>
|
||||
/// typical high range for sensor in applications
|
||||
/// </summary>
|
||||
public double RangeHigh
|
||||
{
|
||||
get => 0 == _rangeHigh ? Capacity : _rangeHigh;
|
||||
set => SetProperty(ref _rangeHigh, value, "RangeHigh");
|
||||
}
|
||||
private double _rangeLow;
|
||||
/// <summary>
|
||||
/// typical low range for sensor in applications
|
||||
/// </summary>
|
||||
public double RangeLow
|
||||
{
|
||||
get => 0 == _rangeLow ? Capacity : _rangeLow;
|
||||
set => SetProperty(ref _rangeLow, value, "RangeLow");
|
||||
}
|
||||
protected int _sensorCategory;
|
||||
/// <summary>
|
||||
/// The type of sensor
|
||||
/// Deprecated, remains for TDC purposes
|
||||
/// Normal = 0,
|
||||
/// POT = 1,
|
||||
/// IRTracc = 2,
|
||||
/// Polynomial = 3
|
||||
/// </summary>
|
||||
public int SensorCategory
|
||||
{
|
||||
get => _sensorCategory;
|
||||
set => SetProperty(ref _sensorCategory, value, "SensorCategory");
|
||||
}
|
||||
private int _sensorModelId;
|
||||
/// <summary>
|
||||
/// the database id of the sensor model, if applicable
|
||||
/// </summary>
|
||||
public int SensorModelId
|
||||
{
|
||||
get => _sensorModelId;
|
||||
set => SetProperty(ref _sensorModelId, value, "SensorModelId");
|
||||
}
|
||||
private const short SHUNT_MODE_EMULATION = 1;
|
||||
protected short _shunt = SHUNT_MODE_EMULATION;
|
||||
/// <summary>
|
||||
/// The type of shunt used for measuring shunt results
|
||||
/// note all SLICE hardware only supports emulation (or none)
|
||||
/// None = 0,
|
||||
/// Emulation = 1,
|
||||
/// Internal = 2,
|
||||
/// External = 3
|
||||
/// </summary>
|
||||
public short Shunt
|
||||
{
|
||||
get => _shunt;
|
||||
set => SetProperty(ref _shunt, value, "Shunt");
|
||||
}
|
||||
protected SensorStatus _status = SensorStatus.Available;
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
/// <summary>
|
||||
/// reserved/not in use
|
||||
/// </summary>
|
||||
public SensorStatus Status
|
||||
{
|
||||
get => _status;
|
||||
set => SetProperty(ref _status, value, "Status");
|
||||
}
|
||||
protected ExcitationVoltageOptions.ExcitationVoltageOption[] _supportedExcitation = new[] { ExcitationVoltageOptions.ExcitationVoltageOption.Volt5 };
|
||||
/// <summary>
|
||||
/// Excitation voltages supported by the sensor
|
||||
/// used to prevent the sensor from being used in a situation that might damaged it
|
||||
/// (say a 2V sensor being fed 10V excitation)
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public ExcitationVoltageOptions.ExcitationVoltageOption[] SupportedExcitation
|
||||
{
|
||||
get => _supportedExcitation;
|
||||
set => SetProperty(ref _supportedExcitation, value, "SupportedExcitation");
|
||||
}
|
||||
protected long _timesUsed;
|
||||
/// <summary>
|
||||
/// Reserved/Not used
|
||||
/// </summary>
|
||||
public long TimesUsed
|
||||
{
|
||||
get => _timesUsed;
|
||||
set => SetProperty(ref _timesUsed, value, "TimesUsed");
|
||||
}
|
||||
protected bool _uniPolar = false;
|
||||
/// <summary>
|
||||
/// flag indicating that the sensor should be interpreted as 0-n rather than -x<0<x
|
||||
/// </summary>
|
||||
public bool UniPolar
|
||||
{
|
||||
get => _uniPolar;
|
||||
set => SetProperty(ref _uniPolar, value, "UniPolar");
|
||||
}
|
||||
private string _userChannelName = string.Empty;
|
||||
/// <summary>
|
||||
/// User channel name to apply when sensor is applied to a blank channel
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(255)]
|
||||
public string UserChannelName
|
||||
{
|
||||
get => _userChannelName;
|
||||
set => SetProperty(ref _userChannelName, value, "UserChannelName");
|
||||
}
|
||||
private string _userCode = string.Empty;
|
||||
/// <summary>
|
||||
/// User channel code to apply when sensor is applied to a blank channel
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string UserCode
|
||||
{
|
||||
get => _userCode;
|
||||
set => SetProperty(ref _userCode, value, "UserCode");
|
||||
}
|
||||
protected string _userSerialNumber = string.Empty;
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string UserSerialNumber
|
||||
{
|
||||
get => _userSerialNumber;
|
||||
set => SetProperty(ref _userSerialNumber, value, "UserSerialNumber");
|
||||
}
|
||||
|
||||
protected string _userValue1 = string.Empty;
|
||||
/// <summary>
|
||||
/// user supplied string
|
||||
/// travels with the sensor to data channels when
|
||||
/// data is recorded with the sensor
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string UserValue1
|
||||
{
|
||||
get => _userValue1;
|
||||
set => SetProperty(ref _userValue1, value, "UserValue1");
|
||||
}
|
||||
protected string _userValue2 = string.Empty;
|
||||
/// <summary>
|
||||
/// user supplied string
|
||||
/// travels with the sensor to data channels when
|
||||
/// data is recorded with the sensor
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string UserValue2
|
||||
{
|
||||
get => _userValue2;
|
||||
set => SetProperty(ref _userValue2, value, "UserValue2");
|
||||
}
|
||||
protected string _userValue3 = string.Empty;
|
||||
/// <summary>
|
||||
/// user supplied string
|
||||
/// travels with the sensor to data channels when
|
||||
/// data is recorded with the sensor
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string UserValue3
|
||||
{
|
||||
get => _userValue3;
|
||||
set => SetProperty(ref _userValue3, value, "UserValue3");
|
||||
}
|
||||
private int _version = 1;
|
||||
/// <summary>
|
||||
/// deprecated
|
||||
/// </summary>
|
||||
public int Version
|
||||
{
|
||||
get => _version;
|
||||
set => SetProperty(ref _version, value, "Version");
|
||||
}
|
||||
private DateTime? _firstUseDate;
|
||||
[Column(TypeName = "datetime")]
|
||||
/// <summary>
|
||||
/// Date of first destructive use since sensor was calibrated,
|
||||
/// only valid when using latest calibration
|
||||
/// null indicates not set
|
||||
/// </summary>
|
||||
public DateTime? FirstUseDate
|
||||
{
|
||||
get => _firstUseDate;
|
||||
set => SetProperty(ref _firstUseDate, value, "FirstUseDate");
|
||||
}
|
||||
private int? _latestCalibrationId;
|
||||
/// <summary>
|
||||
/// deprecated
|
||||
/// Originally held the id of the latest calibration record
|
||||
/// for sensor
|
||||
/// </summary>
|
||||
public int? LatestCalibrationId
|
||||
{
|
||||
get => _latestCalibrationId;
|
||||
set => SetProperty(ref _latestCalibrationId, value, "LatestCalibrationId");
|
||||
}
|
||||
public AnalogDbRecord() { }
|
||||
public AnalogDbRecord(IAnalogDbRecord copy)
|
||||
{
|
||||
AxisNumber = copy.AxisNumber;
|
||||
Bridge = copy.Bridge;
|
||||
BridgeLegMode = copy.BridgeLegMode;
|
||||
BridgeResistance = copy.BridgeResistance;
|
||||
BypassFilter = copy.BypassFilter;
|
||||
CalibrationSignal = copy.CalibrationSignal;
|
||||
CalInterval = copy.CalInterval;
|
||||
Capacity = copy.Capacity;
|
||||
CheckOffset = copy.CheckOffset;
|
||||
Comment = copy.Comment;
|
||||
CouplingMode = copy.CouplingMode;
|
||||
Created = copy.Created;
|
||||
ExternalShuntResistance = copy.ExternalShuntResistance;
|
||||
Filter = new FilterClass(copy.Filter.FClass, copy.Filter.Frequency);
|
||||
EId = copy.EId;
|
||||
InternalShuntResistance = copy.InternalShuntResistance;
|
||||
Invert = copy.Invert;
|
||||
ISOCode = copy.ISOCode;
|
||||
ISOChannelName = copy.ISOChannelName;
|
||||
UserCode = copy.UserCode;
|
||||
UserChannelName = copy.UserChannelName;
|
||||
LastModified = copy.LastModified;
|
||||
LocalOnly = copy.LocalOnly;
|
||||
Manufacturer = copy.Manufacturer;
|
||||
DisplayUnit = copy.DisplayUnit;
|
||||
Model = copy.Model;
|
||||
ModifiedBy = copy.ModifiedBy;
|
||||
NumberOfAxes = copy.NumberOfAxes;
|
||||
OffsetToleranceHigh = copy.OffsetToleranceHigh;
|
||||
OffsetToleranceLow = copy.OffsetToleranceLow;
|
||||
RangeMedium = copy.RangeMedium;
|
||||
RangeHigh = copy.RangeHigh;
|
||||
RangeLow = copy.RangeLow;
|
||||
SensorCategory = copy.SensorCategory;
|
||||
SerialNumber = copy.SerialNumber;
|
||||
Shunt = copy.Shunt;
|
||||
Status = copy.Status;
|
||||
TimesUsed = copy.TimesUsed;
|
||||
UniPolar = copy.UniPolar;
|
||||
UserSerialNumber = copy.UserSerialNumber;
|
||||
DiagnosticsMode = copy.DiagnosticsMode;
|
||||
UserValue1 = copy.UserValue1;
|
||||
UserValue2 = copy.UserValue2;
|
||||
UserValue3 = copy.UserValue3;
|
||||
Version = copy.Version;
|
||||
SupportedExcitation = copy.SupportedExcitation;
|
||||
TagsBlobBytes = copy.TagsBlobBytes;
|
||||
DoNotUse = copy.DoNotUse;
|
||||
Broken = copy.Broken;
|
||||
Id = copy.Id;
|
||||
FirstUseDate = copy.FirstUseDate;
|
||||
LatestCalibrationId = copy.LatestCalibrationId;
|
||||
ACCouplingModeEnabled = copy.ACCouplingModeEnabled;
|
||||
}
|
||||
public AnalogDbRecord(IDataReader reader)
|
||||
{
|
||||
AxisNumber = Utility.GetShort(reader, "AxisNumber", 0);
|
||||
SetBridge(SensorConstants.ConvertIntToBridgeType(Utility.GetInt(reader, "BridgeType")));
|
||||
BridgeLegMode = Utility.GetShort(reader, "BridgeLegMode", 0);
|
||||
BridgeResistance = Utility.GetDouble(reader, "BridgeResistance");
|
||||
BypassFilter = Utility.GetBool(reader, "BypassFilter");
|
||||
CalibrationSignal = Utility.GetBool(reader, "CalibrationSignal");
|
||||
CalInterval = Utility.GetInt(reader, "CalInterval");
|
||||
Capacity = Utility.GetDouble(reader, "Capacity");
|
||||
CheckOffset = Utility.GetBool(reader, "CheckOffset");
|
||||
Comment = Utility.GetString(reader, "Comment");
|
||||
CouplingMode = (SensorConstants.CouplingModes)Utility.GetInt(reader, "CouplingMode");
|
||||
Created = Utility.GetDateTime(reader, "Created", DateTime.MinValue);
|
||||
ExternalShuntResistance = Utility.GetDouble(reader, "ExternalShuntResistance");
|
||||
Filter = new FilterClass(Utility.GetString(reader, "FilterClass"));
|
||||
EId = Utility.GetString(reader, "eId");
|
||||
InternalShuntResistance = Utility.GetDouble(reader, "InternalShuntResistance");
|
||||
Invert = Utility.GetBool(reader, "Invert");
|
||||
ISOCode = Utility.GetString(reader, "IsoCode");
|
||||
ISOChannelName = Utility.GetString(reader, "IsoChannelName");
|
||||
UserCode = Utility.GetString(reader, "UserCode");
|
||||
UserChannelName = Utility.GetString(reader, "UserChannelName");
|
||||
LastModified = Utility.GetDateTime(reader, "LastModified", DateTime.MinValue);
|
||||
LocalOnly = Utility.GetBool(reader, "LocalOnly", false);
|
||||
Manufacturer = Utility.GetString(reader, "Manufacturer");
|
||||
DisplayUnit = Utility.GetString(reader, "MeasurementUnit");
|
||||
Model = Utility.GetString(reader, "Model");
|
||||
ModifiedBy = Utility.GetString(reader, "ModifiedBy");
|
||||
NumberOfAxes = Utility.GetShort(reader, "NumberOfAxes");
|
||||
OffsetToleranceHigh = Utility.GetDouble(reader, "OffsetToleranceHigh");
|
||||
OffsetToleranceLow = Utility.GetDouble(reader, "OffsetToleranceLow");
|
||||
RangeMedium = Utility.GetDouble(reader, "RangeAve");
|
||||
RangeHigh = Utility.GetDouble(reader, "RangeHigh");
|
||||
RangeLow = Utility.GetDouble(reader, "RangeLow");
|
||||
SensorCategory = Utility.GetInt(reader, "SensorCategory");
|
||||
SerialNumber = Utility.GetString(reader, "SerialNumber");
|
||||
Shunt = Utility.GetShort(reader, "Shunt");
|
||||
var oStatus = reader["Status"];
|
||||
if (oStatus is string s)
|
||||
{
|
||||
if (Enum.TryParse(s, out SensorStatus newStatus))
|
||||
{
|
||||
Status = newStatus;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = (SensorStatus)Convert.ToInt32(oStatus);
|
||||
}
|
||||
TimesUsed = Utility.GetInt(reader, "TimesUsed");
|
||||
UniPolar = Utility.GetBool(reader, "UniPolar");
|
||||
UserSerialNumber = Utility.GetString(reader, "UserSerialNumber");
|
||||
DiagnosticsMode = Utility.GetBool(reader, "DiagnosticsMode");
|
||||
UserValue1 = Utility.GetString(reader, "UserValue1");
|
||||
UserValue2 = Utility.GetString(reader, "UserValue2");
|
||||
UserValue3 = Utility.GetString(reader, "UserValue3");
|
||||
Version = Utility.GetInt(reader, "Version");
|
||||
SetSupportedExcitationFromString(Utility.GetString(reader, "SupportedExcitation"));
|
||||
TagsBlobBytes = (byte[])reader["UserTags"];
|
||||
DoNotUse = Utility.GetBool(reader, "DoNotUse");
|
||||
Broken = Utility.GetBool(reader, "Broken");
|
||||
Id = Utility.GetInt(reader, "Id", -1);
|
||||
FirstUseDate = Utility.GetNullableDateTime(reader, "FirstUseDate");
|
||||
LatestCalibrationId = Utility.GetNullableInt(reader, "LatestCalibrationId");
|
||||
ACCouplingModeEnabled = Utility.GetBool(reader, "ACCouplingModeEnabled", false);
|
||||
}
|
||||
public void SetSupportedExcitationFromString(string s)
|
||||
{
|
||||
var excitations = new List<ExcitationVoltageOptions.ExcitationVoltageOption>();
|
||||
|
||||
var tokens = s.Split(new[] { System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None);
|
||||
foreach (var token in tokens)
|
||||
{
|
||||
if (Enum.TryParse(token, out ExcitationVoltageOptions.ExcitationVoltageOption option)) { excitations.Add(option); }
|
||||
}
|
||||
SupportedExcitation = excitations.ToArray();
|
||||
}
|
||||
|
||||
private bool _bACCouplingModeEnabled = false;
|
||||
/// <summary>
|
||||
/// whether to use AC Coupling when using a bridge mode (full/half/quarter/half+sig)
|
||||
/// 18294 Implement Bridge AC/DC coupling(fw update dependent)
|
||||
/// </summary>
|
||||
public bool ACCouplingModeEnabled
|
||||
{
|
||||
get => _bACCouplingModeEnabled;
|
||||
set => SetProperty(ref _bACCouplingModeEnabled, value, "ACCouplingModeEnabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
using DTS.Common.Enums.Sensors;
|
||||
|
||||
namespace DTS.Common.Interface.Hardware
|
||||
{
|
||||
public interface IDiagnosticResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Which DASChannel from which this diagnostics is returning.
|
||||
/// </summary>
|
||||
int DASChannelNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The event number that this diagnostics is relevant for.
|
||||
/// </summary>
|
||||
int EventNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The firmware calculates a scale factory for the channel's input. The hardware will
|
||||
/// deliver raw, unprocessed data upon download, but to diagnos this data to
|
||||
/// reflect real world votages it must be scaled based on the DAS unit's factory
|
||||
/// diagnostics as well as results from this diagnose. The samples that
|
||||
/// will be downloaded will be straight from the A to D Converter so this scale
|
||||
/// factor is MANDATORY and must be used at the software level to scale the data
|
||||
/// to the real sensed voltages and engineering units.
|
||||
/// </summary>
|
||||
double ScalefactorMilliVoltsPerADC { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The factory excitation value (mandatory)
|
||||
/// </summary>
|
||||
double ExpectedExcitationMilliVolts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// gets what will probably be the datazerolevel adc for the channel
|
||||
/// </summary>
|
||||
/// <param name="zeroMethod"></param>
|
||||
/// <returns></returns>
|
||||
short GetExpectedDataZeroLevelADC(ZeroMethodType zeroMethod);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Excitation voltage provided to sensor as measured by the firmware during
|
||||
/// calibration. When read from event attributes, a value of 0.0 might actually
|
||||
/// mean null (i.e. was not measured).
|
||||
/// </summary>
|
||||
double? MeasuredExcitationMilliVolts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// flag to indicate whether MeasuredExcitationMilliVolts was negative when it was initially read
|
||||
/// 14233 Negative Excitation Reported by TDAS hardware not showing in Diagnostics
|
||||
/// this was created to relate to legacy TDC/TDAS broken sensor/wire warnings carried through
|
||||
/// the excitation reading
|
||||
/// </summary>
|
||||
bool NegativeExcitation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What is the sensor's offset reading from the 0 level? This is measured by firmware
|
||||
/// during the calibration. When read from event attributes, a value of 0.0 might actually
|
||||
/// mean null (i.e. was not measured).
|
||||
/// </summary>
|
||||
double? MeasuredOffsetMilliVolts{ get; set; }
|
||||
|
||||
double? MeasuredInternalOffsetMilliVolts{ get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// when a channel is autozero'd (remove offset)
|
||||
/// this is the devation from 0 (from RW Auto zero is checking for +/- 5% from 0 in counts.)
|
||||
/// </summary>
|
||||
double? AutoZeroPercentDeviation{ get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="DTS.DASLib.Service.DiagnosticsService" />.Calibrate method was called with the "RemoveOffset" boolean variable set
|
||||
/// to TRUE then the firmware will attempt to remove the offset of the sensor, moving it's base
|
||||
/// reading back to 0. This value is how much offset is present after removing the offset. While the
|
||||
/// offset my not be compeletely removed it may have been reduced to fall within the high and low
|
||||
/// limits for acceptable offsets for the sensor. See <see cref="AnalogInputDASChannel" /> to find
|
||||
/// these sensor specific values. When read from event attributes, a value of 0.0 might actually
|
||||
/// mean null (i.e. was not measured).
|
||||
/// </summary>
|
||||
short? FinalOffsetADC { get; set; }
|
||||
|
||||
int? RemovedOffsetADC { get; set; }
|
||||
|
||||
int? RemovedInternalOffsetADC { get; set; }
|
||||
/// <summary>
|
||||
/// FullScaleSignal to Noise ratio as a percentage. When read from event attributes, a value of 0.0 might actually
|
||||
/// mean null (i.e. was not measured).
|
||||
/// </summary>
|
||||
double? NoisePercentFullScale { get; set; }
|
||||
|
||||
bool ShuntDeflectionFailed { get; set; }
|
||||
|
||||
bool CalSignalCheckFailed { get; set; }
|
||||
/// <summary>
|
||||
/// If an emulated shunt test is performed the measured shunt deflection in mV detected
|
||||
/// during the test will be here.
|
||||
/// <see cref="DTS.DASLib.Service.DiagnosticsActions" />.PerformShuntCheck
|
||||
/// When read from event attributes, a value of 0.0 might actually mean null
|
||||
/// (i.e. was not measured).
|
||||
/// </summary>
|
||||
double? MeasuredShuntDeflectionMv { get; set; }
|
||||
|
||||
double? MeasuredCalSignalMv { get; set; }
|
||||
double? TargetCalSignalMv { get; set; }
|
||||
|
||||
double? MeasuredDurationMS { get; set; }
|
||||
|
||||
double? MeasuredDelayMS { get; set; }
|
||||
bool? SquibFirePassed { get; set; }
|
||||
bool? SquibDurationPassed { get; set; }
|
||||
bool? SquibDelayPassed { get; set; }
|
||||
double[] SquibFireCurrentData { get; set; }
|
||||
double[] SquibFireVoltageData { get; set; }
|
||||
double[] SquibFireTimeAxis { get; set; }
|
||||
double SquibThreshold { get; set; }
|
||||
|
||||
double SquibVoltageScaler { get; set; }
|
||||
double SquibCurrentScaler { get; set; }
|
||||
|
||||
double? TargetGain { get; set; }
|
||||
double? MeasuredGain { get; set; }
|
||||
double? QueriedGain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If an emulated shunt test is performed the target shunt deflection in mV will be here.
|
||||
/// CalibrateActions.PerformShuntCheck When read from event attributes, a value of 0.0 might actually
|
||||
/// mean null (i.e. was not measured).
|
||||
/// </summary>
|
||||
double? TargetShuntDeflectionMv { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the bridge resistance of the sensor was measured, the measured resistance in
|
||||
/// ohms will be here. <see cref="DiagnosticsActions.MeasureBridgeResistance" />
|
||||
/// When read from event attributes, a value of 0.0 might actually mean null
|
||||
/// (i.e. was not measured).
|
||||
/// </summary>
|
||||
double? BridgeResistance { get; set; }
|
||||
|
||||
short ZeroMVInADC { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// WindowAverageADC is the average ADC over the averaging window specified for the channel
|
||||
/// short.MinValue indicates an unitialized or invalid value
|
||||
/// </summary>
|
||||
short WindowAverageADC { get; set; }
|
||||
bool DigitalInputActiveState { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Utils
|
||||
{
|
||||
//FB 18512 This calss contains utility methods, they are moved from Netwroking module
|
||||
public static class NetworkUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// returns true if the network interface is up, false otherwise
|
||||
/// stolen from FWTU
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsNetworkInterfaceUp(IPAddress ip)
|
||||
{
|
||||
foreach (var a in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
try
|
||||
{
|
||||
var ipp = a.GetIPProperties();
|
||||
|
||||
if (ipp.MulticastAddresses.Count == 0)
|
||||
continue; // most of VPN adapters will be skipped
|
||||
if (!a.SupportsMulticast)
|
||||
continue; // multicast is meaningless for this type of connection
|
||||
if (OperationalStatus.Up != a.OperationalStatus)
|
||||
continue; // this adapter is off or not connected
|
||||
if (null == ipp.GetIPv4Properties())
|
||||
continue; // IPv4 is not configured on this adapter
|
||||
if (a.NetworkInterfaceType == NetworkInterfaceType.Loopback)
|
||||
continue;
|
||||
var addressBytes = ip.GetAddressBytes();
|
||||
if (4 == addressBytes.Length && addressBytes[0] == 169 && addressBytes[1] == 254) { continue; }
|
||||
if (a.GetIPProperties().UnicastAddresses.Any(i => i.Address.AddressFamily == AddressFamily.InterNetwork && IPAddress.Equals(i.Address, ip)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Indicates whether any network connection is available.
|
||||
/// Filter connections below a specified speed, as well as virtual network cards.
|
||||
/// </summary>
|
||||
/// <param name="minimumSpeed">The minimum speed required. Passing 0 will not filter connection using speed.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if a network connection is available; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
private static List<NetworkInterface> GetAvailableNetworkInterfaces(long minimumSpeed = 10000000)
|
||||
{
|
||||
if (!NetworkInterface.GetIsNetworkAvailable())
|
||||
return null;
|
||||
|
||||
var niList = new List<NetworkInterface>();
|
||||
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
// discard because of standard reasons
|
||||
if ((ni.NetworkInterfaceType == NetworkInterfaceType.Loopback)
|
||||
|| (ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel))
|
||||
continue;
|
||||
|
||||
// this allow to filter modems, serial, etc.
|
||||
// use 10000000 as a minimum speed for most cases
|
||||
if (ni.Speed < minimumSpeed)
|
||||
continue;
|
||||
|
||||
// discard virtual cards (virtual box, virtual pc, etc.)
|
||||
if (ni.Description.ToLower().Contains("virtual")
|
||||
|| ni.Name.ToLower().Contains("virtual")
|
||||
|| ni.Description.ToLower().Contains("bluethooth")
|
||||
|| ni.Name.ToLower().Contains("bluethooth"))
|
||||
continue;
|
||||
|
||||
// discard "Microsoft Loopback Adapter", it will not show as NetworkInterfaceType.Loopback but as Ethernet Card.
|
||||
if (ni.Description.Equals("Microsoft Loopback Adapter", StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
|
||||
niList.Add(ni);
|
||||
}
|
||||
|
||||
return niList;
|
||||
}
|
||||
|
||||
private static string GetMACAddress(string id)
|
||||
{
|
||||
var macAddress = string.Empty;
|
||||
|
||||
var nics = GetAvailableNetworkInterfaces();
|
||||
|
||||
if (nics == null)
|
||||
return macAddress;
|
||||
|
||||
foreach (var nic in nics)
|
||||
{
|
||||
if (nic.Id != id) continue;
|
||||
var pa = BitConverter.ToString(nic.GetPhysicalAddress().GetAddressBytes());
|
||||
pa = pa.Replace("-", ":");
|
||||
if (string.IsNullOrEmpty(pa)) continue;
|
||||
macAddress = pa;
|
||||
break;
|
||||
}
|
||||
return macAddress;
|
||||
}
|
||||
|
||||
private static bool InvalidNIC(NetworkInterface ni)
|
||||
{
|
||||
return OperationalStatus.Up != ni.OperationalStatus || !ni.SupportsMulticast;
|
||||
}
|
||||
|
||||
public static List<HostInfo> GetAvailableHosts(bool supportMulticastOnly = false)
|
||||
{
|
||||
var nics = GetAvailableNetworkInterfaces();
|
||||
if (nics == null) { return new List<HostInfo>(); }
|
||||
var hosts = new List<HostInfo>();
|
||||
|
||||
foreach (NetworkInterface ni in nics)
|
||||
{
|
||||
if (supportMulticastOnly && InvalidNIC(ni))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
//exclude wireshark network interface, it claims it can ping ips lyingly
|
||||
if (ni.Description.Contains("Npcap")) { continue; }
|
||||
foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
|
||||
{
|
||||
var addressBytes = ip.Address.GetAddressBytes();
|
||||
if (4 == addressBytes.Length && addressBytes[0] == 169 && addressBytes[1] == 254)
|
||||
{
|
||||
APILogger.Log($"skipping {ni.Name}\\{ni.Description} as it has a 169.254 address");
|
||||
continue;//internal only
|
||||
}
|
||||
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
GetStartAndEndAddress(ip.Address, ip.IPv4Mask, out var startAddress, out var endAddress);
|
||||
hosts.Add(new HostInfo { HostIpAddress = ip.Address.ToString(), HostNetworkId = ni.Id, HostMacAddress = GetMACAddress(ni.Id),
|
||||
StartAddress = startAddress, EndAddress = endAddress
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return hosts;
|
||||
}
|
||||
/// <summary>
|
||||
/// given an IP address and a mask returns a ip address as a string for the first address that is accessible and a string for the last address that is accessible
|
||||
/// anything between the start address and end address after doing a byte-by-byte comparison should be addressable
|
||||
/// will return empty strings if something bad happens. Is designed for 4 byte addresses but isn't necessarily limited.
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
/// <param name="mask"></param>
|
||||
/// <param name="startAddress"></param>
|
||||
/// <param name="endAddress"></param>
|
||||
private static void GetStartAndEndAddress( IPAddress ip, IPAddress mask, out string startAddress, out string endAddress)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ipByte = ip.GetAddressBytes();
|
||||
var maskBytes = mask.GetAddressBytes();
|
||||
|
||||
var startBytes = new byte[ipByte.Length];
|
||||
var endBytes = new byte[ipByte.Length];
|
||||
|
||||
for (var i = 0; i < ipByte.Length; i++)
|
||||
{
|
||||
startBytes[i] = (byte)(ipByte[i] & maskBytes[i]);
|
||||
endBytes[i] = (byte)(ipByte[i] | ~maskBytes[i]);
|
||||
}
|
||||
var startIP = new IPAddress(startBytes);
|
||||
var endIP = new IPAddress(endBytes);
|
||||
startAddress = startIP.ToString();
|
||||
endAddress = endIP.ToString();
|
||||
}
|
||||
catch( Exception ex)
|
||||
{
|
||||
startAddress = string.Empty;
|
||||
endAddress = string.Empty;
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
//FB 25658 Changed the method signature to return bool to determine the connection string has IP in it and it's not USB
|
||||
/// <summary>
|
||||
/// Try to parse connectionString and retrieve the IP address.
|
||||
/// </summary>
|
||||
/// <param name="connectionString"> DAS connectionString which might include the IP address or might be a USB connection string</param>
|
||||
/// <param name="ipAddress">Return the parsed IP address from connectionString</param>
|
||||
/// <returns>Returns true if was able to parse and get the IP otherwise false including the valid USB connection string </returns>
|
||||
public static bool TryParseConnectionString(string connectionString, out string ipAddress)
|
||||
{
|
||||
ipAddress = null;
|
||||
|
||||
if (string.IsNullOrEmpty(connectionString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var uri = new Uri(connectionString);
|
||||
|
||||
if (IPAddress.TryParse(uri.Host, out _))
|
||||
{
|
||||
ipAddress = uri.Host;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
var ip = connectionString.Split(':')[0];
|
||||
|
||||
if (IPAddress.TryParse(ip, out _))
|
||||
{
|
||||
ipAddress = ip;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace DTS.Common.XMLUtils
|
||||
{
|
||||
public class DASListXMLClass
|
||||
{
|
||||
[XmlElement("DASList")]
|
||||
|
||||
public List<DASHardwareXMLClass> DASList {get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user