init
This commit is contained in:
731
Common/DTS.CommonCore/Classes/Sensors/AnalogDbRecord.cs
Normal file
731
Common/DTS.CommonCore/Classes/Sensors/AnalogDbRecord.cs
Normal file
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
65
Common/DTS.CommonCore/Classes/Sensors/CalMode.cs
Normal file
65
Common/DTS.CommonCore/Classes/Sensors/CalMode.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
/// <summary>
|
||||
/// helper class for the calmode in SIFs which is actually a 3 character sequence for shunt/bridge/filter
|
||||
/// </summary>
|
||||
public class CalMode
|
||||
{
|
||||
public bool ShuntCheck { get; set; }
|
||||
|
||||
public bool FullBridge { get; set; }
|
||||
|
||||
public bool Filter { get; set; }
|
||||
|
||||
public CalMode(string value)
|
||||
{
|
||||
switch (value[0])
|
||||
{
|
||||
case 'S':
|
||||
ShuntCheck = true;
|
||||
break;
|
||||
case 'I':
|
||||
ShuntCheck = false;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("TDAS::CalMode Invalid calmode position 0: " + value);
|
||||
}
|
||||
switch (value[1])
|
||||
{
|
||||
case 'D':
|
||||
FullBridge = true;
|
||||
break;
|
||||
case 'S':
|
||||
FullBridge = false;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("TDAS::CalMode Invalid calmode position 1: " + value);
|
||||
}
|
||||
switch (value[2])
|
||||
{
|
||||
case 'F':
|
||||
Filter = true;
|
||||
break;
|
||||
case 'B':
|
||||
Filter = false;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("TDAS::CalMode Invalid calmode position 2: " + value);
|
||||
}
|
||||
}
|
||||
public CalMode() { }
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.Append(ShuntCheck ? 'S' : 'I');
|
||||
sb.Append(FullBridge ? 'D' : 'S');
|
||||
sb.Append(Filter ? 'F' : 'B');
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
518
Common/DTS.CommonCore/Classes/Sensors/CalibrationRecord.cs
Normal file
518
Common/DTS.CommonCore/Classes/Sensors/CalibrationRecord.cs
Normal file
@@ -0,0 +1,518 @@
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System.Globalization;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class CalibrationRecords : ICalibrationRecords
|
||||
{
|
||||
public ICalibrationRecord[] Records { get; set; } = new CalibrationRecord[] { new CalibrationRecord() };
|
||||
|
||||
public CalibrationRecords(ICalibrationRecords copy)
|
||||
{
|
||||
var records = new CalibrationRecord[copy.Records.Length];
|
||||
for (var i = 0; i < copy.Records.Length; i++)
|
||||
{
|
||||
records[i] = new CalibrationRecord(copy.Records[i]);
|
||||
}
|
||||
|
||||
Records = records;
|
||||
}
|
||||
|
||||
public CalibrationRecords()
|
||||
{
|
||||
Records = new CalibrationRecord[] { new CalibrationRecord() };
|
||||
}
|
||||
|
||||
public CalibrationRecords(string records)
|
||||
{
|
||||
FromSerializedString(records);
|
||||
}
|
||||
|
||||
public bool IsEqual(object obj, ISensorCalibration sc)
|
||||
{
|
||||
if (obj is CalibrationRecords r)
|
||||
{
|
||||
if (r.Records.Length != Records.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < r.Records.Length; i++)
|
||||
{
|
||||
if (!r.Records[i].IsEqual(Records[i], sc))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public void FromSerializedString(string s)
|
||||
{
|
||||
var tokens = s.Split(new string[] { MySeparator }, StringSplitOptions.None);
|
||||
for (var i = 0; i < tokens.Length; i++)
|
||||
{
|
||||
tokens[i] = tokens[i].Replace(MySeparatorBackup, MySeparator);
|
||||
}
|
||||
|
||||
var records = new List<CalibrationRecord>();
|
||||
foreach (string token in tokens)
|
||||
{
|
||||
records.Add(new CalibrationRecord(token));
|
||||
}
|
||||
|
||||
Records = records.ToArray();
|
||||
}
|
||||
|
||||
private const string MySeparator = "__x__";
|
||||
private const string MySeparatorBackup = "___xx___";
|
||||
|
||||
public string ToSerializedString(ISensorCalDbRecord sc)
|
||||
{
|
||||
var records = new List<string>();
|
||||
|
||||
foreach (var r in Records)
|
||||
{
|
||||
records.Add(r.ToSerializedString(sc));
|
||||
}
|
||||
|
||||
for (var i = 0; i < records.Count; i++)
|
||||
{
|
||||
System.Diagnostics.Trace.Assert(!records[i].Contains(MySeparatorBackup));
|
||||
records[i] = records[i].Replace(MySeparator, MySeparatorBackup);
|
||||
}
|
||||
|
||||
return string.Join(MySeparator, records.ToArray());
|
||||
}
|
||||
|
||||
public string ToDisplayString(ISensorCalibration sc, ISensorCalibration previous, string linearFormat, string nonlinearFormat)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < Records.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
var r = Records[i];
|
||||
ICalibrationRecord r2 = null;
|
||||
|
||||
if (null != previous)
|
||||
{
|
||||
if (i < previous.Records.Records.Length)
|
||||
{
|
||||
r2 = previous.Records.Records[i];
|
||||
}
|
||||
}
|
||||
|
||||
var s = r.ToDisplayString(sc, r2, previous, linearFormat, nonlinearFormat);
|
||||
if (!string.IsNullOrEmpty(s))
|
||||
{
|
||||
sb.Append(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class CalibrationRecord : ICalibrationRecord
|
||||
{
|
||||
public double Sensitivity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ZeroPoint is used to hold the calibration certificate field for 2D/3D IR-TRACC cal certs
|
||||
/// it is used to zero the IR-TRACC and POT data prior to being fed into the 3D equations
|
||||
/// </summary>
|
||||
private double _zeroPoint = 0D;
|
||||
|
||||
public double ZeroPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
if (false == Equals(Poly.CalibrationFactor, 0.0))
|
||||
{
|
||||
// This field is always calculated. Do not return stored value unless we are unable to calculate
|
||||
return Poly.ZeroPositionIntercept / Poly.CalibrationFactor;
|
||||
}
|
||||
|
||||
return _zeroPoint;
|
||||
}
|
||||
set => _zeroPoint = value;
|
||||
}
|
||||
|
||||
public LinearizationFormula Poly { get; set; }
|
||||
|
||||
public bool AtCapacity { get; set; } = false;
|
||||
|
||||
public string EngineeringUnits { get; set; } = "g";
|
||||
|
||||
public SensorConstants.SensUnits SensitivityUnits { get; set; } = SensorConstants.SensUnits.NONE;
|
||||
|
||||
public ExcitationVoltageOptions.ExcitationVoltageOption Excitation { get; set; } = ExcitationVoltageOptions.ExcitationVoltageOption.Volt5;
|
||||
|
||||
public double CapacityOutputIsBasedOn { get; set; } = 1.000;
|
||||
|
||||
public InitialOffsetTypes InitialOffsetMethod { get; set; } = InitialOffsetTypes.EU;
|
||||
|
||||
public string ISOCode { get; set; } = String.Empty;
|
||||
|
||||
private enum Fields
|
||||
{
|
||||
Sensitivity,
|
||||
Poly,
|
||||
AtCapacity,
|
||||
EngineeringUnits,
|
||||
Excitation,
|
||||
CapacityOutputIsBasedOn,
|
||||
SensitivityUnits,
|
||||
ZeroPoint,
|
||||
ISOCode
|
||||
};
|
||||
|
||||
public string ToSerializedString(ISensorCalDbRecord parentCal)
|
||||
{
|
||||
var tokens = new List<string>();
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case Fields.AtCapacity:
|
||||
tokens.Add(AtCapacity.ToString());
|
||||
break;
|
||||
case Fields.EngineeringUnits:
|
||||
tokens.Add(EngineeringUnits);
|
||||
break;
|
||||
case Fields.Excitation:
|
||||
tokens.Add(Excitation.ToString());
|
||||
break;
|
||||
case Fields.Poly:
|
||||
Poly.MarkValid(parentCal.NonLinear);
|
||||
if (parentCal.LinearAdded)
|
||||
{
|
||||
//We have a mixed-sensitivity sensor. Mark the first CR valid, kill the rest
|
||||
for (var i = 0; i < parentCal.Records.Records.Length; i++)
|
||||
{
|
||||
parentCal.Records.Records[i].Poly.MarkValid(i == 0);
|
||||
}
|
||||
}
|
||||
|
||||
tokens.Add(Poly.ToSerializeString());
|
||||
break;
|
||||
case Fields.Sensitivity:
|
||||
tokens.Add(Sensitivity.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case Fields.CapacityOutputIsBasedOn:
|
||||
tokens.Add(CapacityOutputIsBasedOn.ToString());
|
||||
break;
|
||||
case Fields.SensitivityUnits:
|
||||
tokens.Add(SensitivityUnits.ToString());
|
||||
break;
|
||||
case Fields.ZeroPoint:
|
||||
tokens.Add(ZeroPoint.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case Fields.ISOCode:
|
||||
if (!string.IsNullOrWhiteSpace(ISOCode)) tokens.Add(ISOCode);
|
||||
break;
|
||||
default: throw new NotSupportedException("unknown CalibrationRecord field: " + field.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < tokens.Count; i++)
|
||||
{
|
||||
if (null == tokens[i])
|
||||
{
|
||||
tokens[i] = "";
|
||||
}
|
||||
|
||||
tokens[i] = tokens[i].Replace(System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator,
|
||||
"x_Separator_x");
|
||||
}
|
||||
|
||||
return string.Join(System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator,
|
||||
tokens.ToArray());
|
||||
}
|
||||
|
||||
public string ToDisplayString(ISensorCalibration sc, ICalibrationRecord previous, ISensorCalibration sc2, string linearFormat, string nonlinearFormat)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case Fields.AtCapacity:
|
||||
if (null == previous || AtCapacity != previous.AtCapacity)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_AtCapacity, AtCapacity);
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.EngineeringUnits:
|
||||
if (null == previous || false == EngineeringUnits.Equals(previous.EngineeringUnits))
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_EngineeringUnits, EngineeringUnits);
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.Excitation:
|
||||
if (null == previous || sc.IsProportional != sc2.IsProportional || Excitation != previous.Excitation)
|
||||
{
|
||||
if (sc.IsProportional)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1:0.0}", Strings.Strings.SensorFields_Excitation,
|
||||
GetExcitationVoltageMagnitudeFromEnum(Excitation));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.Poly:
|
||||
if (null == previous || sc.NonLinear || sc.NonLinear != sc2.NonLinear)
|
||||
{
|
||||
if (sc.NonLinear)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_NonLinearFormat,
|
||||
Poly.ToDisplayString(nonlinearFormat));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.Sensitivity:
|
||||
if (null == previous || Sensitivity != previous.Sensitivity)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_Sensitivity,
|
||||
Sensitivity.ToString(linearFormat));
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.CapacityOutputIsBasedOn:
|
||||
if (false == AtCapacity)
|
||||
{
|
||||
if (null == previous || CapacityOutputIsBasedOn != previous.CapacityOutputIsBasedOn)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_CapacityOutputIsBasedOn,
|
||||
CapacityOutputIsBasedOn);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.SensitivityUnits:
|
||||
if (null == previous || false == SensitivityUnits.Equals(previous.SensitivityUnits))
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_SensitivityUnits, SensitivityUnits);
|
||||
}
|
||||
|
||||
break;
|
||||
case Fields.ZeroPoint:
|
||||
if (null == previous || ZeroPoint != previous.ZeroPoint)
|
||||
{
|
||||
if (sb.Length > 1)
|
||||
{
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0}: {1}", Strings.Strings.SensorFields_ZeroPoint, ZeroPoint);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
public bool IsEqual(object obj, ISensorCalibration sc)
|
||||
{
|
||||
if (obj is CalibrationRecord r)
|
||||
{
|
||||
return r.ToSerializedString(sc) == ToSerializedString(sc);
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public void FromString(string s)
|
||||
{
|
||||
var tokens = s.Split(new string[] { CultureInfo.InvariantCulture.TextInfo.ListSeparator },
|
||||
StringSplitOptions.None);
|
||||
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
|
||||
for (var i = 0; i < tokens.Length && i < fields.Length; i++)
|
||||
{
|
||||
var token = tokens[i].Replace("x_Separator_x",
|
||||
CultureInfo.InvariantCulture.TextInfo.ListSeparator);
|
||||
switch (fields[i])
|
||||
{
|
||||
case Fields.AtCapacity:
|
||||
AtCapacity = Convert.ToBoolean(token);
|
||||
break;
|
||||
case Fields.EngineeringUnits:
|
||||
EngineeringUnits = token;
|
||||
break;
|
||||
case Fields.Excitation:
|
||||
Excitation =
|
||||
(ExcitationVoltageOptions.ExcitationVoltageOption)Enum.Parse(
|
||||
typeof(ExcitationVoltageOptions.ExcitationVoltageOption), token);
|
||||
break;
|
||||
case Fields.Poly:
|
||||
Poly = new LinearizationFormula();
|
||||
Poly.FromSerializeString(token);
|
||||
break;
|
||||
case Fields.Sensitivity:
|
||||
Sensitivity = Convert.ToDouble(token, System.Globalization.CultureInfo.InvariantCulture);
|
||||
break;
|
||||
case Fields.CapacityOutputIsBasedOn:
|
||||
CapacityOutputIsBasedOn = Convert.ToDouble(token);
|
||||
break;
|
||||
case Fields.SensitivityUnits:
|
||||
if (Enum.TryParse(token, out SensorConstants.SensUnits unit))
|
||||
{
|
||||
SensitivityUnits = unit;
|
||||
}
|
||||
else { APILogger.Log($"failed to parse sensitivity units: {token} from {s}"); }
|
||||
break;
|
||||
case Fields.ZeroPoint:
|
||||
ZeroPoint = Convert.ToDouble(token, System.Globalization.CultureInfo.InvariantCulture);
|
||||
break;
|
||||
case Fields.ISOCode:
|
||||
ISOCode = token;
|
||||
break;
|
||||
default: throw new NotSupportedException("unknown CalibrationRecord field: " + fields.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CalibrationRecord(string s)
|
||||
{
|
||||
FromString(s);
|
||||
}
|
||||
|
||||
public CalibrationRecord(ICalibrationRecord copy)
|
||||
{
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case Fields.AtCapacity:
|
||||
AtCapacity = copy.AtCapacity;
|
||||
break;
|
||||
case Fields.EngineeringUnits:
|
||||
EngineeringUnits = copy.EngineeringUnits;
|
||||
break;
|
||||
case Fields.Excitation:
|
||||
Excitation = copy.Excitation;
|
||||
break;
|
||||
case Fields.Poly:
|
||||
Poly = new LinearizationFormula(copy.Poly);
|
||||
break;
|
||||
case Fields.Sensitivity:
|
||||
Sensitivity = copy.Sensitivity;
|
||||
break;
|
||||
case Fields.CapacityOutputIsBasedOn:
|
||||
CapacityOutputIsBasedOn = copy.CapacityOutputIsBasedOn;
|
||||
break;
|
||||
case Fields.SensitivityUnits:
|
||||
SensitivityUnits = copy.SensitivityUnits;
|
||||
break;
|
||||
case Fields.ZeroPoint:
|
||||
ZeroPoint = copy.ZeroPoint;
|
||||
break;
|
||||
case Fields.ISOCode:
|
||||
ISOCode = copy.ISOCode;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("unknown calibrationrecord field: " + field.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CalibrationRecord()
|
||||
{
|
||||
Poly = new LinearizationFormula();
|
||||
}
|
||||
|
||||
//helpers moved from DAS.Concepts
|
||||
public static double GetExcitationVoltageMagnitudeFromEnum(ExcitationVoltageOptions.ExcitationVoltageOption target)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ExcitationVoltageOptions.VoltageMagnitudeAttributeCoder().DecodeAttributeValue(target);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("encountered problem attempting to get excitation voltage magnitude from enum", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static ExcitationVoltageOptions.ExcitationVoltageOption GetExcitationVoltageEnumFromMagnitude(double magnitude)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ExcitationVoltageOptions.VoltageMagnitudeAttributeCoder().EncodeAttributeValue(magnitude);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("encountered problem attempting to get excitation voltage enum from magnitude", ex);
|
||||
return ExcitationVoltageOptions.ExcitationVoltageOption.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
320
Common/DTS.CommonCore/Classes/Sensors/DigitalInDbRecord.cs
Normal file
320
Common/DTS.CommonCore/Classes/Sensors/DigitalInDbRecord.cs
Normal file
@@ -0,0 +1,320 @@
|
||||
using DTS.Common.Base;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.Interface.Sensors.SoftwareFilters;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of IDigitalInDbRecord
|
||||
/// represents a record of a digital input setting in the database
|
||||
/// <inheritdoc cref="IDigitalInDbRecord"/>
|
||||
/// </summary>
|
||||
public class DigitalInDbRecord : BasePropertyChanged, IDigitalInDbRecord
|
||||
{
|
||||
private int _id = -1;
|
||||
/// <summary>
|
||||
/// Database id of record
|
||||
/// </summary>
|
||||
[Key]
|
||||
public int Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value, "Id");
|
||||
}
|
||||
private string _serialNumber = "";
|
||||
/// <summary>
|
||||
/// serial number or name of setting
|
||||
/// </summary>
|
||||
public string SerialNumber
|
||||
{
|
||||
get => _serialNumber;
|
||||
set => SetProperty(ref _serialNumber, value, "SerialNumber");
|
||||
}
|
||||
private DigitalInputModes _settingMode = DigitalInputModes.TLH;
|
||||
/// <summary>
|
||||
/// Input mode for setting
|
||||
/// </summary>
|
||||
public DigitalInputModes Mode
|
||||
{
|
||||
get => _settingMode;
|
||||
set => SetProperty(ref _settingMode, value, "Mode");
|
||||
}
|
||||
private IDigitalInputScaleMultiplier _scaleMultiplier = new DigitalInputScaleMultiplier();
|
||||
/// <summary>
|
||||
/// ScaleMultiplier, defines how to interpret output in terms of
|
||||
/// units or active/default value of input state
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public IDigitalInputScaleMultiplier ScaleMultiplier
|
||||
{
|
||||
get => _scaleMultiplier;
|
||||
set => SetProperty(ref _scaleMultiplier, value, "ScaleMultiplier");
|
||||
}
|
||||
private DateTime _lastModified = DateTime.MinValue;
|
||||
[Column(TypeName = "datetime")]
|
||||
/// <summary>
|
||||
/// when setting was last modified
|
||||
/// </summary>
|
||||
public DateTime LastModified
|
||||
{
|
||||
get => _lastModified;
|
||||
set => SetProperty(ref _lastModified, value, "LastModified");
|
||||
}
|
||||
private string _lastModifiedBy = "";
|
||||
/// <summary>
|
||||
/// user that last modified setting in db
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string LastModifiedBy
|
||||
{
|
||||
get => _lastModifiedBy;
|
||||
set => SetProperty(ref _lastModifiedBy, value, "LastModifiedBy");
|
||||
}
|
||||
private string _eId = "";
|
||||
/// <summary>
|
||||
/// Electronic ID for digital input setting
|
||||
/// (dallas or TeDS ID value)
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Column("eId")]
|
||||
[StringLength(50)]
|
||||
public string EID
|
||||
{
|
||||
get => _eId;
|
||||
set => SetProperty(ref _eId, value, "EID");
|
||||
}
|
||||
private string _isoCode = "";
|
||||
/// <summary>
|
||||
/// ISO 13499 code for digital input data collected using this setting
|
||||
/// this is the default code when the setting is applied to an input channel
|
||||
/// but can be changed in group or test settings
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string ISOCode
|
||||
{
|
||||
get => _isoCode;
|
||||
set => SetProperty(ref _isoCode, value, "ISOCode");
|
||||
}
|
||||
private string _isoChannelName = "";
|
||||
/// <summary>
|
||||
/// the associated ISO 13499 channel name to apply to a channel when applying
|
||||
/// setting to an input channel
|
||||
/// but can be changed in group or test settings
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(255)]
|
||||
public string ISOChannelName
|
||||
{
|
||||
get => _isoChannelName;
|
||||
set => SetProperty(ref _isoChannelName, value, "ISOChannelName");
|
||||
}
|
||||
private string _userCode = "";
|
||||
/// <summary>
|
||||
/// the user code to apply to a channel when applying setting to a channel
|
||||
/// can be changed in group or test settings
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string UserCode
|
||||
{
|
||||
get => _userCode;
|
||||
set => SetProperty(ref _userCode, value, "UserCode");
|
||||
}
|
||||
private string _userChannelName = "";
|
||||
/// <summary>
|
||||
/// user channel name to apply to a channel when applying setting to a channel
|
||||
/// can be changed in group or test settings
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(255)]
|
||||
public string UserChannelName
|
||||
{
|
||||
get => _userChannelName;
|
||||
set => SetProperty(ref _userChannelName, value, "UserChannelName");
|
||||
}
|
||||
private string _userValue1 = "";
|
||||
/// <summary>
|
||||
/// user value to carry through to collected data channel when collecting data with this setting
|
||||
/// </summary>
|
||||
[StringLength(255)]
|
||||
public string UserValue1
|
||||
{
|
||||
get => _userValue1;
|
||||
set => SetProperty(ref _userValue1, value, "UserValue1");
|
||||
}
|
||||
private string _userValue2 = "";
|
||||
/// <summary>
|
||||
/// user value to carry through to collected data channel when collecting data with this setting
|
||||
/// </summary>
|
||||
[StringLength(255)]
|
||||
public string UserValue2
|
||||
{
|
||||
get => _userValue2;
|
||||
set => SetProperty(ref _userValue2, value, "UserValue2");
|
||||
}
|
||||
private string _userValue3 = "";
|
||||
/// <summary>
|
||||
/// user value to carry through to collected data channel when collecting data with this setting
|
||||
/// </summary>
|
||||
[StringLength(255)]
|
||||
public string UserValue3
|
||||
{
|
||||
get => _userValue3;
|
||||
set => SetProperty(ref _userValue3, value, "UserValue3");
|
||||
}
|
||||
private byte[] _userTags;
|
||||
/// <summary>
|
||||
/// bytes describing tag ids for tags associated with setting
|
||||
/// see ITagAware for more information
|
||||
/// </summary>
|
||||
public byte[] UserTags
|
||||
{
|
||||
get => _userTags;
|
||||
set => SetProperty(ref _userTags, value, "UserTags");
|
||||
}
|
||||
private string _measurementUnit = "V";
|
||||
/// <summary>
|
||||
/// measurement unit for collected data, for example
|
||||
/// 'V' or Volts
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string MeasurementUnit
|
||||
{
|
||||
get => _measurementUnit;
|
||||
set => SetProperty(ref _measurementUnit, value, "MeasurementUnit");
|
||||
}
|
||||
private IFilterClass _filterClass;
|
||||
/// <summary>
|
||||
/// software filter class (applied when viewing data) to apply to collected data by default
|
||||
/// can be changed when viewing or exporting, this is just a default filter
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public IFilterClass FilterClass
|
||||
{
|
||||
get => _filterClass;
|
||||
set => SetProperty(ref _filterClass, value, "FilterClass");
|
||||
}
|
||||
private bool _doNotUse = false;
|
||||
/// <summary>
|
||||
/// a flag indicating setting should not be used for arbitrary user specified reason
|
||||
/// </summary>
|
||||
public bool DoNotUse
|
||||
{
|
||||
get => _doNotUse;
|
||||
set => SetProperty(ref _doNotUse, value, "DoNotUse");
|
||||
}
|
||||
private bool _broken = false;
|
||||
/// <summary>
|
||||
/// a flag indicating setting should not be used because it is currently broken
|
||||
/// </summary>
|
||||
public bool Broken
|
||||
{
|
||||
get => _broken;
|
||||
set => SetProperty(ref _broken, value, "Broken");
|
||||
}
|
||||
public DigitalInDbRecord() { }
|
||||
public DigitalInDbRecord(ISensorData copy, byte [] tagBlockBytes, IDigitalInputScaleMultiplier digitalScaleMultiplier)
|
||||
{
|
||||
Id = copy.DatabaseId;
|
||||
SerialNumber = copy.SerialNumber;
|
||||
ISOCode = copy.ISOCode;
|
||||
ISOChannelName = copy.ISOChannelName;
|
||||
UserCode = copy.UserCode;
|
||||
UserChannelName = copy.UserChannelName;
|
||||
Broken = copy.Broken;
|
||||
DoNotUse = copy.DoNotUse;
|
||||
LastModified = copy.LastModified;
|
||||
LastModifiedBy = copy.LastUpdatedBy;
|
||||
Mode = copy.InputMode;
|
||||
MeasurementUnit = copy.DIUnits;
|
||||
FilterClass = new FilterClass(copy.FilterClass.FClass, copy.FilterClass.Frequency);
|
||||
ISOCode = copy.ISOCode;
|
||||
EID = copy.EID;
|
||||
UserValue1 = copy.UserValue1;
|
||||
UserValue2 = copy.UserValue2;
|
||||
UserValue3 = copy.UserValue3;
|
||||
if (null == tagBlockBytes) { UserTags = null; }
|
||||
else
|
||||
{
|
||||
if (tagBlockBytes.Any())
|
||||
{
|
||||
UserTags = new byte[tagBlockBytes.Length];
|
||||
Array.Copy(tagBlockBytes, UserTags, tagBlockBytes.Length);
|
||||
}
|
||||
else { UserTags = new byte[0]; }
|
||||
}
|
||||
ScaleMultiplier.FromDbSerializeString(digitalScaleMultiplier.ToSerializeDbString());
|
||||
}
|
||||
public DigitalInDbRecord(IDataReader reader)
|
||||
{
|
||||
Id = Utility.GetInt(reader, "Id", -1);
|
||||
SerialNumber = Utility.GetString(reader, "SerialNumber", string.Empty);
|
||||
ISOCode = Utility.GetString(reader, "ISOCode", string.Empty);
|
||||
ISOChannelName = Utility.GetString(reader, "ISOChannelName", string.Empty);
|
||||
UserCode = Utility.GetString(reader, "UserCode", string.Empty);
|
||||
UserChannelName = Utility.GetString(reader, "UserChannelName", string.Empty);
|
||||
Broken = Utility.GetBool(reader, "Broken", false);
|
||||
DoNotUse = Utility.GetBool(reader, "DoNotUse", false);
|
||||
LastModified = Utility.GetDateTime(reader, "LastModified", DateTime.MinValue);
|
||||
LastModifiedBy = Utility.GetString(reader, "LastModifiedBy", string.Empty);
|
||||
Mode = (DigitalInputModes)Utility.GetInt(reader,"SettingMode");
|
||||
MeasurementUnit = Utility.GetString(reader, "MeasurementUnit");
|
||||
FilterClass = new FilterClass(Utility.GetString(reader, "FilterClass"));
|
||||
if( ISOCode.Length< 16) { ISOCode = ISOCode.PadRight(16, '?'); }
|
||||
var s = ISOCode.ToCharArray();
|
||||
s[15] = '0';
|
||||
ISOCode = new string(s);
|
||||
|
||||
EID = Utility.GetString(reader, "eId", string.Empty);
|
||||
UserValue1 = Utility.GetString(reader, "UserValue1", string.Empty);
|
||||
UserValue2 = Utility.GetString(reader, "UserValue2", string.Empty);
|
||||
UserValue3 = Utility.GetString(reader, "UserValue3", string.Empty);
|
||||
UserTags = (byte[])reader["UserTags"];
|
||||
ScaleMultiplier.FromDbSerializeString(Utility.GetString(reader, "ScaleMultiplier"));
|
||||
}
|
||||
public DigitalInDbRecord(IDigitalInDbRecord copy)
|
||||
{
|
||||
Id = copy.Id;
|
||||
SerialNumber = copy.SerialNumber;
|
||||
ISOCode = copy.ISOCode;
|
||||
ISOChannelName = copy.ISOChannelName;
|
||||
UserCode = copy.UserCode;
|
||||
UserChannelName = copy.UserChannelName;
|
||||
Broken = copy.Broken;
|
||||
DoNotUse = copy.DoNotUse;
|
||||
LastModified = copy.LastModified;
|
||||
LastModifiedBy = copy.LastModifiedBy;
|
||||
Mode = copy.Mode;
|
||||
MeasurementUnit = copy.MeasurementUnit;
|
||||
FilterClass = new FilterClass(copy.FilterClass.FClass, copy.FilterClass.Frequency);
|
||||
ISOCode = copy.ISOCode;
|
||||
EID = copy.EID;
|
||||
UserValue1 = copy.UserValue1;
|
||||
UserValue2 = copy.UserValue2;
|
||||
UserValue3 = copy.UserValue3;
|
||||
if( null == copy.UserTags) { UserTags = null; }
|
||||
else
|
||||
{
|
||||
if(copy.UserTags.Any())
|
||||
{
|
||||
var userTags = new byte[copy.UserTags.Length];
|
||||
Array.Copy(copy.UserTags, userTags, copy.UserTags.Length);
|
||||
UserTags = userTags;
|
||||
}
|
||||
else { UserTags = new byte[0]; }
|
||||
}
|
||||
ScaleMultiplier.FromDbSerializeString(copy.ScaleMultiplier.ToSerializeDbString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using System;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
/// <summary>
|
||||
/// the scaler is a bit different than an ordinary scaler, so the name here is inaccurate, however the idea is
|
||||
/// that we allow the user to transform collected data, primarly by allowing them to define the 0,1 value of the digital output
|
||||
/// </summary>
|
||||
public class DigitalInputScaleMultiplier : IDigitalInputScaleMultiplier
|
||||
{
|
||||
public Forms Form { get; set; } = Forms.ArbitraryLowAndHigh;
|
||||
|
||||
/// <summary>
|
||||
/// for arbirary low/high, this is the low value, the value 0 should be displayed as (OFF)
|
||||
/// </summary>
|
||||
public double DefaultValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// for arbitrary low/high, this is the high value, the value 1 should be displayed as (ON)
|
||||
/// </summary>
|
||||
public double ActiveValue { get; set; } = 1D;
|
||||
|
||||
public bool SimpleEquals(IDigitalInputScaleMultiplier rhs)
|
||||
{
|
||||
return Form == rhs.Form && DefaultValue == rhs.DefaultValue && ActiveValue == rhs.ActiveValue;
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is DigitalInputScaleMultiplier)
|
||||
{
|
||||
var b = obj as DigitalInputScaleMultiplier;
|
||||
return b.Form == Form
|
||||
&& b.ActiveValue == ActiveValue
|
||||
&& b.DefaultValue == DefaultValue;
|
||||
}
|
||||
else { return false; }
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
//the idea here is to use two primes to avoid collisions, it's not perfect but should work in general and we can predict when it won't
|
||||
if (ActiveValue == 31 || DefaultValue == 31 || DefaultValue == 79 || ActiveValue == 79)
|
||||
{
|
||||
return (int)Form + Convert.ToInt32(ActiveValue * 127) + Convert.ToInt32(DefaultValue * 23);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)Form + Convert.ToInt32(ActiveValue * 31) + Convert.ToInt32(DefaultValue * 79);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// constructor and copy constructor
|
||||
/// </summary>
|
||||
public DigitalInputScaleMultiplier()
|
||||
{
|
||||
DefaultValue = 0D;
|
||||
}
|
||||
|
||||
public DigitalInputScaleMultiplier(DigitalInputScaleMultiplier copy)
|
||||
{
|
||||
Form = copy.Form;
|
||||
DefaultValue = copy.DefaultValue;
|
||||
ActiveValue = copy.ActiveValue;
|
||||
}
|
||||
/// <summary>
|
||||
/// serializes scaler to a string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ToSerializeDbString()
|
||||
{
|
||||
switch (Form)
|
||||
{
|
||||
case Forms.ArbitraryLowAndHigh: return ToSerializeDbStringLowAndHigh();
|
||||
default: throw new NotSupportedException("DigitalScaleMultiplier::ToSerializeDbString unsupported form: " + Form);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// serializes an ArbitraryLowHigh to a string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string ToSerializeDbStringLowAndHigh() { return string.Format("{1}{0}{2}{0}{3}", System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator, Form, DefaultValue.ToString(System.Globalization.CultureInfo.InvariantCulture), ActiveValue.ToString(System.Globalization.CultureInfo.InvariantCulture)); }
|
||||
/// <summary>
|
||||
/// deserializes an arbitrary low/high from a string
|
||||
/// </summary>
|
||||
/// <param name="tokens"></param>
|
||||
private void FromDbSerializeStringLowAndHigh(string[] tokens)
|
||||
{
|
||||
if (tokens.Length < 3) { throw new NotSupportedException("DigitalInputScaleMultiplier::FromDbSerializeStringLowAndHigh invalid format for scale multiplier"); }
|
||||
if (double.TryParse(tokens[1], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out double d))
|
||||
{
|
||||
DefaultValue = d;
|
||||
}
|
||||
else { throw new NotSupportedException("DigitalInputScaleMultiplier::FromDbSerializeStringLowAndHigh invalid format for low value: " + tokens[1]); }
|
||||
|
||||
if (double.TryParse(tokens[2], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out d))
|
||||
{
|
||||
ActiveValue = d;
|
||||
}
|
||||
else { throw new NotSupportedException("DigitalInputScaleMultiplier::FromDbSerializeStringLowAndHigh invalid format for high value: " + tokens[2]); }
|
||||
}
|
||||
/// <summary>
|
||||
/// deserializes a scaler from a string, regardless of format
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public void FromDbSerializeString(string s)
|
||||
{
|
||||
if (null == s)
|
||||
{
|
||||
Utilities.Logging.APILogger.Log("Unable to serialize Db. String is null.");
|
||||
|
||||
//FIXME is this the right thing to do?
|
||||
return;
|
||||
//throw new NotSupportedException("DigitalINputScaleMultiplier::FromDbSerializeString nothing to parse");
|
||||
}
|
||||
|
||||
var tokens = s.Split(new[] { System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None);
|
||||
if (Enum.TryParse(tokens[0], out Forms form))
|
||||
{
|
||||
Form = form;
|
||||
switch (form)
|
||||
{
|
||||
case Forms.ArbitraryLowAndHigh: FromDbSerializeStringLowAndHigh(tokens); break;
|
||||
default: throw new NotSupportedException("DigitalInputScaleMultiplier::FromDbSerializeString unsupported form " + form);
|
||||
}
|
||||
}
|
||||
else { throw new NotSupportedException("DigitalINputScaleMultiplier::FromDbSerializeString unsupported format: " + s); }
|
||||
}
|
||||
}
|
||||
}
|
||||
180
Common/DTS.CommonCore/Classes/Sensors/DigitalOutDbRecord.cs
Normal file
180
Common/DTS.CommonCore/Classes/Sensors/DigitalOutDbRecord.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using DTS.Common.Base;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class DigitalOutDbRecord : BasePropertyChanged, IDigitalOutDbRecord
|
||||
{
|
||||
private string _serialNumber = "";
|
||||
public string SerialNumber
|
||||
{
|
||||
get => _serialNumber;
|
||||
set => SetProperty(ref _serialNumber, value, "SerialNumber");
|
||||
}
|
||||
|
||||
private double _doDelay = 0D;
|
||||
public double DODelay
|
||||
{
|
||||
get => _doDelay;
|
||||
set => SetProperty(ref _doDelay, value, "DODelay");
|
||||
}
|
||||
|
||||
private double _doDuration = 0D;
|
||||
public double DODuration
|
||||
{
|
||||
get => _doDuration;
|
||||
set => SetProperty(ref _doDuration, value, "DODuration");
|
||||
}
|
||||
private string _modifiedBy = "";
|
||||
public string ModifiedBy
|
||||
{
|
||||
get => _modifiedBy;
|
||||
set => SetProperty(ref _modifiedBy, value, "ModifiedBy");
|
||||
}
|
||||
private DateTime _lastModified = DateTime.MinValue;
|
||||
public DateTime LastModified
|
||||
{
|
||||
get => _lastModified;
|
||||
set => SetProperty(ref _lastModified, value, "LastModified");
|
||||
}
|
||||
private int _databaseId = -1;
|
||||
public int DatabaseId
|
||||
{
|
||||
get => _databaseId;
|
||||
set => SetProperty(ref _databaseId, value, "DatabaseId");
|
||||
}
|
||||
private string _isoCode = "";
|
||||
public string ISOCode
|
||||
{
|
||||
get => _isoCode;
|
||||
set => SetProperty(ref _isoCode, value, "ISOCode");
|
||||
}
|
||||
private string _isoChannelName = "";
|
||||
public string ISOChannelName
|
||||
{
|
||||
get => _isoChannelName;
|
||||
set => SetProperty(ref _isoChannelName, value, "ISOChannelName");
|
||||
}
|
||||
private string _userCode = "";
|
||||
public string UserCode
|
||||
{
|
||||
get => _userCode;
|
||||
set => SetProperty(ref _userCode, value, "UserCode");
|
||||
}
|
||||
private string _userChannelName = "";
|
||||
public string UserChannelName
|
||||
{
|
||||
get => _userChannelName;
|
||||
set => SetProperty(ref _userChannelName, value, "UserChannelName");
|
||||
}
|
||||
private bool _broken = false;
|
||||
public bool Broken
|
||||
{
|
||||
get => _broken;
|
||||
set => SetProperty(ref _broken, value, "Broken");
|
||||
}
|
||||
private bool _doNotUse = false;
|
||||
public bool DoNotUse
|
||||
{
|
||||
get => _doNotUse;
|
||||
set => SetProperty(ref _doNotUse, value, "DoNotUse");
|
||||
}
|
||||
private DigitalOutputModes _doMode = DigitalOutputModes.CCNC;
|
||||
public DigitalOutputModes DOMode
|
||||
{
|
||||
get => _doMode;
|
||||
set => SetProperty(ref _doMode, value, "DOMode");
|
||||
}
|
||||
private bool _limitDuration = true;
|
||||
public bool LimitDuration
|
||||
{
|
||||
get => _limitDuration;
|
||||
set => SetProperty(ref _limitDuration, value, "LimitDuration");
|
||||
}
|
||||
|
||||
private int _version = 0;
|
||||
public int Version
|
||||
{
|
||||
get => _version;
|
||||
set => SetProperty(ref _version, value, "Version");
|
||||
}
|
||||
private byte[] _tagsBlobBytes = null;
|
||||
public byte [] TagsBlobBytes
|
||||
{
|
||||
get => _tagsBlobBytes;
|
||||
set => SetProperty(ref _tagsBlobBytes, value, "TagsBlobBytes");
|
||||
}
|
||||
public DigitalOutDbRecord()
|
||||
{
|
||||
}
|
||||
public DigitalOutDbRecord(ISensorData copy, byte [] tagsBlobBytes)
|
||||
{
|
||||
SerialNumber = copy.SerialNumber;
|
||||
DatabaseId = copy.DatabaseId;
|
||||
Broken = copy.Broken;
|
||||
DoNotUse = copy.DoNotUse;
|
||||
Version = copy.Version;
|
||||
DOMode = copy.DigitalOutputMode;
|
||||
LimitDuration = copy.DigitalOutputLimitDuration;
|
||||
ModifiedBy = copy.LastUpdatedBy;
|
||||
LastModified = copy.LastModified;
|
||||
DODuration = copy.DigitalOutputDurationMS;
|
||||
DODelay = copy.DigitalOutputDelayMS;
|
||||
if (null == tagsBlobBytes)
|
||||
{
|
||||
TagsBlobBytes = null;
|
||||
}
|
||||
else if (tagsBlobBytes.Any())
|
||||
{
|
||||
var bytes = new byte[tagsBlobBytes.Length];
|
||||
Array.Copy(tagsBlobBytes, bytes, tagsBlobBytes.Length);
|
||||
TagsBlobBytes = bytes;
|
||||
}
|
||||
else { TagsBlobBytes = new byte[0]; }
|
||||
}
|
||||
public DigitalOutDbRecord(IDigitalOutDbRecord copy)
|
||||
{
|
||||
SerialNumber = copy.SerialNumber;
|
||||
DatabaseId = copy.DatabaseId;
|
||||
Broken = copy.Broken;
|
||||
DoNotUse = copy.DoNotUse;
|
||||
Version = copy.Version;
|
||||
DOMode = copy.DOMode;
|
||||
LimitDuration = copy.LimitDuration;
|
||||
ModifiedBy = copy.ModifiedBy;
|
||||
LastModified = copy.LastModified;
|
||||
DODuration = copy.DODuration;
|
||||
DODelay = copy.DODelay;
|
||||
if( null == copy.TagsBlobBytes)
|
||||
{
|
||||
TagsBlobBytes = null;
|
||||
}
|
||||
else if(copy.TagsBlobBytes.Any())
|
||||
{
|
||||
var tagsBlobBytes = new byte[copy.TagsBlobBytes.Length];
|
||||
Array.Copy(copy.TagsBlobBytes, tagsBlobBytes, copy.TagsBlobBytes.Length);
|
||||
TagsBlobBytes = tagsBlobBytes;
|
||||
}
|
||||
else { TagsBlobBytes = new byte[0]; }
|
||||
}
|
||||
public DigitalOutDbRecord(IDataReader reader)
|
||||
{
|
||||
DatabaseId = Utility.GetInt(reader, "Id", -1);
|
||||
Broken = Utility.GetBool(reader, "Broken", false);
|
||||
DoNotUse = Utility.GetBool(reader, "DoNotUse");
|
||||
SerialNumber = Utility.GetString(reader, "SerialNumber");
|
||||
Version = Utility.GetInt(reader, "Version");
|
||||
DOMode = (DigitalOutputModes)Utility.GetInt(reader, "OutputMode");
|
||||
LimitDuration = Utility.GetBool(reader, "LimitDuration", true);
|
||||
ModifiedBy = Utility.GetString(reader, "LastModifiedBy", string.Empty);
|
||||
LastModified = Utility.GetDateTime(reader, "LastModified", DateTime.MinValue);
|
||||
DODuration = Utility.GetDouble(reader, "DurationMSFloat");
|
||||
DODelay = Utility.GetDouble(reader, "DelayMS");
|
||||
TagsBlobBytes = (byte[])reader["UserTags"];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class DisplayedCalibrationBehavior
|
||||
{
|
||||
public DTS.Common.Enums.Sensors.CalibrationBehaviors CalibrationBehavior;
|
||||
public string DisplayString;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return DisplayString;
|
||||
}
|
||||
}
|
||||
}
|
||||
632
Common/DTS.CommonCore/Classes/Sensors/FilterClass.cs
Normal file
632
Common/DTS.CommonCore/Classes/Sensors/FilterClass.cs
Normal file
@@ -0,0 +1,632 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Sensors.SoftwareFilters;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class FilterClass : INotifyPropertyChanged, IFilterClass
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected bool SetProperty<T>(ref T storage, T value, String propertyName = null)
|
||||
{
|
||||
if (Equals(storage, value)) return false;
|
||||
|
||||
storage = value;
|
||||
OnPropertyChanged(propertyName);
|
||||
return true;
|
||||
}
|
||||
protected void OnPropertyChanged(string propertyName = null)
|
||||
{
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public FilterClassType FClass { get; set; }
|
||||
|
||||
//FB 13120 used for filter options drop down localization
|
||||
public string FilterName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name = "";
|
||||
|
||||
if (FClass == FilterClassType.None)
|
||||
{
|
||||
name = Strings.Strings.FilterClassType_None;
|
||||
}
|
||||
else if (FClass == FilterClassType.Unfiltered)
|
||||
{
|
||||
name = Strings.Strings.FilterClassType_Unfiltered;
|
||||
}
|
||||
else if (FClass == FilterClassType.AdHoc)
|
||||
{
|
||||
name = Frequency.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
name = Frequency + " (" + FClass.ToString() + ")";
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the numeric filter class value for the filter class; EX CFC60 returns 60, CFC1000 returns 1000
|
||||
/// </summary>
|
||||
/// <returns>integer for filter class name</returns>
|
||||
public int GetFilterClassNumericValue()
|
||||
{
|
||||
switch (FClass)
|
||||
{
|
||||
|
||||
case FilterClassType.CFC10:
|
||||
return 10;
|
||||
case FilterClassType.CFC60:
|
||||
return 60;
|
||||
case FilterClassType.CFC180:
|
||||
return 180;
|
||||
case FilterClassType.CFC600:
|
||||
return 600;
|
||||
case FilterClassType.None:
|
||||
return 0;
|
||||
case FilterClassType.Unfiltered:
|
||||
return -2;
|
||||
default: // adhoc and cfc1000 enter here
|
||||
return 1000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private double _Frequency;
|
||||
public double Frequency
|
||||
{
|
||||
get { return _Frequency; }
|
||||
set { _Frequency = value; }
|
||||
}
|
||||
|
||||
#region Tags
|
||||
|
||||
internal const string FilterClassTag = "FilterClass";
|
||||
internal const string ClassTag = "Class";
|
||||
internal const string FrequencyTag = "Frequency";
|
||||
|
||||
#endregion
|
||||
private string TableName;
|
||||
public FilterClass(XElement elem, string prefix, string tblName, string id)
|
||||
{
|
||||
TableName = tblName;
|
||||
XElement inner = null;
|
||||
try
|
||||
{
|
||||
inner = elem.Element(mkTag(prefix));
|
||||
}
|
||||
catch (ArgumentNullException)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
throw new System.Exception(string.Format("{0}: Can't find tag {1} for entry {2}", TableName, prefix + "-" + FilterClassTag, id));
|
||||
}
|
||||
throw new System.Exception(string.Format("{0}: Can't find tag {1} in file", TableName, prefix + "-" + FilterClassTag));
|
||||
}
|
||||
FClass = (FilterClassType)Enum.Parse(typeof(FilterClassType), inner.Attribute(ClassTag).Value);
|
||||
switch (FClass)
|
||||
{
|
||||
case FilterClassType.None:
|
||||
_Frequency = (double)FilterClassType.None;
|
||||
break;
|
||||
case FilterClassType.Unfiltered:
|
||||
_Frequency = (double)FilterClassType.Unfiltered;
|
||||
break;
|
||||
case FilterClassType.CFC10:
|
||||
_Frequency = (double)FilterClassType.CFC10;
|
||||
break;
|
||||
case FilterClassType.CFC60:
|
||||
_Frequency = (double)FilterClassType.CFC60;
|
||||
break;
|
||||
case FilterClassType.CFC180:
|
||||
_Frequency = (double)FilterClassType.CFC180;
|
||||
break;
|
||||
case FilterClassType.CFC600:
|
||||
_Frequency = (double)FilterClassType.CFC600;
|
||||
break;
|
||||
case FilterClassType.CFC1000:
|
||||
_Frequency = (double)FilterClassType.CFC1000;
|
||||
break;
|
||||
case FilterClassType.AdHoc:
|
||||
if (!double.TryParse(inner.Value, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out _Frequency))
|
||||
{
|
||||
throw new System.Exception(string.Format("{0}: Invalid filter frequency {1}", TableName, inner.Value));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public FilterClass(FilterClassType fc, double freq)
|
||||
{
|
||||
FClass = fc;
|
||||
Frequency = freq;
|
||||
}
|
||||
|
||||
public static FilterClassType GetFilterClassTypeFromNumericFC(int fc)
|
||||
{
|
||||
switch (fc)
|
||||
{
|
||||
case 1000:
|
||||
case -1:
|
||||
return FilterClassType.CFC1000;
|
||||
case 600:
|
||||
return FilterClassType.CFC600;
|
||||
case 180:
|
||||
return FilterClassType.CFC180;
|
||||
case 60:
|
||||
return FilterClassType.CFC60;
|
||||
case 10:
|
||||
return FilterClassType.CFC10;
|
||||
case 0:
|
||||
return FilterClassType.None;
|
||||
case -2:
|
||||
return FilterClassType.Unfiltered;
|
||||
default:
|
||||
return FilterClassType.None;
|
||||
}
|
||||
}
|
||||
|
||||
public FilterClass(double freq)
|
||||
{
|
||||
Frequency = freq;
|
||||
if (freq == (double)FilterClassType.CFC10)
|
||||
{
|
||||
FClass = FilterClassType.CFC10;
|
||||
}
|
||||
else if (freq == (double)FilterClassType.CFC60)
|
||||
{
|
||||
FClass = FilterClassType.CFC60;
|
||||
}
|
||||
else if (freq == (double)FilterClassType.CFC180)
|
||||
{
|
||||
FClass = FilterClassType.CFC180;
|
||||
}
|
||||
else if (freq == (double)FilterClassType.CFC600)
|
||||
{
|
||||
FClass = FilterClassType.CFC600;
|
||||
}
|
||||
else if (freq == (double)FilterClassType.CFC1000)
|
||||
{
|
||||
FClass = FilterClassType.CFC1000;
|
||||
}
|
||||
else if (freq == 0)
|
||||
{
|
||||
FClass = FilterClassType.None;
|
||||
}
|
||||
else if (freq == (double)FilterClassType.Unfiltered)
|
||||
{
|
||||
FClass = FilterClassType.Unfiltered;
|
||||
}
|
||||
else
|
||||
{
|
||||
FClass = FilterClassType.AdHoc;
|
||||
//FB 13120 set the frequency for ad hoc filters
|
||||
Frequency = freq;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///FB 13120 Specify and return the default filter class
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static FilterClass GetDefaultFilterClass(List<ISoftwareFilter> softwareFilters)
|
||||
{
|
||||
if (softwareFilters == null)
|
||||
{
|
||||
return new FilterClass(FilterClassType.CFC1000);
|
||||
}
|
||||
|
||||
var softwareFilter = softwareFilters.FirstOrDefault(p => p.IsDefault);
|
||||
FilterClass fc = null;
|
||||
|
||||
switch (softwareFilter?.ISOCode)
|
||||
{
|
||||
case '0':
|
||||
fc = new FilterClass(FilterClassType.Unfiltered);
|
||||
break;
|
||||
case 'P':
|
||||
fc = new FilterClass(FilterClassType.None);
|
||||
break;
|
||||
case 'S':
|
||||
fc = new FilterClass(FilterClassType.AdHoc, softwareFilter.Frequency);
|
||||
break;
|
||||
case 'A':
|
||||
fc = new FilterClass(FilterClassType.CFC1000);
|
||||
break;
|
||||
case 'B':
|
||||
fc = new FilterClass(FilterClassType.CFC600);
|
||||
break;
|
||||
case 'C':
|
||||
fc = new FilterClass(FilterClassType.CFC180);
|
||||
break;
|
||||
case 'D':
|
||||
fc = new FilterClass(FilterClassType.CFC60);
|
||||
break;
|
||||
default:
|
||||
fc = new FilterClass(FilterClassType.CFC1000);
|
||||
break;
|
||||
}
|
||||
|
||||
return fc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// FB 13120 Get the filter class based on the isoCode provided
|
||||
/// </summary>
|
||||
/// <param name="isoCode"></param>
|
||||
/// <param name="frequency">this frequency will be used for AdHoc filter</param>
|
||||
/// <returns></returns>
|
||||
public static FilterClass GetFilterClassFromIsoCode(string isoCode, double frequency = 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(isoCode))
|
||||
{
|
||||
return new FilterClass(FilterClassType.CFC1000);
|
||||
}
|
||||
FilterClass fc = null;
|
||||
|
||||
switch (isoCode.ToUpper())
|
||||
{
|
||||
case "0":
|
||||
fc = new FilterClass(FilterClassType.Unfiltered);
|
||||
break;
|
||||
case "P":
|
||||
fc = new FilterClass(FilterClassType.None);
|
||||
break;
|
||||
case "S":
|
||||
fc = new FilterClass(FilterClassType.AdHoc, frequency);
|
||||
break;
|
||||
case "A":
|
||||
fc = new FilterClass(FilterClassType.CFC1000);
|
||||
break;
|
||||
case "B":
|
||||
fc = new FilterClass(FilterClassType.CFC600);
|
||||
break;
|
||||
case "C":
|
||||
fc = new FilterClass(FilterClassType.CFC180);
|
||||
break;
|
||||
case "D":
|
||||
fc = new FilterClass(FilterClassType.CFC60);
|
||||
break;
|
||||
default:
|
||||
fc = new FilterClass(FilterClassType.CFC1000);
|
||||
break;
|
||||
}
|
||||
|
||||
return fc;
|
||||
}
|
||||
/// <summary>
|
||||
/// FB 15574 Get the FilterClass setting from cfc iso code
|
||||
/// </summary>
|
||||
/// <param name="cfcIsoCode">cfc iso code ex: A</param>
|
||||
/// <returns>filter class setting on format of FilterType,Frequency ex: None,0 </returns>
|
||||
public static string GetFilterClassSettingFromCFC(string cfcIsoCode)
|
||||
{
|
||||
var filterClass = GetFilterClassFromIsoCode(cfcIsoCode);
|
||||
return $"{filterClass.FClass.ToString()},{filterClass.Frequency}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///FB 15574 Get the FilterClass setting from FilterClass
|
||||
/// </summary>
|
||||
/// <param name="filterClass"></param>
|
||||
/// <returns>filter class setting on format of FilterType,Frequency ex: None,0 </returns>
|
||||
public static string GetFilterClassSettingFromFilterClass(IFilterClass filterClass)
|
||||
{
|
||||
return $"{filterClass.FClass.ToString()},{filterClass.Frequency}";
|
||||
}
|
||||
|
||||
public static double GetFrequencyFromFilterClassType(FilterClassType filterClassType)
|
||||
{
|
||||
if (filterClassType == FilterClassType.AdHoc)
|
||||
{
|
||||
throw new Exception("GetFrequencyFromFilterClassType: AdHoc FilterClassType does not have frequency associated");
|
||||
}
|
||||
return (double)filterClassType;
|
||||
}
|
||||
|
||||
public static FilterClass GetFilterClassFromFilterClassType(FilterClassType filterClassType, double adHocFrequency = 0)
|
||||
{
|
||||
if (filterClassType == FilterClassType.AdHoc)
|
||||
{
|
||||
return new FilterClass(filterClassType, adHocFrequency);
|
||||
}
|
||||
return new FilterClass(filterClassType);
|
||||
}
|
||||
|
||||
public static FilterClass GetFilterClassFromFilterClassSetting(string filterClassSetting)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filterClassSetting))
|
||||
{
|
||||
return GetFilterClassFromFilterClassType(FilterClassType.Unfiltered);
|
||||
}
|
||||
|
||||
var setting = filterClassSetting.Split(',');
|
||||
|
||||
if (Enum.TryParse(setting[0], out FilterClassType fct))
|
||||
{
|
||||
return GetFilterClassFromFilterClassType(fct, Convert.ToDouble(setting[1]));
|
||||
}
|
||||
|
||||
return GetFilterClassFromFilterClassType(FilterClassType.Unfiltered);
|
||||
}
|
||||
public FilterClass(FilterClassType fc)
|
||||
{
|
||||
FClass = fc;
|
||||
switch (fc)
|
||||
{
|
||||
case FilterClassType.None:
|
||||
Frequency = 0;
|
||||
break;
|
||||
case FilterClassType.AdHoc:
|
||||
Frequency = (double) FilterClassType.AdHoc;
|
||||
break;
|
||||
case FilterClassType.Unfiltered:
|
||||
Frequency = (double)FilterClassType.Unfiltered;
|
||||
break;
|
||||
case FilterClassType.CFC10:
|
||||
Frequency = (double)FilterClassType.CFC10;
|
||||
break;
|
||||
case FilterClassType.CFC60:
|
||||
Frequency = (double)FilterClassType.CFC60;
|
||||
break;
|
||||
case FilterClassType.CFC180:
|
||||
Frequency = (double)FilterClassType.CFC180;
|
||||
break;
|
||||
case FilterClassType.CFC600:
|
||||
Frequency = (double)FilterClassType.CFC600;
|
||||
break;
|
||||
case FilterClassType.CFC1000:
|
||||
Frequency = (double)FilterClassType.CFC1000;
|
||||
break;
|
||||
default:
|
||||
throw new System.Exception("FilterClass: unknown class");
|
||||
}
|
||||
}
|
||||
|
||||
public XElement ToXElement(string prefix)
|
||||
{
|
||||
var element = new XElement(mkTag(prefix), Frequency);
|
||||
element.SetAttributeValue(ClassTag, FClass.ToString());
|
||||
return element;
|
||||
}
|
||||
|
||||
public void Update(XElement elem, string prefix)
|
||||
{
|
||||
elem.SetElementValue(mkTag(prefix), Frequency);
|
||||
var element = elem.Element(mkTag(prefix));
|
||||
element.SetAttributeValue(ClassTag, FClass.ToString());
|
||||
}
|
||||
|
||||
public static string mkTag(string prefix)
|
||||
{
|
||||
return prefix + "-" + FilterClassTag;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
switch (FClass)
|
||||
{
|
||||
case FilterClassType.None:
|
||||
return "None";
|
||||
case FilterClassType.Unfiltered:
|
||||
return "Unfiltered";
|
||||
case FilterClassType.CFC10:
|
||||
return string.Format("{0} (CFC10)", (int)FilterClassType.CFC10);
|
||||
case FilterClassType.CFC60:
|
||||
return string.Format("{0} (CFC60)", (int)FilterClassType.CFC60);
|
||||
case FilterClassType.CFC180:
|
||||
return string.Format("{0} (CFC180)", (int)FilterClassType.CFC180);
|
||||
case FilterClassType.CFC600:
|
||||
return string.Format("{0} (CFC600)", (int)FilterClassType.CFC600);
|
||||
case FilterClassType.CFC1000:
|
||||
return string.Format("{0} (CFC1000)", (int)FilterClassType.CFC1000);
|
||||
case FilterClassType.AdHoc:
|
||||
return ((int)Frequency).ToString();
|
||||
}
|
||||
throw new System.Exception("FilterClass.ToString: Invalid class=" + FClass.ToString());
|
||||
}
|
||||
|
||||
public FilterClass(string fclass)
|
||||
{
|
||||
int fc;
|
||||
if (int.TryParse(fclass, NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out fc))
|
||||
{
|
||||
switch (fc)
|
||||
{
|
||||
case 17:
|
||||
FClass = FilterClassType.CFC10;
|
||||
_Frequency = (double) FClass;
|
||||
return;
|
||||
case 100:
|
||||
FClass = FilterClassType.CFC60;
|
||||
_Frequency = (double) FClass;
|
||||
return;
|
||||
case 300:
|
||||
FClass = FilterClassType.CFC180;
|
||||
_Frequency = (double) FClass;
|
||||
return;
|
||||
case 1000:
|
||||
FClass = FilterClassType.CFC600;
|
||||
_Frequency = (double) FClass;
|
||||
return;
|
||||
case 1650:
|
||||
FClass = FilterClassType.CFC1000;
|
||||
_Frequency = (double) FClass;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(fclass) || fclass == "None")
|
||||
{
|
||||
FClass = FilterClassType.None;
|
||||
}
|
||||
else if (fclass.Contains("Unfiltered"))
|
||||
{
|
||||
FClass = FilterClassType.Unfiltered;
|
||||
_Frequency = (double)FilterClassType.Unfiltered;
|
||||
}
|
||||
else if (fclass.Contains("CFC1000"))
|
||||
{
|
||||
FClass = FilterClassType.CFC1000;
|
||||
_Frequency = (double)FilterClassType.CFC1000;
|
||||
}
|
||||
else if (fclass.Contains("CFC600"))
|
||||
{
|
||||
FClass = FilterClassType.CFC600;
|
||||
_Frequency = (double)FilterClassType.CFC600;
|
||||
}
|
||||
else if (fclass.Contains("CFC60"))
|
||||
{
|
||||
FClass = FilterClassType.CFC60;
|
||||
_Frequency = (double)FilterClassType.CFC60;
|
||||
}
|
||||
else if (fclass.Contains("CFC180"))
|
||||
{
|
||||
FClass = FilterClassType.CFC180;
|
||||
_Frequency = (double)FilterClassType.CFC180;
|
||||
}
|
||||
else
|
||||
{
|
||||
//FB 13120 parse and set frequncy
|
||||
double freq = 0;
|
||||
if (double.TryParse(fclass, out freq))
|
||||
{
|
||||
FClass = FilterClassType.AdHoc;
|
||||
_Frequency = freq;
|
||||
}
|
||||
else
|
||||
{
|
||||
FClass = FilterClassType.CFC1000;
|
||||
_Frequency = (double)FilterClassType.CFC1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(obj is FilterClass))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var filterObj = obj as FilterClass;
|
||||
//FB 13120 needs this since the frequency would be different (-2 & 0) for unfiltered case
|
||||
if (FClass == filterObj.FClass && FClass == FilterClassType.Unfiltered)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return FClass == filterObj.FClass && Frequency == filterObj.Frequency;
|
||||
}
|
||||
|
||||
public int CompareTo(object filterClass)
|
||||
{
|
||||
IFilterClass fc = filterClass as FilterClass;
|
||||
if (this == null)
|
||||
{
|
||||
if (fc == null)
|
||||
{
|
||||
// both null, equal
|
||||
return 0;
|
||||
}
|
||||
// left null but not right
|
||||
return -1;
|
||||
}
|
||||
if (fc == null)
|
||||
{
|
||||
// left not null, right null
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (this.FClass != FilterClassType.None)
|
||||
return fc.FClass == FilterClassType.None ? 1 : this.Frequency.CompareTo(fc.Frequency);
|
||||
if (fc.FClass == FilterClassType.None)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns an identical hash index for any two "equal" filterclass objects
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
//.equals compares frequency and class, but we just need to guarantee that
|
||||
//equal objects hash to the same index
|
||||
return Convert.ToInt32(Frequency);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// FB 13120 Factory method to create a filter class
|
||||
/// </summary>
|
||||
/// <param name="fc"></param>
|
||||
/// <param name="frequency"></param>
|
||||
/// <returns></returns>
|
||||
public static IFilterClass CreateFilterClass(FilterClassType fc, double frequency = 0)
|
||||
{
|
||||
if (fc == FilterClassType.AdHoc)
|
||||
{
|
||||
return new FilterClass(frequency);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new FilterClass(fc);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the filter class based on the string cfc
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
public static IFilterClass GetFilterClassFromString(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s)) return new FilterClass(FilterClassType.Unfiltered);
|
||||
s = s.ToLower().Replace("cfc", "").Replace("hz", "").Trim();
|
||||
double freq = 0;
|
||||
if (double.TryParse(s, out freq))
|
||||
{
|
||||
switch (freq)
|
||||
{
|
||||
case 10:
|
||||
return new FilterClass(FilterClassType.CFC10);
|
||||
case 60:
|
||||
return new FilterClass(FilterClassType.CFC60);
|
||||
case 180:
|
||||
return new FilterClass(FilterClassType.CFC180);
|
||||
case 600:
|
||||
return new FilterClass(FilterClassType.CFC600);
|
||||
case 1000:
|
||||
return new FilterClass(FilterClassType.CFC1000);
|
||||
default:
|
||||
return new FilterClass(FilterClassType.AdHoc, freq);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (s.ToLower())
|
||||
{
|
||||
case "unfiltered":
|
||||
return new FilterClass(FilterClassType.Unfiltered);
|
||||
case "none":
|
||||
return new FilterClass(FilterClassType.None);
|
||||
default:
|
||||
return new FilterClass(FilterClassType.Unfiltered);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
392
Common/DTS.CommonCore/Classes/Sensors/InitialOffset.cs
Normal file
392
Common/DTS.CommonCore/Classes/Sensors/InitialOffset.cs
Normal file
@@ -0,0 +1,392 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using DTS.Common.Converters;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// InitialOffset is the replacement for InitialEU
|
||||
/// it encompasses the old InitialOffset specified in EU with a offset of specifying it in mV @EU
|
||||
/// Initial EU is a post data collection adjustment to engineering units recorded
|
||||
/// </summary>
|
||||
public class InitialOffset : Base.BasePropertyChanged
|
||||
{
|
||||
/// <summary>
|
||||
/// copy constructor
|
||||
/// </summary>
|
||||
/// <param name="copy"></param>
|
||||
public InitialOffset(InitialOffset copy)
|
||||
{
|
||||
if (null == copy) { return; }
|
||||
EU = copy.EU;
|
||||
MV = copy.MV;
|
||||
Form = copy.Form;
|
||||
}
|
||||
/// <summary>
|
||||
/// default constructor
|
||||
/// </summary>
|
||||
public InitialOffset()
|
||||
{
|
||||
Form = InitialOffsetTypes.None;
|
||||
EU = 0D;
|
||||
MV = 0D;
|
||||
}
|
||||
/// <summary>
|
||||
/// constructor for the old format Initial EU (a single double representing offset in EU)
|
||||
/// </summary>
|
||||
/// <param name="d"></param>
|
||||
public InitialOffset(double d)
|
||||
{
|
||||
Form = InitialOffsetTypes.EU;
|
||||
EU = d;
|
||||
MV = 0D;
|
||||
}
|
||||
/// <summary>
|
||||
/// constructor for string from db
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public InitialOffset(string s)
|
||||
{
|
||||
FromDbSerializeString(s);
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
var converter = new EnumDescriptionTypeConverter(typeof(InitialOffsetTypes));
|
||||
return converter.ConvertToString(Form);
|
||||
}
|
||||
/// <summary>
|
||||
/// serializes to a db safe string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ToDbSerializeString()
|
||||
{
|
||||
var s = new List<string>
|
||||
{
|
||||
Form.ToString(),
|
||||
EU.ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
MV.ToString(System.Globalization.CultureInfo.InvariantCulture)
|
||||
};
|
||||
return string.Join(System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator, s.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// deserializes from a string suitable for db storage
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
public void FromDbSerializeString(string input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
{
|
||||
Form = InitialOffsetTypes.None;
|
||||
EU = 0;
|
||||
MV = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (input == "EU")
|
||||
{
|
||||
Form = InitialOffsetTypes.EU;
|
||||
EU = 0;
|
||||
return;
|
||||
}
|
||||
if (input.Contains(InitialOffsets.MySeparator))
|
||||
{
|
||||
//we got an InputOffsets input. just take the first one
|
||||
input = input.Split(new [] {InitialOffsets.MySeparator}, StringSplitOptions.RemoveEmptyEntries)[0];
|
||||
}
|
||||
|
||||
var tokens = input.Split(new string[] { System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None);
|
||||
|
||||
if (Enum.TryParse(tokens[0], out InitialOffsetTypes form))
|
||||
{
|
||||
Form = form;
|
||||
if (tokens.Length < 3)
|
||||
{
|
||||
throw new System.IO.InvalidDataException($"Invalid InitialOffset number of parameters: {input}");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (double.TryParse(tokens[1], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var d))
|
||||
{
|
||||
EU = d;
|
||||
}
|
||||
else { throw new FormatException($"Invalid InitialOffset EU format: {tokens[1]}"); }
|
||||
if (double.TryParse(tokens[2], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out d))
|
||||
{
|
||||
MV = d;
|
||||
}
|
||||
else { throw new FormatException($"Invalid InitialOffset MV format: {tokens[2]}"); }
|
||||
}
|
||||
}
|
||||
else { throw new System.IO.InvalidDataException("Invalid InitialOffset form: " + tokens[0]); }
|
||||
}
|
||||
|
||||
private InitialOffsetTypes _form;
|
||||
|
||||
/// <summary>
|
||||
/// the format this intial offset instance is in
|
||||
/// </summary>
|
||||
public InitialOffsetTypes Form
|
||||
{
|
||||
get => _form;
|
||||
set => SetProperty(ref _form, value, Fields.Form.ToString());
|
||||
}
|
||||
|
||||
//FB18158 Don't allow removal of None option
|
||||
public System.Windows.Visibility InitialOffsetVisibility
|
||||
{
|
||||
get => Form != InitialOffsetTypes.None ? System.Windows.Visibility.Visible: System.Windows.Visibility.Hidden;
|
||||
}
|
||||
|
||||
private double _eu = 0D;
|
||||
|
||||
/// <summary>
|
||||
/// EU value. In the case of Form == EU, this is the offset in EU
|
||||
/// In. the form of EU@mV, this is the EU@mV value, and offset in EU still needs to be calculated
|
||||
/// GetInitialEUValue calculates the offset in eu
|
||||
/// this value is not used for InitialOffset format None
|
||||
/// </summary>
|
||||
public double EU
|
||||
{
|
||||
get => _eu;
|
||||
set => SetProperty(ref _eu, value, Fields.EU.ToString());
|
||||
}
|
||||
|
||||
private double _mv = 0D;
|
||||
|
||||
/// <summary>
|
||||
/// mV value, only applies for the format EU@mV
|
||||
/// this is the value in mV that The value in EU is observed at by a calibrated instrument
|
||||
/// </summary>
|
||||
public double MV
|
||||
{
|
||||
get => _mv;
|
||||
set => SetProperty(ref _mv, value, Fields.MV.ToString());
|
||||
}
|
||||
|
||||
private enum Fields
|
||||
{
|
||||
Form,
|
||||
EU,
|
||||
MV
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays initial offset structure to string
|
||||
/// created for FB5429
|
||||
/// </summary>
|
||||
/// <param name="NONEFormatString">string resource similar to "None"</param>
|
||||
/// <param name="EUFormatString">string resource similar to "EU"</param>
|
||||
/// <param name="mVFormatString">string resource similar to "mV"</param>
|
||||
/// <returns></returns>
|
||||
public string ToDisplayString(string NONEFormatString, string EUFormatString, string mVFormatString)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
switch (Form)
|
||||
{
|
||||
case InitialOffsetTypes.EU:
|
||||
case InitialOffsetTypes.LHS:
|
||||
case InitialOffsetTypes.RHS:
|
||||
case InitialOffsetTypes.FRONTAL:
|
||||
sb.AppendFormat("{0} {1}", EU, EUFormatString);
|
||||
break;
|
||||
case InitialOffsetTypes.EUAtMV:
|
||||
sb.AppendFormat("{0} {1} @ {2} {3}", EU, EUFormatString, MV, mVFormatString);
|
||||
break;
|
||||
case InitialOffsetTypes.None:
|
||||
sb.AppendFormat("{0}", NONEFormatString);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares attributes to another InitialOffset object
|
||||
/// created for FB5429
|
||||
/// </summary>
|
||||
/// <param name="obj">an InitialOffset object</param>
|
||||
/// <returns>if contents are equal</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is InitialOffset io)
|
||||
{
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case Fields.Form: if (io.Form != Form) { return false; } break;
|
||||
case Fields.EU: if (io.EU != EU) { return false; } break;
|
||||
case Fields.MV: if (io.MV != MV) { return false; } break;
|
||||
default:
|
||||
throw new NotSupportedException("InitialOffset::Equals Unknown field " + field);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class InitialOffsets : IInitialOffsets
|
||||
{
|
||||
public InitialOffset[] Offsets { get; set; } = new InitialOffset[] { };
|
||||
//FB18158 Always add None option to InitialOffsets
|
||||
private void SeedNoneInInitialOffsets()
|
||||
{
|
||||
if (Offsets.Any(p => p.Form == InitialOffsetTypes.None))
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<InitialOffset> initialOffsets = new List<InitialOffset>();
|
||||
initialOffsets.Add(new InitialOffset());
|
||||
foreach (var io in Offsets)
|
||||
{
|
||||
initialOffsets.Add(io);
|
||||
}
|
||||
Offsets = initialOffsets.ToArray();
|
||||
}
|
||||
|
||||
public InitialOffset DefaultOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
//30442 Don't default InitialOffset to None if other options exist
|
||||
if (null != Offsets && Offsets.Any())
|
||||
{
|
||||
if ((Offsets.Count() > 1) && (Offsets[0].Form == InitialOffsetTypes.None))
|
||||
{
|
||||
return Offsets[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return Offsets.First();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new InitialOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public InitialOffsets(InitialOffsets copy)
|
||||
{
|
||||
InitialOffset[] offsets = new InitialOffset[copy.Offsets.Length];
|
||||
for (int i = 0; i < copy.Offsets.Length; i++)
|
||||
{
|
||||
offsets[i] = new InitialOffset(copy.Offsets[i]);
|
||||
}
|
||||
Offsets = offsets;
|
||||
SeedNoneInInitialOffsets();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This produces an instance of the class based on an existing instance,
|
||||
/// but without the first Initial Offset, only additional Initial Offsets
|
||||
/// </summary>
|
||||
/// <param name="copy"></param>
|
||||
/// <param name="numAdditionalInitialOffsets"></param>
|
||||
public InitialOffsets(InitialOffsets copy, int numAdditionalInitialOffsets)
|
||||
{
|
||||
InitialOffset[] offsets = new InitialOffset[numAdditionalInitialOffsets];
|
||||
for (int i = 0; i < numAdditionalInitialOffsets; i++)
|
||||
{
|
||||
offsets[i] = new InitialOffset(copy.Offsets[i + 1]);
|
||||
}
|
||||
Offsets = offsets;
|
||||
SeedNoneInInitialOffsets();
|
||||
}
|
||||
|
||||
public InitialOffsets()
|
||||
{
|
||||
Offsets = new InitialOffset[] { new InitialOffset() };
|
||||
SeedNoneInInitialOffsets();
|
||||
}
|
||||
public InitialOffsets(string offsets)
|
||||
{
|
||||
FromSerializedString(offsets);
|
||||
SeedNoneInInitialOffsets();
|
||||
}
|
||||
|
||||
public InitialOffsets(InitialOffset startingOffset)
|
||||
{
|
||||
Offsets = new InitialOffset[] { startingOffset };
|
||||
SeedNoneInInitialOffsets();
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is InitialOffsets r)
|
||||
{
|
||||
if (r.Offsets.Length != Offsets.Length) { return false; }
|
||||
for (var i = 0; i < r.Offsets.Length; i++)
|
||||
{
|
||||
if (!r.Offsets[i].Equals(Offsets[i])) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return base.Equals(obj);
|
||||
}
|
||||
public void FromSerializedString(string s)
|
||||
{
|
||||
var tokens = s.Split(new string[] { MySeparator }, StringSplitOptions.None);
|
||||
for (var i = 0; i < tokens.Length; i++) { tokens[i] = tokens[i].Replace(MySeparatorBackup, MySeparator); }
|
||||
|
||||
var offsets = new List<InitialOffset>();
|
||||
foreach (string token in tokens)
|
||||
{
|
||||
offsets.Add(new InitialOffset(token));
|
||||
}
|
||||
Offsets = offsets.ToArray();
|
||||
SeedNoneInInitialOffsets();
|
||||
}
|
||||
internal const string MySeparator = "__x__";
|
||||
internal const string MySeparatorBackup = "___xx___";
|
||||
public string ToSerializedString()
|
||||
{
|
||||
var offsets = new List<string>();
|
||||
|
||||
foreach (var r in Offsets) { offsets.Add(r.ToDbSerializeString()); }
|
||||
|
||||
for (int i = 0; i < offsets.Count; i++)
|
||||
{
|
||||
Trace.Assert(!offsets[i].Contains(MySeparatorBackup));
|
||||
offsets[i] = offsets[i].Replace(MySeparator, MySeparatorBackup);
|
||||
}
|
||||
return string.Join(MySeparator, offsets.ToArray());
|
||||
}
|
||||
|
||||
public string ToDisplayString(string averageOverTimeFormatString, string diagnosticLevelFormatString, string absoluteZeroFormatString)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < Offsets.Length; i++)
|
||||
{
|
||||
if (i > 0) { sb.AppendLine(); }
|
||||
|
||||
var s = Offsets[i].ToDisplayString(averageOverTimeFormatString, diagnosticLevelFormatString, absoluteZeroFormatString);
|
||||
if (!string.IsNullOrEmpty(s))
|
||||
{
|
||||
sb.Append(s);
|
||||
}
|
||||
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return ToDisplayString(Strings.Strings.SensorFields_InitialOffset_AverageOverTimeFormat, Strings.Strings.SensorFields_InitialOffset_DiagnosticLevelFormat,
|
||||
Strings.Strings.SensorFields_InitialOffset_AbsoluteZeroFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
699
Common/DTS.CommonCore/Classes/Sensors/LinearizationFormula.cs
Normal file
699
Common/DTS.CommonCore/Classes/Sensors/LinearizationFormula.cs
Normal file
@@ -0,0 +1,699 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class LinearizationFormula
|
||||
{
|
||||
private bool _bIsValid;
|
||||
public bool IsValid() { return _bIsValid; }
|
||||
public void MarkValid(bool bValid)
|
||||
{
|
||||
_bIsValid = bValid;
|
||||
}
|
||||
|
||||
|
||||
// Translation
|
||||
public NonLinearSLICEWareStyles NonLinearSliceWareStyle
|
||||
{
|
||||
get => (NonLinearSLICEWareStyles)NonLinearStyle;
|
||||
set => NonLinearStyle = (NonLinearStyles)value;
|
||||
}
|
||||
|
||||
public NonLinearStyles NonLinearStyle { get; set; } = NonLinearStyles.Polynomial; // Dont make the default style one that locks a specific zero-method FB 10323
|
||||
|
||||
public double PolynomialSensitivity { get; set; } = 1D;
|
||||
|
||||
public double LinearizationExponent { get; set; } = 1D;
|
||||
|
||||
/// <summary>
|
||||
/// THIS IS MM/V, (UI has already been updated, we need to update the variable name)
|
||||
/// </summary>
|
||||
private double _mmPerMV;
|
||||
public double MMPerV
|
||||
{
|
||||
get => _mmPerMV;
|
||||
set => _mmPerMV = value;
|
||||
}
|
||||
|
||||
public double MVAt0MM { get; set; }
|
||||
|
||||
public double Slope { get; set; }
|
||||
|
||||
public double Intercept { get; set; }
|
||||
|
||||
public double CalibrationFactor { get; set; }
|
||||
|
||||
public double ZeroPositionIntercept { get; set; }
|
||||
|
||||
public LinearizationFormula()
|
||||
{
|
||||
ZeroPositionIntercept = 0D;
|
||||
CalibrationFactor = 0D;
|
||||
Intercept = 0D;
|
||||
_coefficients = new List<double>(new double[] { 0, 0, 0, 0 });
|
||||
_exponents = new List<double>(new double[] { 0, 1, 2, 3 });
|
||||
}
|
||||
|
||||
public LinearizationFormula(LinearizationFormula copy)
|
||||
{
|
||||
UsemVOverVForPolys = copy.UsemVOverVForPolys;
|
||||
_bIsValid = copy._bIsValid;
|
||||
_coefficients = new List<double>(copy._coefficients.ToArray());
|
||||
_exponents = new List<double>(copy._exponents.ToArray());
|
||||
Intercept = copy.Intercept;
|
||||
LinearizationExponent = copy.LinearizationExponent;
|
||||
_mmPerMV = copy._mmPerMV;
|
||||
MVAt0MM = copy.MVAt0MM;
|
||||
Slope = copy.Slope;
|
||||
NonLinearStyle = copy.NonLinearStyle;
|
||||
_coefficients = new List<double>(copy._coefficients);
|
||||
_exponents = new List<double>(copy._exponents);
|
||||
PolynomialSensitivity = copy.PolynomialSensitivity;
|
||||
ZeroPositionIntercept = copy.ZeroPositionIntercept;
|
||||
CalibrationFactor = copy.CalibrationFactor;
|
||||
}
|
||||
public double GetCoefficient(double exponent)
|
||||
{
|
||||
for (var i = 0; i < _exponents.Count && i < _coefficients.Count; i++)
|
||||
{
|
||||
if (_exponents[i] == exponent) { return _coefficients[i]; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public void SetCoefficient(double exponent, double coefficient)
|
||||
{
|
||||
for (var i = 0; i < _exponents.Count && i < _coefficients.Count; i++)
|
||||
{
|
||||
if (_exponents[i] == exponent) { _coefficients[i] = coefficient; return; }
|
||||
}
|
||||
}
|
||||
public double GetLinearizedValue(double input, double excitation, bool? isProportional = null)
|
||||
{
|
||||
if (NonLinearStyle != NonLinearStyles.Polynomial && input <= 0)
|
||||
{
|
||||
//ir-tracc should never be < 0, however we may get readings less than zero due to
|
||||
//noise and other factors, treat these as positive near to zero
|
||||
input = .001;
|
||||
}
|
||||
//first linearize
|
||||
input /= 1000D;//assume input is in mV and we want it in Volts
|
||||
input = Math.Pow(input, LinearizationExponent);
|
||||
|
||||
switch (NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero:
|
||||
return GetEUDiagnosticsZero(input);
|
||||
case NonLinearStyles.IRTraccManual:
|
||||
return GetEUIRTraccManual(input);
|
||||
case NonLinearStyles.IRTraccZeroMMmV:
|
||||
return GetEUZeroMMmV(input);
|
||||
case NonLinearStyles.IRTraccAverageOverTime:
|
||||
return GetEUAverageOverTime(input);
|
||||
case NonLinearStyles.Polynomial:
|
||||
//FB 29728 pass parameter isProportional, consider null as true to use the existing formula to divide by excitation
|
||||
return GetEUPolynomial(input, excitation, isProportional ?? true);
|
||||
case NonLinearStyles.IRTraccCalFactor:
|
||||
return GetEUIRTraccCalFactor(input);
|
||||
default:
|
||||
throw new NotSupportedException("unknown format: " + NonLinearStyle);
|
||||
}
|
||||
}
|
||||
private double GetEUIRTraccCalFactor(double volts)
|
||||
{
|
||||
return volts * CalibrationFactor + ZeroPositionIntercept;
|
||||
}
|
||||
private double GetEUIRTraccManual(double volts)
|
||||
{
|
||||
return (volts - Intercept) / Slope;
|
||||
}
|
||||
|
||||
public bool UsemVOverVForPolys { get; set; } = true;
|
||||
|
||||
private double GetEUZeroMMmV(double volts)
|
||||
{
|
||||
var input = MVAt0MM / 1000D;
|
||||
input = Math.Pow(input, LinearizationExponent);
|
||||
if (double.IsNaN(input) || double.IsNegativeInfinity(input) || double.IsPositiveInfinity(input))
|
||||
{
|
||||
return volts * MMPerV;
|
||||
}
|
||||
return (volts * MMPerV - MMPerV * input);
|
||||
}
|
||||
private List<double> _coefficients = new List<double>();
|
||||
private List<double> _exponents = new List<double>();
|
||||
private double GetEUPolynomial(double volts, double excitation, bool isProportional)
|
||||
{
|
||||
//per J2517
|
||||
//3.4 Use of the Calibration Coefficients
|
||||
//The potentiometer assembly should be re-installed in the dummy without any mechanical adjustment of the
|
||||
//potentiometer. Prior to a crash test, the original zero offset level must be preserved by either not zeroing the
|
||||
//potentiometer (by signal conditioning or post-processing) or the amount that was zeroed must be added during postprocessing.
|
||||
//During the test the absolute voltage output time history should be recorded. This voltage signal is then
|
||||
//converted to engineering units by:
|
||||
//1. Convert voltage signal to mV/V at the sensor. This is the sensor reading S.
|
||||
//2. Convert the sensor reading S to displacement D by using the equation:
|
||||
//D = A*S^3 + B*S^2 + C*S + M (Eq. 2)
|
||||
//where:
|
||||
//D is the displacement relative to the thorax design position in mm
|
||||
//S is the sensor output reading in mV/V
|
||||
//A, B, C, and M are the calibration coefficients
|
||||
//NOTE: Make sure to use sufficient significant digits on all coefficients to assure accuracy of the conversion to
|
||||
//engineering units. It is recommended to use 5 significant digits (example 0.000012345).
|
||||
|
||||
//double mV = volts * 1000D;
|
||||
//double gain = 1D;
|
||||
//mV = mV / (gain * excitation);
|
||||
|
||||
//if (0 != PolynomialSensitivity && 1!= PolynomialSensitivity) { mV /= PolynomialSensitivity; }
|
||||
//double eu = 0D;
|
||||
//for (int i = 0; i < _coefficients.Count && i < _exponents.Count; i++)
|
||||
//{
|
||||
// eu += _coefficients[i] * Math.Pow(mV, _exponents[i]);
|
||||
//}
|
||||
//return eu;
|
||||
|
||||
//CHANGED FOR GM TESTING
|
||||
|
||||
if (0 != PolynomialSensitivity && 1 != PolynomialSensitivity)
|
||||
{
|
||||
volts /= PolynomialSensitivity;
|
||||
}
|
||||
var voltsOverV = 0D;
|
||||
|
||||
//FB 29728 if is not proportinal then excitation voltage should be 1
|
||||
if (!isProportional)
|
||||
{
|
||||
excitation = 1D;
|
||||
}
|
||||
|
||||
if (UsemVOverVForPolys)
|
||||
{
|
||||
//convert to mV first
|
||||
voltsOverV = volts * 1000D / excitation;
|
||||
}
|
||||
else
|
||||
{
|
||||
//used by GM
|
||||
voltsOverV = volts / excitation;
|
||||
}
|
||||
double eu = 0;
|
||||
|
||||
for (var i = 0; i < _coefficients.Count && i < _exponents.Count; i++)
|
||||
{
|
||||
if (_exponents[i] != 0)
|
||||
{
|
||||
eu += _coefficients[i] * Math.Pow(voltsOverV, _exponents[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
eu += _coefficients[i];
|
||||
}
|
||||
}
|
||||
return eu;
|
||||
}
|
||||
/// <summary>
|
||||
/// MvAt0MM set at diagnostics
|
||||
/// </summary>
|
||||
/// <param name="volts"></param>
|
||||
/// <returns></returns>
|
||||
private double GetEUDiagnosticsZero(double volts)
|
||||
{
|
||||
//double input = MVAt0MM/1000D;
|
||||
//input = System.Math.Pow(input,LinearizationExponent);
|
||||
var input = double.NaN;
|
||||
if (double.IsNaN(input) || double.IsPositiveInfinity(input) || double.IsNegativeInfinity(input))
|
||||
{
|
||||
return volts * MMPerV;
|
||||
}
|
||||
return volts * MMPerV - MMPerV * input;
|
||||
}
|
||||
/// <summary>
|
||||
/// MVAt0MM set by diagnostics and then later on at
|
||||
/// Average Over Time
|
||||
/// </summary>
|
||||
/// <param name="volts"></param>
|
||||
/// <returns></returns>
|
||||
private double GetEUAverageOverTime(double volts)
|
||||
{
|
||||
//double input = MVAt0MM / 1000D;
|
||||
//input = System.Math.Pow(input, LinearizationExponent);
|
||||
var input = double.NaN;
|
||||
if (double.IsNaN(input) || double.IsNegativeInfinity(input) || double.IsPositiveInfinity(input))
|
||||
{
|
||||
return volts * MMPerV;
|
||||
}
|
||||
return volts * MMPerV - MMPerV * input;
|
||||
}
|
||||
|
||||
|
||||
public string ToSLICEWareSerializeString()
|
||||
{
|
||||
if (!_bIsValid) { return ""; }
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendFormat("{0}_", NonLinearStyle);
|
||||
|
||||
switch (NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero:
|
||||
sb.Append(ToIRTraccDiagnosticZeroString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccManual:
|
||||
sb.Append(ToIRTraccManualString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccZeroMMmV:
|
||||
sb.Append(ToIRTraccZeroMMmVString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccAverageOverTime:
|
||||
sb.Append(ToIRTraccAverageOverTimeString());
|
||||
break;
|
||||
case NonLinearStyles.Polynomial:
|
||||
sb.Append(ToSLICEWarePolynomialString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccCalFactor:
|
||||
throw new NotSupportedException("CalFactor not supported in SLICEWare");
|
||||
default:
|
||||
throw new NotSupportedException("unknown type: " + NonLinearStyle);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// serializes to a string of the format "c0xe0 c1xe1...cnxen"
|
||||
/// this will allow us arbitrary length polynomials and fractional exponents.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ToSerializeString()
|
||||
{
|
||||
if (!_bIsValid) { return ""; }
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendFormat("{0}_", NonLinearStyle);
|
||||
|
||||
switch (NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero:
|
||||
sb.Append(ToIRTraccDiagnosticZeroString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccManual:
|
||||
sb.Append(ToIRTraccManualString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccZeroMMmV:
|
||||
sb.Append(ToIRTraccZeroMMmVString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccAverageOverTime:
|
||||
sb.Append(ToIRTraccAverageOverTimeString());
|
||||
break;
|
||||
case NonLinearStyles.Polynomial:
|
||||
sb.Append(ToPolynomialString());
|
||||
break;
|
||||
case NonLinearStyles.IRTraccCalFactor:
|
||||
sb.Append(ToIRTraccCalFactorString());
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("unknown type: " + NonLinearStyle);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
public string ToIRTraccDiagnosticZeroString()
|
||||
{
|
||||
return $"{MMPerV.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{LinearizationExponent.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
public string ToIRTraccCalFactorString()
|
||||
{
|
||||
return $"{CalibrationFactor.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{LinearizationExponent.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{ZeroPositionIntercept.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
public void FromIRTraccCalFactorString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = s.Split('x');
|
||||
if (tokens.Length < 3) { throw new NotSupportedException("Invalid CalFactor format: " + s); }
|
||||
|
||||
CalibrationFactor = double.Parse(tokens[0], culture);
|
||||
LinearizationExponent = double.Parse(tokens[1], culture);
|
||||
ZeroPositionIntercept = double.Parse(tokens[2], culture);
|
||||
}
|
||||
public void FromIRTraccDiagnosticZeroString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = s.Split('x');
|
||||
if (tokens.Length < 2) { throw new NotSupportedException("Invalid DiagnosticsZero format: " + s); }
|
||||
MMPerV = double.Parse(tokens[0], culture);
|
||||
LinearizationExponent = double.Parse(tokens[1], culture);
|
||||
}
|
||||
public string ToIRTraccManualString()
|
||||
{
|
||||
return $"{Slope.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{Intercept.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{LinearizationExponent.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
public void FromIRTraccManualString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = s.Split('x');
|
||||
if (tokens.Length < 3) { throw new NotSupportedException("Invalid IRTraccManual format: " + s); }
|
||||
Slope = double.Parse(tokens[0], culture);
|
||||
Intercept = double.Parse(tokens[1], culture);
|
||||
LinearizationExponent = double.Parse(tokens[2], culture);
|
||||
}
|
||||
public string ToIRTraccZeroMMmVString()
|
||||
{
|
||||
return $"{MMPerV.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{MVAt0MM.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{LinearizationExponent.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
public string ToSLICEWarePolynomialString()
|
||||
{
|
||||
//SLICEWare is the reverse order of our DataPRO Database
|
||||
var sb = new StringBuilder();
|
||||
for (var i = _exponents.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (i != _exponents.Count - 1) { sb.Append(","); }
|
||||
sb.AppendFormat("{0}x{1}", _coefficients[i].ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
_exponents[i].ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
sb.AppendFormat(",S={0}", PolynomialSensitivity.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
return sb.ToString();
|
||||
}
|
||||
public string ToPolynomialString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (var i = 0; i < _coefficients.Count && i < _exponents.Count; i++)
|
||||
{
|
||||
if (i > 0) { sb.Append(","); }
|
||||
sb.AppendFormat("{0}x{1}", _coefficients[i].ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
_exponents[i].ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
sb.AppendFormat(",S={0},mV={1}",
|
||||
PolynomialSensitivity.ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
UsemVOverVForPolys.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
public double[] PolynomialCoefficients
|
||||
{
|
||||
get => _coefficients.ToArray();
|
||||
set => _coefficients = new List<double>(value);
|
||||
}
|
||||
public double[] PolynomialExponents
|
||||
{
|
||||
get => _exponents.ToArray();
|
||||
set => _exponents = new List<double>(value);
|
||||
}
|
||||
public string ToIRTraccAverageOverTimeString()
|
||||
{
|
||||
return $"{MMPerV.ToString(System.Globalization.CultureInfo.InvariantCulture)}x{LinearizationExponent.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
public void FromIRTraccAverageOverTimeString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = s.Split('x');
|
||||
if (tokens.Length < 2) { throw new NotSupportedException("Invalid IRTRaccAverageOverTime format: " + s); }
|
||||
MMPerV = double.Parse(tokens[0], culture);
|
||||
LinearizationExponent = double.Parse(tokens[1], culture);
|
||||
}
|
||||
public void FromIRTraccZeroMMmVString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = s.Split('x');
|
||||
if (tokens.Length < 3) { throw new NotSupportedException("Invalid IRTraccZeroMMmV format: " + s); }
|
||||
MMPerV = double.Parse(tokens[0], culture);
|
||||
MVAt0MM = double.Parse(tokens[1], culture);
|
||||
LinearizationExponent = double.Parse(tokens[2], culture);
|
||||
}
|
||||
public void FromPolynomialString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
_coefficients.Clear();
|
||||
_exponents.Clear();
|
||||
|
||||
var tokens = s.Split(',');
|
||||
foreach (var t in tokens)
|
||||
{
|
||||
var subtokens = t.Split(new[] { 'x' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (2 == subtokens.Length)
|
||||
{
|
||||
if (double.TryParse(subtokens[0], System.Globalization.NumberStyles.Float, culture, out var d))
|
||||
{
|
||||
_coefficients.Add(d);
|
||||
_exponents.Add(double.Parse(subtokens[1], culture));
|
||||
}
|
||||
else
|
||||
{
|
||||
PolynomialSensitivity = double.Parse(subtokens[1], culture);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
subtokens = subtokens[0].Split('=');
|
||||
if (subtokens.Length == 2)
|
||||
{
|
||||
switch (subtokens[0])
|
||||
{
|
||||
case "S":
|
||||
PolynomialSensitivity = double.Parse(subtokens[1], culture);
|
||||
break;
|
||||
case "mV":
|
||||
UsemVOverVForPolys = Convert.ToBoolean(subtokens[1], culture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void FromSerializeString(string s, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s)) { _bIsValid = false; return; }
|
||||
if (s.Equals("1") || s.Equals("0") || s.Equals("1 ")) { _bIsValid = false; return; }
|
||||
|
||||
var tokens = s.Split('_');
|
||||
if (tokens.Length < 2) { throw new NotSupportedException("unsupported Linearization Formula Format"); }
|
||||
var style = (NonLinearStyles)Enum.Parse(typeof(NonLinearStyles), tokens[0], true);
|
||||
NonLinearStyle = style;
|
||||
switch (NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero:
|
||||
FromIRTraccDiagnosticZeroString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
case NonLinearStyles.IRTraccManual:
|
||||
FromIRTraccManualString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
case NonLinearStyles.IRTraccZeroMMmV:
|
||||
FromIRTraccZeroMMmVString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
case NonLinearStyles.Polynomial:
|
||||
FromPolynomialString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
case NonLinearStyles.IRTraccAverageOverTime:
|
||||
FromIRTraccAverageOverTimeString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
case NonLinearStyles.IRTraccCalFactor:
|
||||
FromIRTraccCalFactorString(tokens[1], culture);
|
||||
_bIsValid = true;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("Unknown format: " + NonLinearStyle);
|
||||
}
|
||||
}
|
||||
public void FromSerializeString(string s)
|
||||
{
|
||||
FromSerializeString(s, System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public void FromTDCSerializeString()
|
||||
{
|
||||
_bIsValid = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will return a display string for a nonlinear calibration based on N4 formating
|
||||
/// </summary>
|
||||
public string ToDisplayString()
|
||||
{
|
||||
return ToDisplayString("N4");
|
||||
}
|
||||
/// <summary>
|
||||
/// Will return a display string for a nonlinear calibration based on 1st paramater formating string
|
||||
/// </summary>
|
||||
/// <param name="nonlinearFormat"></param>
|
||||
/// <returns></returns>
|
||||
public string ToDisplayString(string nonlinearFormat)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nonlinearFormat)) { nonlinearFormat = "N4"; }
|
||||
switch (NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.Polynomial:
|
||||
{
|
||||
return ToPolynomial(nonlinearFormat);
|
||||
}
|
||||
case NonLinearStyles.IRTraccZeroMMmV:
|
||||
{
|
||||
return $"mV = {MVAt0MM:n4}, {MMPerV:n4}*(V^{ToSuperScript(LinearizationExponent.ToString(nonlinearFormat))})";
|
||||
}
|
||||
case NonLinearStyles.IRTraccManual:
|
||||
{
|
||||
return $"((V^{ToSuperScript(LinearizationExponent.ToString(nonlinearFormat))})-{Intercept:n4})/{Slope:n4}";
|
||||
}
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero:
|
||||
{
|
||||
return $"{MMPerV:n4}*(V^{ToSuperScript(LinearizationExponent.ToString(nonlinearFormat))})";
|
||||
}
|
||||
case NonLinearStyles.IRTraccAverageOverTime:
|
||||
{
|
||||
return $"{MMPerV:n4}*(V^{ToSuperScript(LinearizationExponent.ToString(nonlinearFormat))})";
|
||||
}
|
||||
case NonLinearStyles.IRTraccCalFactor:
|
||||
{
|
||||
return $"{ZeroPositionIntercept:n4}+{CalibrationFactor:n4}*(V^{ToSuperScript(LinearizationExponent.ToString(nonlinearFormat))})";
|
||||
}
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
private string ToPolynomial(string nonlinearFormat)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nonlinearFormat)) { nonlinearFormat = "N4"; }
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var termNumber = PolynomialCoefficients.Length - 1;
|
||||
foreach (var x in PolynomialCoefficients)
|
||||
{
|
||||
if (PolynomialCoefficients[termNumber] == 0)
|
||||
{
|
||||
termNumber--;
|
||||
continue;
|
||||
}
|
||||
double coeff = HandleSign(termNumber);
|
||||
|
||||
sb.Append(coeff.ToString(nonlinearFormat));
|
||||
if (PolynomialExponents[termNumber] != 0)
|
||||
{
|
||||
sb.Append("x");
|
||||
if (PolynomialExponents[termNumber] != 1)
|
||||
{
|
||||
sb.Append(ToSuperScript(PolynomialExponents[termNumber].ToString("N0")));
|
||||
}
|
||||
}
|
||||
if (termNumber > 0)
|
||||
{
|
||||
// Coerricients are Displayed in absolute value. We need to combine the sign with the addition symbol
|
||||
sb.Append(PolynomialCoefficients[termNumber - 1] > 0 ? " + " : " - ");
|
||||
}
|
||||
termNumber--;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private double HandleSign(int termNumber)
|
||||
{
|
||||
double coeff = PolynomialCoefficients[termNumber];
|
||||
|
||||
// Let the appended math symbol handle sign unless we're the first term.
|
||||
if (termNumber != PolynomialCoefficients.Length - 1)
|
||||
{
|
||||
coeff = Math.Abs(coeff);
|
||||
}
|
||||
return coeff;
|
||||
}
|
||||
|
||||
private string ToSuperScript(string source)
|
||||
{
|
||||
var superScript = new StringBuilder();
|
||||
|
||||
foreach (var c in source)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '-':
|
||||
superScript.Append('\u207B');
|
||||
break;
|
||||
case '.':
|
||||
superScript.Append('\u00B7');
|
||||
break;
|
||||
case '1':
|
||||
superScript.Append('\u00B9');
|
||||
break;
|
||||
case '2':
|
||||
superScript.Append('\u00B2');
|
||||
break;
|
||||
case '3':
|
||||
superScript.Append('\u00B3');
|
||||
break;
|
||||
case '4':
|
||||
superScript.Append('\u2074');
|
||||
break;
|
||||
case '5':
|
||||
superScript.Append('\u2075');
|
||||
break;
|
||||
case '6':
|
||||
superScript.Append('\u2076');
|
||||
break;
|
||||
case '7':
|
||||
superScript.Append('\u2077');
|
||||
break;
|
||||
case '8':
|
||||
superScript.Append('\u2078');
|
||||
break;
|
||||
case '9':
|
||||
superScript.Append('\u2079');
|
||||
break;
|
||||
case '0':
|
||||
superScript.Append('\u2070');
|
||||
break;
|
||||
case '\'':
|
||||
superScript.Append('\u02C8');
|
||||
break;
|
||||
case ',':
|
||||
superScript.Append('\u22C5'); // there is no unicode superscript comma. this comes close
|
||||
break;
|
||||
case '\u00A0':
|
||||
superScript.Append('\u2009'); // unicode 'thin' space
|
||||
break;
|
||||
default:
|
||||
superScript.Append('\u207F');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return superScript.ToString();
|
||||
}
|
||||
/*
|
||||
* we are given an equation in the form of y = ax^1 + b, except x and y are backwards for us (y=V where we'd prefer X was voltage, so we switch it)
|
||||
* y/a - b/a = x, and then switch y and x, (1/a)x^1 -(b/a)x^0 = y
|
||||
* now we want to get the coefficient of the first equation, which is "a", we get this by taking the inverse
|
||||
* we get b on the other hand by taking -1 * (b/a)*a. if we have the "coefficient", we have a
|
||||
*/
|
||||
/*
|
||||
public double GetIRTraccCoefficient()
|
||||
{
|
||||
foreach (Factor f in Factors)
|
||||
{
|
||||
if (f.Exponent == 1D) { return System.Math.Pow(f.Coefficient, -1); }
|
||||
}
|
||||
return 1D; //0 doesn't make sense for ir
|
||||
}
|
||||
public double GetIRTraccConstant()
|
||||
{
|
||||
foreach (Factor f in Factors)
|
||||
{
|
||||
if (f.Exponent == 0D) { return -1D * GetIRTraccCoefficient() * f.Coefficient; }
|
||||
}
|
||||
return 0D;
|
||||
}
|
||||
public void SetIRTraccFactor(double coefficient, double constant)
|
||||
{
|
||||
if (0 == coefficient)
|
||||
{
|
||||
//well this doesn't make any sense ...
|
||||
coefficient = 1;
|
||||
}
|
||||
Factors = new Factor[]
|
||||
{
|
||||
new Factor(1/coefficient,1),
|
||||
new Factor(-constant/coefficient,0),
|
||||
};
|
||||
}*/
|
||||
}
|
||||
}
|
||||
112
Common/DTS.CommonCore/Classes/Sensors/ParseParameters.cs
Normal file
112
Common/DTS.CommonCore/Classes/Sensors/ParseParameters.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
/// <summary>
|
||||
/// internal helper class to avoid passing a huge number of parameters between methods
|
||||
/// right now it's needed both in the Wizard CSV import code and in DataPRO CSV import code
|
||||
/// but it can probably be moved to only be in Wizard CSV import code when DataPRO CSV import code is removed
|
||||
/// for now it lives here.
|
||||
/// </summary>
|
||||
public class ParseParameters
|
||||
{
|
||||
private ISensorData _sd;
|
||||
public ISensorData SensorData { get => _sd; set => _sd = value; }
|
||||
|
||||
private IFormatProvider _importCulture;
|
||||
public IFormatProvider ImportCulture { get => _importCulture; set => _importCulture = value; }
|
||||
|
||||
private List<string> _errors;
|
||||
public List<string> Errors { get => _errors; set => _errors = value; }
|
||||
|
||||
private double _dIrTraccExponent;
|
||||
public double IrtraccExponent { get => _dIrTraccExponent; set => _dIrTraccExponent = value; }
|
||||
|
||||
private ISensorCalibration _sc;
|
||||
public ISensorCalibration SensorCal { get => _sc; set => _sc = value; }
|
||||
|
||||
private double _dSensitivity;
|
||||
public double Sensitivity { get => _dSensitivity; set => _dSensitivity = value; }
|
||||
|
||||
private bool _bSavedIsProportional;
|
||||
public bool SavedIsProportional { get => _bSavedIsProportional; set => _bSavedIsProportional = value; }
|
||||
|
||||
private bool _savedRemoveOffset;
|
||||
public bool SavedRemoveOffset { get => _savedRemoveOffset; set => _savedRemoveOffset = value; }
|
||||
|
||||
private bool _stripBackslash;
|
||||
public bool StripBackslash { get => _stripBackslash; set => _stripBackslash = value; }
|
||||
|
||||
private double _dOriginalOffset;
|
||||
public double OriginalOffset { get => _dOriginalOffset; set => _dOriginalOffset = value; }
|
||||
|
||||
private ZeroMethodType _zmt;
|
||||
public ZeroMethodType ZeroType { get => _zmt; set => _zmt = value; }
|
||||
|
||||
private double _zeroMethodEnd;
|
||||
public double ZeroEnd
|
||||
{
|
||||
get => _zeroMethodEnd; set => _zeroMethodEnd = value;
|
||||
}
|
||||
|
||||
private double _zeroMethodStart;
|
||||
public double ZeroStart { get => _zeroMethodStart; set => _zeroMethodStart = value; }
|
||||
|
||||
private ISquibSettingDefaults _squibDefaults;
|
||||
public ISquibSettingDefaults SquibDefaults
|
||||
{
|
||||
get => _squibDefaults; set => _squibDefaults = value;
|
||||
}
|
||||
|
||||
private IDigitalOutDefaults _digitalOutDefaults;
|
||||
public IDigitalOutDefaults DigitalOutDefaults
|
||||
{
|
||||
get => _digitalOutDefaults; set => _digitalOutDefaults = value;
|
||||
}
|
||||
|
||||
private Dictionary<string, string> _sensorGroupNameLookup;
|
||||
public Dictionary<string, string> SensorGroupNameLookup
|
||||
{
|
||||
get => _sensorGroupNameLookup; set => _sensorGroupNameLookup = value;
|
||||
}
|
||||
|
||||
private Dictionary<string, string> _sensorGroupTypeLookup;
|
||||
public Dictionary<string, string> SensorGroupTypeLookup
|
||||
{
|
||||
get => _sensorGroupTypeLookup; set => _sensorGroupTypeLookup = value;
|
||||
}
|
||||
|
||||
private Dictionary<string, string> _groupNameToTestObjectLookup;
|
||||
public Dictionary<string, string> GroupNameToTestObjectLookup { get => _groupNameToTestObjectLookup; set => _groupNameToTestObjectLookup = value; }
|
||||
|
||||
private string _sensorTestObject;
|
||||
public string SensorTestObject { get => _sensorTestObject; set => _sensorTestObject = value; }
|
||||
|
||||
private bool _bUseISOCodeFilterMapping;
|
||||
public bool UseISOCodeFilterMapping { get => _bUseISOCodeFilterMapping; set => _bUseISOCodeFilterMapping = value; }
|
||||
|
||||
private bool _bUseZeroForUnfiltered;
|
||||
public bool UseZeroForUnfiltered { get => _bUseZeroForUnfiltered; set => _bUseZeroForUnfiltered = value; }
|
||||
|
||||
private Dictionary<string, string> _SensorISOCode;
|
||||
public Dictionary<string, string> SensorISOCode { get=> _SensorISOCode; set=> _SensorISOCode = value; }
|
||||
|
||||
private Dictionary<string, string> _SensorISOChannelName;
|
||||
public Dictionary<string, string> SensorISOChannelName { get=> _SensorISOChannelName; set=> _SensorISOChannelName = value; }
|
||||
|
||||
private Dictionary<string, string> _SensorUserCode;
|
||||
public Dictionary<string, string> SensorUserCode { get=> _SensorUserCode; set=> _SensorUserCode = value; }
|
||||
|
||||
private Dictionary<string, string> _SensorUserChannelName;
|
||||
public Dictionary<string, string> SensorUserChannelName { get=> _SensorUserChannelName; set=> _SensorUserChannelName = value; }
|
||||
|
||||
private Dictionary<string, string> _SensorDASSerialNumber;
|
||||
public Dictionary<string, string> SensorDASSerialNumber { get => _SensorDASSerialNumber; set => _SensorDASSerialNumber = value; }
|
||||
|
||||
private Dictionary<string, int> _SensorDASChannelIndex;
|
||||
public Dictionary<string, int> SensorDASChannelIndex { get=> _SensorDASChannelIndex; set=> _SensorDASChannelIndex = value; }
|
||||
}
|
||||
}
|
||||
177
Common/DTS.CommonCore/Classes/Sensors/SensorCalDbRecord.cs
Normal file
177
Common/DTS.CommonCore/Classes/Sensors/SensorCalDbRecord.cs
Normal file
@@ -0,0 +1,177 @@
|
||||
using DTS.Common.Base;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Data;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class SensorCalDbRecord : BasePropertyChanged, ISensorCalDbRecord
|
||||
{
|
||||
public bool LinearAdded
|
||||
{
|
||||
get => NonLinear && Records.Records[0].Poly.NonLinearStyle == NonLinearStyles.Polynomial &&
|
||||
Records.Records.Length > 1 && ZeroMethods.Methods.Length > 1;
|
||||
}
|
||||
|
||||
private int? _calibrationId = null;
|
||||
/// <summary>
|
||||
/// database id, if known, for calibration, null indicates not known
|
||||
/// 13065 Sensor "First Use" Date
|
||||
/// </summary>
|
||||
[Key]
|
||||
public int? CalibrationId
|
||||
{
|
||||
get => _calibrationId;
|
||||
set => SetProperty(ref _calibrationId, value, "CalibrationId");
|
||||
}
|
||||
protected string _serialNumber;
|
||||
public string SerialNumber
|
||||
{
|
||||
get => _serialNumber;
|
||||
set => SetProperty(ref _serialNumber, value, "SerialNumber");
|
||||
}
|
||||
|
||||
protected DateTime _calibrationDate;
|
||||
[Column(TypeName = "datetime")]
|
||||
public DateTime CalibrationDate
|
||||
{
|
||||
get => _calibrationDate;
|
||||
set => SetProperty(ref _calibrationDate, value, "CalibrationDate");
|
||||
}
|
||||
protected string _userName = "";
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Username
|
||||
{
|
||||
get => _userName;
|
||||
set => SetProperty(ref _userName, value, "Username");
|
||||
}
|
||||
private bool _localOnly;
|
||||
public bool LocalOnly
|
||||
{
|
||||
get => _localOnly;
|
||||
set => SetProperty(ref _localOnly, value, "LocalOnly");
|
||||
}
|
||||
private bool _nonLinear;
|
||||
public bool NonLinear
|
||||
{
|
||||
get => _nonLinear;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _nonLinear, value, "NonLinear");
|
||||
if (!value) return;
|
||||
Records.Records.First().Sensitivity = 1D;
|
||||
//FB 29728 don't make IsProportinal false
|
||||
//IsProportional = false;
|
||||
RemoveOffset = false;
|
||||
}
|
||||
}
|
||||
|
||||
private ICalibrationRecords _records = new CalibrationRecords();
|
||||
[Required]
|
||||
[StringLength(255)]
|
||||
public ICalibrationRecords Records
|
||||
{
|
||||
get => _records;
|
||||
set => SetProperty(ref _records, value, "Records");
|
||||
}
|
||||
private DateTime _modifyDate;
|
||||
[Column(TypeName = "datetime")]
|
||||
public DateTime ModifyDate
|
||||
{
|
||||
get => _modifyDate;
|
||||
set => SetProperty(ref _modifyDate, value, "ModifyDate");
|
||||
}
|
||||
private bool _isProportional;
|
||||
public bool IsProportional
|
||||
{
|
||||
get => _isProportional;
|
||||
set => SetProperty(ref _isProportional, value, "IsProportional");
|
||||
}
|
||||
private bool _removeOffset;
|
||||
public bool RemoveOffset
|
||||
{
|
||||
get => _removeOffset;
|
||||
set => SetProperty(ref _removeOffset, value, "RemoveOffset");
|
||||
}
|
||||
private ZeroMethods _zeroMethods = new ZeroMethods();
|
||||
[Required]
|
||||
[StringLength(255)]
|
||||
public ZeroMethods ZeroMethods
|
||||
{
|
||||
get => _zeroMethods;
|
||||
set => SetProperty(ref _zeroMethods, value, "ZeroMethods");
|
||||
}
|
||||
private string[] _certificationDocuments = new string[0];
|
||||
[Required]
|
||||
[StringLength(2048)]
|
||||
public string[] CertificationDocuments
|
||||
{
|
||||
get => _certificationDocuments;
|
||||
set => SetProperty(ref _certificationDocuments, value, "CertificationDocuments");
|
||||
}
|
||||
//FB18158 It's None the default now not EU
|
||||
private InitialOffsets _initialOffsets = new InitialOffsets(new InitialOffset());
|
||||
public InitialOffsets InitialOffsets
|
||||
{
|
||||
get => _initialOffsets;
|
||||
set => SetProperty(ref _initialOffsets, value, "InitialOffsets");
|
||||
}
|
||||
public SensorCalDbRecord() { }
|
||||
public SensorCalDbRecord(ISensorCalDbRecord copy)
|
||||
{
|
||||
CalibrationDate = copy.CalibrationDate;
|
||||
LocalOnly = copy.LocalOnly;
|
||||
SerialNumber = copy.SerialNumber;
|
||||
Username = copy.Username;
|
||||
Records = new CalibrationRecords(copy.Records);
|
||||
NonLinear = copy.NonLinear;
|
||||
IsProportional = copy.IsProportional;
|
||||
ModifyDate = copy.ModifyDate;
|
||||
var list = new List<string>(copy.CertificationDocuments);
|
||||
CertificationDocuments = list.ToArray();
|
||||
RemoveOffset = copy.RemoveOffset;
|
||||
ZeroMethods = new ZeroMethods(copy.ZeroMethods);
|
||||
InitialOffsets = new InitialOffsets(copy.InitialOffsets);
|
||||
|
||||
CalibrationId = copy.CalibrationId;
|
||||
|
||||
//this is downright silly, but because the linearization formula marks itself valid when it deserializes with data in it, we go and correct it here.
|
||||
Records.Records[0].Poly.MarkValid(NonLinear);
|
||||
}
|
||||
public SensorCalDbRecord(IDataReader reader)
|
||||
{
|
||||
try
|
||||
{
|
||||
CalibrationDate = Utility.GetDateTime(reader, "CalibrationDate", DateTime.MinValue);
|
||||
LocalOnly = Utility.GetBool(reader, "LocalOnly", false);
|
||||
SerialNumber = Utility.GetString(reader, "SerialNumber");
|
||||
Username = Utility.GetString(reader, "Username");
|
||||
Records = new CalibrationRecords(Utility.GetString(reader, "CalibrationRecords"));
|
||||
NonLinear = Utility.GetBool(reader, "NonLinear");
|
||||
IsProportional = Utility.GetBool(reader, "IsProportional");
|
||||
ModifyDate = Utility.GetDateTime(reader, "ModifyDate", DateTime.MinValue);
|
||||
CertificationDocuments = Utility.GetString(reader, "CertificationDocuments").Split(new[] { CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None).ToArray();
|
||||
RemoveOffset = Utility.GetBool(reader, "RemoveOffset");
|
||||
ZeroMethods = new ZeroMethods(Utility.GetString(reader, "ZeroMethod"));
|
||||
InitialOffsets = new InitialOffsets(Utility.GetString(reader, "InitialOffset"));
|
||||
|
||||
CalibrationId = Utility.GetNullableInt(reader, "SensorCalibrationId");
|
||||
|
||||
//this is downright silly, but because the linearization formula marks itself valid when it deserializes with data in it, we go and correct it here.
|
||||
Records.Records[0].Poly.MarkValid(NonLinear);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to process Sensor Calibration record", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Common/DTS.CommonCore/Classes/Sensors/SensorDbRecord.cs
Normal file
38
Common/DTS.CommonCore/Classes/Sensors/SensorDbRecord.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Data;
|
||||
using DTS.Common.Interface.Tags;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class SensorDbRecord : TagAwareBase, ISensorDbRecord
|
||||
{
|
||||
public override TagTypes TagType => TagTypes.SensorModels;
|
||||
protected int _id = 0;
|
||||
public int id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value, "id");
|
||||
}
|
||||
|
||||
protected short _sensorType = 0;
|
||||
public short SensorType
|
||||
{
|
||||
get => _sensorType;
|
||||
set => SetProperty(ref _sensorType, value, "SensorType");
|
||||
}
|
||||
|
||||
protected string _serialNumber = string.Empty;
|
||||
public string SerialNumber
|
||||
{
|
||||
get => _serialNumber;
|
||||
set => SetProperty(ref _serialNumber, value, "SerialNumber");
|
||||
}
|
||||
|
||||
public SensorDbRecord(IDataReader reader)
|
||||
{
|
||||
id = Utility.GetInt(reader, "id", 0);
|
||||
SensorType = Utility.GetShort(reader, "SensorType", 0);
|
||||
SerialNumber = Utility.GetString(reader, "SerialNumber");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using DTS.Common.Interface.Sensors.SensorsList;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors.SensorsList
|
||||
{
|
||||
public class DragAndDropPayload
|
||||
{
|
||||
public IDragAndDropItem [] Items { get; }
|
||||
|
||||
public DragAndDropPayload(IDragAndDropItem[] items)
|
||||
{
|
||||
Items = items;
|
||||
}
|
||||
|
||||
public const string FORMAT = "DTS.Common.Classes.Sensors.SensorsList.DragAndDropPayload";
|
||||
public const string ALT_FORMAT = "ALT_DTS.Common.Classes.Sensors.SensorsList.DragAndDropPayload";
|
||||
public const string CTRL_FORMAT = "CTRL_DTS.Common.Classes.Sensors.SensorsList.DragAndDropPayload";
|
||||
}
|
||||
}
|
||||
316
Common/DTS.CommonCore/Classes/Sensors/SquibDbRecord.cs
Normal file
316
Common/DTS.CommonCore/Classes/Sensors/SquibDbRecord.cs
Normal file
@@ -0,0 +1,316 @@
|
||||
using DTS.Common.Base;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class SquibDbRecord : BasePropertyChanged, ISquibDbRecord
|
||||
{
|
||||
private string _serialNumber = "";
|
||||
public string SerialNumber
|
||||
{
|
||||
get => _serialNumber;
|
||||
set => SetProperty(ref _serialNumber, value, "SerialNumber");
|
||||
}
|
||||
private int _id = -1;
|
||||
[Key]
|
||||
public int Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value, "Id");
|
||||
}
|
||||
private bool _bypassCurrentFilter = false;
|
||||
public bool BypassCurrentFilter
|
||||
{
|
||||
get => _bypassCurrentFilter;
|
||||
set => SetProperty(ref _bypassCurrentFilter, value, "BypassCurrentFilter");
|
||||
}
|
||||
private bool _bypassVoltageFilter = false;
|
||||
public bool BypassVoltageFilter
|
||||
{
|
||||
get => _bypassVoltageFilter;
|
||||
set => SetProperty(ref _bypassVoltageFilter, value, "BypassVoltageFilter");
|
||||
}
|
||||
private double _delayMS = 0D;
|
||||
[Column("DelayMS")]
|
||||
public double DelayMs
|
||||
{
|
||||
get => _delayMS;
|
||||
set => SetProperty(ref _delayMS, value, "DelayMs");
|
||||
}
|
||||
private double _durationMS = 10D;
|
||||
[Column("DurationMS")]
|
||||
public double DurationMs
|
||||
{
|
||||
get => _durationMS;
|
||||
set => SetProperty(ref _durationMS, value, "DurationMs");
|
||||
}
|
||||
private SquibFireMode _fireMode = SquibFireMode.NONE;
|
||||
public SquibFireMode FireMode
|
||||
{
|
||||
get => _fireMode;
|
||||
set => SetProperty(ref _fireMode, value, "FireMode");
|
||||
}
|
||||
private string _isoCode = "";
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string IsoCode
|
||||
{
|
||||
get => _isoCode;
|
||||
set => SetProperty(ref _isoCode, value, "IsoCode");
|
||||
}
|
||||
private string _isoChannelName = "";
|
||||
[Required]
|
||||
[StringLength(255)]
|
||||
public string IsoChannelName
|
||||
{
|
||||
get => _isoChannelName;
|
||||
set => SetProperty(ref _isoChannelName, value, "IsoChannelName");
|
||||
}
|
||||
private string _userCode = "";
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string UserCode
|
||||
{
|
||||
get => _userCode;
|
||||
set => SetProperty(ref _userCode, value, "UserCode");
|
||||
}
|
||||
private string _userChannelName = "";
|
||||
[Required]
|
||||
[StringLength(255)]
|
||||
public string UserChannelName
|
||||
{
|
||||
get => _userChannelName;
|
||||
set => SetProperty(ref _userChannelName, value, "UserChannelName");
|
||||
}
|
||||
private SquibMeasurementType _squibMeasurementType = SquibMeasurementType.VOLTAGE;
|
||||
public SquibMeasurementType MeasurementType
|
||||
{
|
||||
get => _squibMeasurementType;
|
||||
set => SetProperty(ref _squibMeasurementType, value, "MeasurementType");
|
||||
}
|
||||
private double _squibOutputCurrent = 1.5D;
|
||||
public double SquibOutputCurrent
|
||||
{
|
||||
get => _squibOutputCurrent;
|
||||
set => SetProperty(ref _squibOutputCurrent, value, "SquibOutputCurrent");
|
||||
}
|
||||
private double _squibToleranceLow = 1D;
|
||||
public double SquibToleranceLow
|
||||
{
|
||||
get => _squibToleranceLow;
|
||||
set => SetProperty(ref _squibToleranceLow, value, "SquibToleranceLow");
|
||||
}
|
||||
private double _squibToleranceHigh = 8D;
|
||||
public double SquibToleranceHigh
|
||||
{
|
||||
get => _squibToleranceHigh;
|
||||
set => SetProperty(ref _squibToleranceHigh, value, "SquibToleranceHigh");
|
||||
}
|
||||
private bool _limitDuration = true;
|
||||
public bool LimitDuration
|
||||
{
|
||||
get => _limitDuration;
|
||||
set => SetProperty(ref _limitDuration, value, "LimitDuration");
|
||||
}
|
||||
private string _articleId = "";
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string ArticleId
|
||||
{
|
||||
get => _articleId;
|
||||
set => SetProperty(ref _articleId, value, "ArticleId");
|
||||
}
|
||||
private int _version = 1;
|
||||
public int Version
|
||||
{
|
||||
get => _version;
|
||||
set => SetProperty(ref _version, value, "Version");
|
||||
}
|
||||
private DateTime _lastModified = DateTime.MinValue;
|
||||
[Column(TypeName = "datetime")]
|
||||
public DateTime LastModified
|
||||
{
|
||||
get => _lastModified;
|
||||
set => SetProperty(ref _lastModified, value, "LastModified");
|
||||
}
|
||||
private string _lastModifiedBy = "";
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string LastModifiedBy
|
||||
{
|
||||
get => _lastModifiedBy;
|
||||
set => SetProperty(ref _lastModifiedBy, value, "LastModifiedBy");
|
||||
}
|
||||
private string _userValue1 = "";
|
||||
[StringLength(255)]
|
||||
public string UserValue1
|
||||
{
|
||||
get => _userValue1;
|
||||
set => SetProperty(ref _userValue1, value, "UserValue1");
|
||||
}
|
||||
private string _userValue2 = "";
|
||||
[StringLength(255)]
|
||||
public string UserValue2
|
||||
{
|
||||
get => _userValue2;
|
||||
set => SetProperty(ref _userValue2, value, "UserValue2");
|
||||
}
|
||||
private string _userValue3 = "";
|
||||
[StringLength(255)]
|
||||
public string UserValue3
|
||||
{
|
||||
get => _userValue3;
|
||||
set => SetProperty(ref _userValue3, value, "UserValue3");
|
||||
}
|
||||
private byte[] _userTags = new byte[0];
|
||||
public byte[] UserTags
|
||||
{
|
||||
get => _userTags;
|
||||
set => SetProperty(ref _userTags, value, "UserTags");
|
||||
}
|
||||
private bool _doNotUse = false;
|
||||
public bool DoNotUse
|
||||
{
|
||||
get => _doNotUse;
|
||||
set => SetProperty(ref _doNotUse, value, "DoNotUse");
|
||||
}
|
||||
private bool _broken = false;
|
||||
public bool Broken
|
||||
{
|
||||
get => _broken;
|
||||
set => SetProperty(ref _broken, value, "Broken");
|
||||
}
|
||||
private bool _defineDelayInTest = false;
|
||||
public bool DefineDelayInTest
|
||||
{
|
||||
get => _defineDelayInTest;
|
||||
set => SetProperty(ref _defineDelayInTest, value, "DefineDelayInTest");
|
||||
}
|
||||
public SquibDbRecord(ISensorData copy, bool defineDelayInTest, byte [] tags)
|
||||
{
|
||||
Id = copy.DatabaseId;
|
||||
IsoChannelName = copy.ISOChannelName;
|
||||
UserCode = copy.UserCode;
|
||||
UserChannelName = copy.UserChannelName;
|
||||
Broken = copy.Broken;
|
||||
DoNotUse = copy.DoNotUse;
|
||||
Version = copy.Version;
|
||||
SquibToleranceLow = copy.SquibToleranceLow;
|
||||
SquibToleranceHigh = copy.SquibToleranceHigh;
|
||||
SquibOutputCurrent = copy.SquibOutputCurrent;
|
||||
SerialNumber = copy.SerialNumber;
|
||||
MeasurementType = copy.SquibMeasurementType;
|
||||
LimitDuration = copy.LimitDuration;
|
||||
DefineDelayInTest = defineDelayInTest;
|
||||
LastModifiedBy = copy.LastUpdatedBy;
|
||||
LastModified = copy.LastModified;
|
||||
IsoCode = copy.ISOCode;
|
||||
FireMode = copy.SquibFireMode;
|
||||
DurationMs = copy.SquibFireDurationMS;
|
||||
DelayMs = copy.SquibFireDelayMS;
|
||||
BypassVoltageFilter = copy.BypassVoltageFilter;
|
||||
BypassCurrentFilter = copy.BypassCurrentFilter;
|
||||
ArticleId = copy.EID;
|
||||
UserValue1 = copy.UserValue1;
|
||||
|
||||
UserValue2 = copy.UserValue2;
|
||||
UserValue3 = copy.UserValue3;
|
||||
if (null == tags) { UserTags = null; }
|
||||
else if (tags.Any())
|
||||
{
|
||||
var userTags = new byte[tags.Length];
|
||||
Array.Copy(tags, userTags, tags.Length);
|
||||
UserTags = userTags;
|
||||
}
|
||||
else { UserTags = new byte[0]; }
|
||||
}
|
||||
public SquibDbRecord() { }
|
||||
public SquibDbRecord(ISquibDbRecord copy)
|
||||
{
|
||||
Id = copy.Id;
|
||||
IsoChannelName = copy.IsoChannelName;
|
||||
UserCode = copy.UserCode;
|
||||
UserChannelName = copy.UserChannelName;
|
||||
Broken = copy.Broken;
|
||||
DoNotUse = copy.DoNotUse;
|
||||
Version = copy.Version;
|
||||
SquibToleranceLow = copy.SquibToleranceLow;
|
||||
SquibToleranceHigh = copy.SquibToleranceHigh;
|
||||
SquibOutputCurrent = copy.SquibOutputCurrent;
|
||||
SerialNumber = copy.SerialNumber;
|
||||
MeasurementType = copy.MeasurementType;
|
||||
LimitDuration = copy.LimitDuration;
|
||||
DefineDelayInTest = copy.DefineDelayInTest;
|
||||
LastModifiedBy = copy.LastModifiedBy;
|
||||
LastModified = copy.LastModified;
|
||||
IsoCode = copy.IsoCode;
|
||||
FireMode = copy.FireMode;
|
||||
DurationMs = copy.DurationMs;
|
||||
DelayMs = copy.DelayMs;
|
||||
BypassVoltageFilter = copy.BypassVoltageFilter;
|
||||
BypassCurrentFilter = copy.BypassCurrentFilter;
|
||||
ArticleId = copy.ArticleId;
|
||||
UserValue1 = copy.UserValue1;
|
||||
//Comment = UserValue1;
|
||||
UserValue2 = copy.UserValue2;
|
||||
UserValue3 = copy.UserValue3;
|
||||
if( null == copy.UserTags) { UserTags = null; }
|
||||
else if(copy.UserTags.Any())
|
||||
{
|
||||
var userTags = new byte[copy.UserTags.Length];
|
||||
Array.Copy(copy.UserTags, userTags, copy.UserTags.Length);
|
||||
UserTags = userTags;
|
||||
}
|
||||
else { UserTags = new byte[0]; }
|
||||
}
|
||||
public SquibDbRecord(IDataReader reader)
|
||||
{
|
||||
try
|
||||
{
|
||||
Id = Utility.GetInt(reader, "Id", -1);
|
||||
IsoChannelName = Utility.GetString(reader, "ISOChannelName", string.Empty);
|
||||
UserCode = Utility.GetString(reader, "UserCode", string.Empty);
|
||||
UserChannelName = Utility.GetString(reader, "UserChannelName", string.Empty);
|
||||
Broken = Utility.GetBool(reader, "Broken", false);
|
||||
DoNotUse = Utility.GetBool(reader, "DoNotUse", false);
|
||||
Version = Utility.GetInt(reader, "Version", -1);
|
||||
SquibToleranceLow = Utility.GetDouble(reader, "SquibToleranceLow", 0D);
|
||||
SquibToleranceHigh = Utility.GetDouble(reader, "SquibToleranceHigh", 8D);
|
||||
SquibOutputCurrent = Utility.GetDouble(reader, "SquibOutputCurrent", 1.5D);
|
||||
SerialNumber = Utility.GetString(reader, "SerialNumber", string.Empty);
|
||||
MeasurementType = (SquibMeasurementType)Utility.GetShort(reader, "MeasurementType");
|
||||
LimitDuration = Utility.GetBool(reader, "LimitDuration");
|
||||
DefineDelayInTest = Utility.GetBool(reader, "DefineDelayInTest");
|
||||
LastModifiedBy = Utility.GetString(reader, "LastModifiedBy", string.Empty);
|
||||
LastModified = Utility.GetDateTime(reader, "LastModified", DateTime.MinValue);
|
||||
IsoCode = Utility.GetString(reader, "ISOCode", string.Empty);
|
||||
FireMode = (SquibFireMode)Utility.GetShort(reader, "FireMode");
|
||||
DurationMs = Utility.GetDouble(reader, "DurationMS", 0D);
|
||||
DelayMs = Utility.GetDouble(reader, "DelayMS", 0D);
|
||||
BypassVoltageFilter = Utility.GetBool(reader, "BypassVoltageFilter", false);
|
||||
BypassCurrentFilter = Utility.GetBool(reader, "BypassCurrentFilter", false);
|
||||
ArticleId = Utility.GetString(reader, "ArticleId", string.Empty);
|
||||
UserValue1 = Utility.GetString(reader, "UserValue1");
|
||||
//Comment = UserValue1;
|
||||
UserValue2 = Utility.GetString(reader, "UserValue2", string.Empty);
|
||||
UserValue3 = Utility.GetString(reader, "UserValue3", string.Empty);
|
||||
var o = reader["UserTags"];
|
||||
UserTags = DBNull.Value.Equals(o)
|
||||
? new byte[0]
|
||||
: (byte[])o;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to process: ", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
98
Common/DTS.CommonCore/Classes/Sensors/StreamInputRecord.cs
Normal file
98
Common/DTS.CommonCore/Classes/Sensors/StreamInputRecord.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.Interface.Tags;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Data;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class StreamInputRecord : TagAwareBase, IStreamInputRecord
|
||||
{
|
||||
public override TagTypes TagType => TagTypes.Sensors;
|
||||
private int _id;
|
||||
public int Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value, "Id");
|
||||
}
|
||||
private string _serialNumber;
|
||||
public string SerialNumber
|
||||
{
|
||||
get => _serialNumber;
|
||||
set => SetProperty(ref _serialNumber, value, "SerialNumber");
|
||||
}
|
||||
private DateTime _lastModified;
|
||||
public DateTime LastModified
|
||||
{
|
||||
get => _lastModified;
|
||||
set => SetProperty(ref _lastModified, value, "LastModified");
|
||||
}
|
||||
private string _lastUpdatedBy;
|
||||
public string LastUpdatedBy
|
||||
{
|
||||
get => _lastUpdatedBy;
|
||||
set => SetProperty(ref _lastUpdatedBy, value, "LastUpdatedBy");
|
||||
}
|
||||
|
||||
private bool _doNotUse;
|
||||
public bool DoNotUse
|
||||
{
|
||||
get => _doNotUse;
|
||||
set => SetProperty(ref _doNotUse, value, "DoNotUse");
|
||||
}
|
||||
private bool _broken;
|
||||
public bool Broken
|
||||
{
|
||||
get => _broken;
|
||||
set => SetProperty(ref _broken, value, "Broken");
|
||||
}
|
||||
|
||||
public const string DEFAULT_UDP_ADDRESS = "UDP://239.1.2.10:8400";
|
||||
protected string _udpAddress = DEFAULT_UDP_ADDRESS;
|
||||
public string StreamInUDPAddress
|
||||
{
|
||||
get => _udpAddress;
|
||||
set => SetProperty(ref _udpAddress, value, "StreamInUDPAddress");
|
||||
}
|
||||
|
||||
public StreamInputRecord(ISensorData sd)
|
||||
{
|
||||
try
|
||||
{
|
||||
Id = sd.DatabaseId;
|
||||
SerialNumber = sd.SerialNumber;
|
||||
|
||||
StreamInUDPAddress = sd.StreamInUDPAddress;
|
||||
|
||||
Broken = sd.Broken;
|
||||
DoNotUse = sd.DoNotUse;
|
||||
LastModified = sd.LastModified;
|
||||
LastUpdatedBy = sd.LastUpdatedBy;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to process: ", ex);
|
||||
}
|
||||
}
|
||||
public StreamInputRecord(IDataReader reader)
|
||||
{
|
||||
try
|
||||
{
|
||||
Id = Utility.GetInt(reader, "Id");
|
||||
SerialNumber = Utility.GetString(reader, "SerialNumber");
|
||||
|
||||
StreamInUDPAddress = Utility.GetString(reader, "UDPAddress");
|
||||
|
||||
Broken = Utility.GetBool(reader, "Broken");
|
||||
DoNotUse = Utility.GetBool(reader, "DoNotUse");
|
||||
LastModified = Utility.GetDateTime(reader, "LastModified", DateTime.MinValue);
|
||||
LastUpdatedBy = Utility.GetString(reader, "LastModifiedBy");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to process: ", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
212
Common/DTS.CommonCore/Classes/Sensors/StreamOutputRecord.cs
Normal file
212
Common/DTS.CommonCore/Classes/Sensors/StreamOutputRecord.cs
Normal file
@@ -0,0 +1,212 @@
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.Interface.Tags;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class StreamOutputRecord : TagAwareBase, IStreamOutputRecord
|
||||
{
|
||||
public override TagTypes TagType => TagTypes.Sensors;
|
||||
private int _id;
|
||||
public int Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value, "Id");
|
||||
}
|
||||
private string _serialNumber;
|
||||
public string SerialNumber
|
||||
{
|
||||
get => _serialNumber;
|
||||
set => SetProperty(ref _serialNumber, value, "SerialNumber");
|
||||
}
|
||||
private DateTime _lastModified;
|
||||
public DateTime LastModified
|
||||
{
|
||||
get => _lastModified;
|
||||
set => SetProperty(ref _lastModified, value, "LastModified");
|
||||
}
|
||||
private string _lastUpdatedBy;
|
||||
public string LastUpdatedBy
|
||||
{
|
||||
get => _lastUpdatedBy;
|
||||
set => SetProperty(ref _lastUpdatedBy, value, "LastUpdatedBy");
|
||||
}
|
||||
|
||||
private bool _doNotUse;
|
||||
public bool DoNotUse
|
||||
{
|
||||
get => _doNotUse;
|
||||
set => SetProperty(ref _doNotUse, value, "DoNotUse");
|
||||
}
|
||||
private bool _broken;
|
||||
public bool Broken
|
||||
{
|
||||
get => _broken;
|
||||
set => SetProperty(ref _broken, value, "Broken");
|
||||
}
|
||||
protected UDPStreamProfile _udpProfile = DEFAULT_UDP_PROFILE;
|
||||
public const UDPStreamProfile DEFAULT_UDP_PROFILE = UDPStreamProfile.CH10_ANALOG_2HDR; //supported on both S6A & TSRAIR
|
||||
public UDPStreamProfile StreamOutUDPProfile
|
||||
{
|
||||
get => _udpProfile;
|
||||
set => SetProperty(ref _udpProfile, value, "StreamOutUDPProfile");
|
||||
}
|
||||
public const string DEFAULT_UDP_ADDRESS = "UDP://239.1.2.10:8400";
|
||||
protected string _udpAddress = DEFAULT_UDP_ADDRESS;
|
||||
public string StreamOutUDPAddress
|
||||
{
|
||||
get => _udpAddress;
|
||||
set => SetProperty(ref _udpAddress, value, "StreamOutUDPAddress");
|
||||
}
|
||||
public const ushort MINIMUM_STREAMOUT_TIMECHANNELID = 10;
|
||||
public const ushort MAXIMUM_STREAMOUT_TIMECHANNELID = 100;
|
||||
public const ushort DEFAULT_UDP_TIME_CHANNEL_ID = 1;
|
||||
protected ushort _udpTimeChannelId = DEFAULT_UDP_TIME_CHANNEL_ID;
|
||||
public ushort StreamOutUDPTimeChannelId
|
||||
{
|
||||
get => _udpTimeChannelId;
|
||||
set => SetProperty(ref _udpTimeChannelId, value, "StreamOutUDPTimeChannelId");
|
||||
}
|
||||
public const ushort MINIMUM_STREAMOUT_DATACHANNELID = 10;
|
||||
public const ushort MAXIMUM_STREAMOUT_DATACHANNELID = 100;
|
||||
public const ushort DEFAULT_UDP_DATA_CHANNEL_ID = 3;
|
||||
protected ushort _udpDataChannelId = DEFAULT_UDP_DATA_CHANNEL_ID;
|
||||
public ushort StreamOutUDPDataChannelId
|
||||
{
|
||||
get => _udpDataChannelId;
|
||||
set => SetProperty(ref _udpDataChannelId, value, "StreamOutUDPDataChannelId");
|
||||
}
|
||||
public const string DEFAULT_UDPTMNS_CONFIG = "(1,6,60,0,0,0,0,0)";
|
||||
protected string _udpTmNSConfig = DEFAULT_UDPTMNS_CONFIG;
|
||||
public string StreamOutUDPTmNSConfig
|
||||
{
|
||||
get => _udpTmNSConfig;
|
||||
set => SetProperty(ref _udpTmNSConfig, value, "StreamOutUDPTmNSConfig");
|
||||
}
|
||||
public const ushort MINIMUM_STREAMOUT_TDP_INTERVAL_MS = 10;
|
||||
public const ushort MAXIMUM_STREAMOUT_TDP_INTERVAL_MS = 1000;
|
||||
public const ushort DEFAULT_IRIG_TIME_DATA_PACKET_INTERVAL_MS = 500;
|
||||
protected ushort _irigTimeDataPacketIntervalMs = DEFAULT_IRIG_TIME_DATA_PACKET_INTERVAL_MS;
|
||||
|
||||
public const ushort MINIMUM_STREAMOUT_TMATS_INTERVAL_MS = ushort.MinValue;
|
||||
public const ushort MAXIMUM_STREAMOUT_TMATS_INTERVAL_MS = ushort.MaxValue;
|
||||
private ushort _streamOutTMATSIntervalMs = DEFAULT_TMATS_INTERVAL_MS;
|
||||
/// <summary>
|
||||
/// time in MS between sending tmats information while streaming
|
||||
/// http://manuscript.dts.local/f/cases/29987/Add-CG-DP-TMATS-interval-UI-support
|
||||
/// </summary>
|
||||
public ushort StreamOutTMATSIntervalMs
|
||||
{
|
||||
get => _streamOutTMATSIntervalMs;
|
||||
set => SetProperty(ref _streamOutTMATSIntervalMs, value, "StreamOutTMATSIntervalMs");
|
||||
}
|
||||
public ushort StreamOutIRIGTimeDataPacketIntervalMs
|
||||
{
|
||||
get => _irigTimeDataPacketIntervalMs;
|
||||
set => SetProperty(ref _irigTimeDataPacketIntervalMs, value, "StreamOutIRIGTimeDataPacketIntervalMs");
|
||||
}
|
||||
public StreamOutputRecord(ISensorData sd)
|
||||
{
|
||||
try
|
||||
{
|
||||
Id = sd.DatabaseId;
|
||||
SerialNumber = sd.SerialNumber;
|
||||
|
||||
StreamOutUDPProfile = sd.StreamOutUDPProfile;
|
||||
StreamOutUDPAddress = sd.StreamOutUDPAddress;
|
||||
StreamOutUDPTimeChannelId = sd.StreamOutUDPTimeChannelId;
|
||||
StreamOutUDPDataChannelId = sd.StreamOutUDPDataChannelId;
|
||||
StreamOutUDPTmNSConfig = sd.StreamOutUDPTmNSConfig;
|
||||
StreamOutIRIGTimeDataPacketIntervalMs = sd.StreamOutIRIGTimeDataPacketIntervalMs;
|
||||
StreamOutTMATSIntervalMs = sd.StreamOutTMATSIntervalMs;
|
||||
|
||||
Broken = sd.Broken;
|
||||
DoNotUse = sd.DoNotUse;
|
||||
LastModified = sd.LastModified;
|
||||
LastUpdatedBy = sd.LastUpdatedBy;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to process: ", ex);
|
||||
}
|
||||
}
|
||||
public StreamOutputRecord(IDataReader reader, int ClientDbVersion, int ConnectionDbVersion)
|
||||
{
|
||||
try
|
||||
{
|
||||
Id = Utility.GetInt(reader, "Id");
|
||||
SerialNumber = Utility.GetString(reader, "SerialNumber");
|
||||
|
||||
StreamOutUDPProfile = (UDPStreamProfile)Enum.Parse(typeof(UDPStreamProfile),
|
||||
Utility.GetString(reader, "StreamProfile"));
|
||||
StreamOutUDPAddress = Utility.GetString(reader, "UDPAddress");
|
||||
StreamOutUDPTimeChannelId = Utility.GetUShort(reader, "TimeChannelId");
|
||||
StreamOutUDPDataChannelId = Utility.GetUShort(reader, "DataChannelId");
|
||||
StreamOutUDPTmNSConfig = Utility.GetString(reader, "TmNSConfig");
|
||||
StreamOutIRIGTimeDataPacketIntervalMs = Utility.GetUShort(reader, "IRIGTimeDataPacketIntervalMs");
|
||||
|
||||
Broken = Utility.GetBool(reader, "Broken");
|
||||
DoNotUse = Utility.GetBool(reader, "DoNotUse");
|
||||
LastModified = Utility.GetDateTime(reader, "LastModified", DateTime.MinValue);
|
||||
LastUpdatedBy = Utility.GetString(reader, "LastModifiedBy");
|
||||
//only try to retrieve this field if both client and db are high enough level
|
||||
if (ClientDbVersion >= Constants.TMATS_INTERVAL_VERSION && ConnectionDbVersion >= Constants.TMATS_INTERVAL_VERSION)
|
||||
{
|
||||
StreamOutTMATSIntervalMs = Utility.GetUShort(reader, "TMATS_IntervalMS", StreamOutputRecord.DEFAULT_TMATS_INTERVAL_MS);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to process: ", ex);
|
||||
}
|
||||
}
|
||||
//28291 Reduce list of Stream profiles to choose from.
|
||||
//Define this here so that it only needs to be changed in one place, if a change needs to be made in the future.
|
||||
//30249 Add LTS behavior for case 30075 (ADC UART stream)
|
||||
public static UDPStreamProfile[] AvailableUDPStreamProfiles(int ConnectionDbVersion, bool UseAdvancedStreamingProfiles)
|
||||
{
|
||||
var profiles = new List<UDPStreamProfile>();
|
||||
if (UseAdvancedStreamingProfiles)
|
||||
{
|
||||
profiles.AddRange(
|
||||
new UDPStreamProfile[]
|
||||
{
|
||||
UDPStreamProfile.CH10_ANALOG,
|
||||
UDPStreamProfile.CH10_ANALOG_2HDR,
|
||||
UDPStreamProfile.CH10_PCM128_MM,
|
||||
UDPStreamProfile.CH10_PCM_128BIT_2HDR,
|
||||
UDPStreamProfile.TMNS_PCM_STANDARD,
|
||||
UDPStreamProfile.TMNS_PCM_SUPERCOM,
|
||||
UDPStreamProfile.IENA_PTYPE_STREAM,
|
||||
UDPStreamProfile.CH10_MANUAL_CONFIG
|
||||
});
|
||||
if (ConnectionDbVersion >= Constants.ADC_TO_UART_DB_VERSION)
|
||||
{
|
||||
profiles.Add(UDPStreamProfile.UART_STREAM);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 31840 Basic / Advanced Streaming profiles
|
||||
profiles.AddRange(
|
||||
new UDPStreamProfile[]
|
||||
{
|
||||
UDPStreamProfile.CH10_ANALOG_2HDR,
|
||||
UDPStreamProfile.CH10_PCM_128BIT_2HDR
|
||||
});
|
||||
}
|
||||
return profiles.ToArray();
|
||||
}
|
||||
/// <summary>
|
||||
/// the default interval between sending out tmats information while streaming
|
||||
/// this is used if the value is not set or is null
|
||||
/// http://manuscript.dts.local/f/cases/29987/Add-CG-DP-TMATS-interval-UI-support
|
||||
/// </summary>
|
||||
public const ushort DEFAULT_TMATS_INTERVAL_MS = 1000;
|
||||
}
|
||||
}
|
||||
138
Common/DTS.CommonCore/Classes/Sensors/UARTRecord.cs
Normal file
138
Common/DTS.CommonCore/Classes/Sensors/UARTRecord.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using DTS.Common.Base;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.Interface.Tags;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class UARTRecord : TagAwareBase, IUARTRecord
|
||||
{
|
||||
public override TagTypes TagType { get => TagTypes.Sensors; }
|
||||
private int _id;
|
||||
public int Id
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty(ref _id, value, "Id");
|
||||
}
|
||||
private string _serialNumber;
|
||||
public string SerialNumber
|
||||
{
|
||||
get => _serialNumber;
|
||||
set => SetProperty(ref _serialNumber, value, "SerialNumber");
|
||||
}
|
||||
public const uint UART_BAUDRATE_DEFAULT = 57600;
|
||||
private uint _uartBaudRate = UART_BAUDRATE_DEFAULT;
|
||||
public uint UartBaudRate
|
||||
{
|
||||
get => _uartBaudRate;
|
||||
set => _uartBaudRate = value;
|
||||
}
|
||||
public const uint UART_DATABITS_DEFAULT = 8;
|
||||
private uint _uartDataBits = UART_DATABITS_DEFAULT;
|
||||
public uint UartDataBits
|
||||
{
|
||||
get => _uartDataBits;
|
||||
set => SetProperty(ref _uartDataBits, value, "UartDataBits");
|
||||
}
|
||||
private StopBits _uartStopBits = StopBits.None;
|
||||
public const StopBits UART_STOPBITS_DEFAULT = StopBits.None;
|
||||
public StopBits UartStopBits
|
||||
{
|
||||
get => _uartStopBits;
|
||||
set => _uartStopBits = value;
|
||||
}
|
||||
public const UartDataFormat UART_DATAFORMAT_DEFAULT = UartDataFormat.Binary;
|
||||
|
||||
public const Handshake UART_FLOWCONTROL_DEFAULT = Handshake.None;
|
||||
protected Handshake _flowControl = Handshake.None;
|
||||
public Handshake UartFlowControl
|
||||
{
|
||||
get => _flowControl;
|
||||
set => SetProperty(ref _flowControl, value, "UartFlowControl");
|
||||
}
|
||||
|
||||
private UartDataFormat _uartDataFormat = UART_DATAFORMAT_DEFAULT;
|
||||
public UartDataFormat UartDataFormat
|
||||
{
|
||||
get => _uartDataFormat;
|
||||
set => SetProperty(ref _uartDataFormat, value, "UartDataFormat");
|
||||
}
|
||||
private DateTime _lastModified;
|
||||
public DateTime LastModified
|
||||
{
|
||||
get => _lastModified;
|
||||
set => SetProperty(ref _lastModified, value, "LastModified");
|
||||
}
|
||||
private string _lastUpdatedBy;
|
||||
public string LastUpdatedBy
|
||||
{
|
||||
get => _lastUpdatedBy;
|
||||
set => SetProperty(ref _lastUpdatedBy, value, "LastUpdatedBy");
|
||||
}
|
||||
|
||||
private bool _doNotUse;
|
||||
public bool DoNotUse
|
||||
{
|
||||
get => _doNotUse;
|
||||
set => SetProperty(ref _doNotUse, value, "DoNotUse");
|
||||
}
|
||||
private bool _broken;
|
||||
public bool Broken
|
||||
{
|
||||
get => _broken;
|
||||
set => SetProperty(ref _broken, value, "Broken");
|
||||
}
|
||||
public const Parity UART_PARITY_DEFAULT = Parity.None;
|
||||
protected Parity _parity = Parity.None;
|
||||
public Parity UartParity
|
||||
{
|
||||
get => _parity;
|
||||
set => SetProperty(ref _parity, value, "UartParity");
|
||||
}
|
||||
public UARTRecord(ISensorData sensor)
|
||||
{
|
||||
Id = sensor.DatabaseId;
|
||||
SerialNumber = sensor.SerialNumber;
|
||||
|
||||
UartBaudRate = sensor.UartBaudRate;
|
||||
UartDataBits = sensor.UartDataBits;
|
||||
UartStopBits = sensor.UartStopBits;
|
||||
UartParity = sensor.UartParity;
|
||||
UartFlowControl = sensor.UartFlowControl;
|
||||
UartDataFormat = sensor.UartDataFormat;
|
||||
|
||||
Broken = sensor.Broken;
|
||||
DoNotUse = sensor.DoNotUse;
|
||||
LastModified = sensor.LastModified;
|
||||
LastUpdatedBy = sensor.LastUpdatedBy;
|
||||
}
|
||||
public UARTRecord(IDataReader reader)
|
||||
{
|
||||
try
|
||||
{
|
||||
Id = Utility.GetInt(reader,"Id");
|
||||
SerialNumber = Utility.GetString(reader, "SerialNumber");
|
||||
|
||||
UartBaudRate = Utility.GetUInt(reader, "BaudRate");
|
||||
UartDataBits = Utility.GetUInt(reader, "DataBits");
|
||||
UartStopBits = (StopBits)Enum.Parse(typeof(StopBits), Utility.GetString(reader, "StopBits"));
|
||||
UartParity = (Parity)Enum.Parse(typeof(Parity), Utility.GetString(reader, "Parity"));
|
||||
UartFlowControl = (Handshake)Enum.Parse(typeof(Handshake), Utility.GetString(reader, "FlowControl"));
|
||||
UartDataFormat = (UartDataFormat)Enum.Parse(typeof(UartDataFormat), Utility.GetString(reader, "DataFormat"));
|
||||
|
||||
Broken = Utility.GetBool(reader, "Broken");
|
||||
DoNotUse = Utility.GetBool(reader, "DoNotUse");
|
||||
LastModified = Utility.GetDateTime(reader, "LastModified", DateTime.MinValue);
|
||||
LastUpdatedBy = Utility.GetString(reader, "LastModifiedBy");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to process: ", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
304
Common/DTS.CommonCore/Classes/Sensors/ZeroMethod.cs
Normal file
304
Common/DTS.CommonCore/Classes/Sensors/ZeroMethod.cs
Normal file
@@ -0,0 +1,304 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using System.ComponentModel;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
public class ZeroMethod : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected bool SetProperty<T>(ref T storage, T value, String propertyName = null)
|
||||
{
|
||||
if (Equals(storage, value)) return false;
|
||||
|
||||
storage = value;
|
||||
OnPropertyChanged(propertyName);
|
||||
return true;
|
||||
}
|
||||
protected void OnPropertyChanged(string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Method.GetHashCode() + Start.GetHashCode() + End.GetHashCode();
|
||||
}
|
||||
|
||||
public ZeroMethodType Method { get; set; } = SensorConstants.DefaultZeroMethodType; // FB12764: Belt-and-suspenders, fetch default from SensorConstants
|
||||
|
||||
public double Start { get; set; } = SensorConstants.DefaultZeroMethodStart; // FB12764: Belt-and-suspenders, fetch default from SensorConstants
|
||||
|
||||
public double End { get; set; } = SensorConstants.DefaultZeroMethodEnd; // FB12764: Belt-and-suspenders, fetch default from SensorConstants
|
||||
|
||||
#region Tags
|
||||
|
||||
internal const string ZERO_METHOD_TAG = "ZeroMethod";
|
||||
internal const string METHOD_TAG = "Method";
|
||||
internal const string START_TAG = "Start";
|
||||
internal const string END_TAG = "End";
|
||||
|
||||
#endregion
|
||||
|
||||
public ZeroMethod(ZeroMethodType zm, double start, double end)
|
||||
{
|
||||
Method = zm;
|
||||
Start = start;
|
||||
End = end;
|
||||
}
|
||||
|
||||
public ZeroMethod(string zm, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
Initialize(zm, culture);
|
||||
}
|
||||
public ZeroMethod(string zm)
|
||||
{
|
||||
Initialize(zm, System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
/// <summary>
|
||||
/// do a deep copy
|
||||
/// </summary>
|
||||
/// <param name="copy"></param>
|
||||
public ZeroMethod(ZeroMethod copy)
|
||||
{
|
||||
Method = copy.Method;
|
||||
Start = copy.Start;
|
||||
End = copy.End;
|
||||
}
|
||||
private void Initialize(string zm, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
var tokens = zm.Split(',');
|
||||
if (tokens.Length < 3) { return; }
|
||||
Start = Convert.ToDouble(tokens[1], culture);
|
||||
End = Convert.ToDouble(tokens[2], culture);
|
||||
if( tokens[0].Contains("PreCalZero") )
|
||||
{
|
||||
Method = ZeroMethodType.UsePreEventDiagnosticsZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
Method = (ZeroMethodType)
|
||||
Enum.Parse(typeof(ZeroMethodType), tokens[0]);
|
||||
}
|
||||
}
|
||||
public string ToDbString()
|
||||
{
|
||||
return $"{Method.ToString()},{Start},{End}";
|
||||
}
|
||||
private readonly string _tableName;
|
||||
public ZeroMethod(XElement elem, string prefix, string tblName, string id)
|
||||
{
|
||||
_tableName = tblName;
|
||||
XElement inner;
|
||||
try
|
||||
{
|
||||
inner = elem.Element(mkTag(prefix));
|
||||
}
|
||||
catch (ArgumentNullException)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
throw new Exception($"{_tableName}: Can't find tag {prefix + "-" + ZERO_METHOD_TAG} for entry {id}");
|
||||
}
|
||||
throw new Exception($"{_tableName}: Can't find tag {prefix + "-" + ZERO_METHOD_TAG} in file");
|
||||
}
|
||||
try
|
||||
{
|
||||
// this is a special case to remain compatible with older TDM
|
||||
// I moved this to avoid the exception
|
||||
// 6/8/2010 - dtm
|
||||
if (inner.Value == "UsePreCalZero")
|
||||
{
|
||||
Method = ZeroMethodType.UsePreEventDiagnosticsZero;
|
||||
}
|
||||
else if (inner.Value == ZeroMethodType.UsePreEventDiagnosticsZero.ToString())
|
||||
{
|
||||
inner.Value = "UsePreCalZero";
|
||||
Method = ZeroMethodType.UsePreEventDiagnosticsZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
Method = (ZeroMethodType) Enum.Parse(typeof(ZeroMethodType), inner.Value);
|
||||
}
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
throw;
|
||||
}
|
||||
Start = double.Parse(inner.Attribute(START_TAG).Value, System.Globalization.CultureInfo.InvariantCulture);
|
||||
End = double.Parse(inner.Attribute(END_TAG).Value, System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
internal XElement ToXElement(string prefix)
|
||||
{
|
||||
string value;
|
||||
switch (Method)
|
||||
{
|
||||
case ZeroMethodType.UsePreEventDiagnosticsZero:
|
||||
value = "UsePreCalZero";
|
||||
break;
|
||||
default:
|
||||
value = Method.ToString();
|
||||
break;
|
||||
}
|
||||
|
||||
var element = new XElement(mkTag(prefix), value);
|
||||
element.SetAttributeValue(START_TAG, Start);
|
||||
element.SetAttributeValue(END_TAG, End);
|
||||
return element;
|
||||
}
|
||||
|
||||
internal void Update(XElement elem, string prefix)
|
||||
{
|
||||
elem.SetElementValue(mkTag(prefix), Method.ToString());
|
||||
var element = elem.Element(mkTag(prefix));
|
||||
element.SetAttributeValue(START_TAG, Start);
|
||||
element.SetAttributeValue(END_TAG, End);
|
||||
}
|
||||
|
||||
internal static string mkTag(string prefix)
|
||||
{
|
||||
return prefix + "-" + ZERO_METHOD_TAG;
|
||||
}
|
||||
|
||||
public string ToSerializeString()
|
||||
{
|
||||
return $"{Method.ToString()},{Start.ToString(System.Globalization.CultureInfo.InvariantCulture)},{End.ToString(System.Globalization.CultureInfo.InvariantCulture)}";
|
||||
}
|
||||
|
||||
|
||||
public string ToDisplayString(string averageOverTimeFormatString, string diagnosticLevelFormatString, string absoluteZeroFormatString)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
switch (Method)
|
||||
{
|
||||
case ZeroMethodType.AverageOverTime:
|
||||
sb.AppendFormat("{0} from {1} to {2}", averageOverTimeFormatString, Start, End);
|
||||
break;
|
||||
case ZeroMethodType.UsePreEventDiagnosticsZero:
|
||||
sb.AppendFormat("{0}", diagnosticLevelFormatString);
|
||||
break;
|
||||
case ZeroMethodType.None:
|
||||
sb.AppendFormat("{0}", absoluteZeroFormatString);
|
||||
break;
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ZeroMethod zm)
|
||||
{
|
||||
return zm.Method == Method && zm.Start == Start && zm.End == End;
|
||||
}
|
||||
return base.Equals(obj);
|
||||
}
|
||||
}
|
||||
|
||||
public class ZeroMethods : IZeroMethods
|
||||
{
|
||||
public ZeroMethod[] Methods { get; set; } = new ZeroMethod[] { };
|
||||
|
||||
public ZeroMethods(ZeroMethods copy) : this(copy.Methods)
|
||||
{
|
||||
}
|
||||
|
||||
public ZeroMethods(ZeroMethod[] copyMethods)
|
||||
{
|
||||
ZeroMethod[] methods = new ZeroMethod[copyMethods.Length];
|
||||
for (int i = 0; i < copyMethods.Length; i++)
|
||||
{
|
||||
methods[i] = new ZeroMethod(copyMethods[i]);
|
||||
}
|
||||
Methods = methods;
|
||||
}
|
||||
|
||||
public ZeroMethods()
|
||||
{
|
||||
Methods = new ZeroMethod[] { };
|
||||
}
|
||||
public ZeroMethods(string methods)
|
||||
{
|
||||
FromSerializedString(methods);
|
||||
}
|
||||
|
||||
public ZeroMethods(ZeroMethod startingMethod)
|
||||
{
|
||||
Methods = new ZeroMethod[] { startingMethod };
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ZeroMethods r)
|
||||
{
|
||||
if (r.Methods.Length != Methods.Length) { return false; }
|
||||
for (int i = 0; i < r.Methods.Length; i++)
|
||||
{
|
||||
if (!r.Methods[i].Equals(Methods[i])) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return base.Equals(obj);
|
||||
}
|
||||
public void FromSerializedString(string s)
|
||||
{
|
||||
string[] tokens = s.Split(new string[] { MySeparator }, StringSplitOptions.None);
|
||||
for (int i = 0; i < tokens.Length; i++) { tokens[i] = tokens[i].Replace(MySeparatorBackup, MySeparator); }
|
||||
|
||||
List<ZeroMethod> methods = new List<ZeroMethod>();
|
||||
foreach (string token in tokens)
|
||||
{
|
||||
methods.Add(new ZeroMethod(token));
|
||||
}
|
||||
Methods = methods.ToArray();
|
||||
}
|
||||
private const string MySeparator = "__x__";
|
||||
private const string MySeparatorBackup = "___xx___";
|
||||
public string ToSerializedString()
|
||||
{
|
||||
List<string> methods = new List<string>();
|
||||
|
||||
foreach (var r in Methods) { methods.Add(r.ToSerializeString()); }
|
||||
|
||||
for (int i = 0; i < methods.Count; i++)
|
||||
{
|
||||
System.Diagnostics.Trace.Assert(!methods[i].Contains(MySeparatorBackup));
|
||||
methods[i] = methods[i].Replace(MySeparator, MySeparatorBackup);
|
||||
}
|
||||
return string.Join(MySeparator, methods.ToArray());
|
||||
}
|
||||
|
||||
public string ToDisplayString(string averageOverTimeFormatString, string diagnosticLevelFormatString, string absoluteZeroFormatString)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
/*foreach (var r in Methods)
|
||||
{
|
||||
if (currentMethod > 1) { sb.AppendLine(); }
|
||||
sb.AppendFormat("{0}: {1}", currentMethod++, r.ToDisplayString(sc));
|
||||
}*/
|
||||
for (int i = 0; i < Methods.Length; i++)
|
||||
{
|
||||
if (i > 0) { sb.AppendLine(); }
|
||||
|
||||
string s = Methods[i].ToDisplayString(averageOverTimeFormatString, diagnosticLevelFormatString, absoluteZeroFormatString);
|
||||
if (!string.IsNullOrEmpty(s))
|
||||
{
|
||||
sb.Append(s);
|
||||
}
|
||||
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return ToDisplayString(Strings.Strings.SensorFields_InitialOffset_AverageOverTimeFormat, Strings.Strings.SensorFields_InitialOffset_DiagnosticLevelFormat,
|
||||
Strings.Strings.SensorFields_InitialOffset_AbsoluteZeroFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
52
Common/DTS.CommonCore/Classes/Sensors/ZeroRef.cs
Normal file
52
Common/DTS.CommonCore/Classes/Sensors/ZeroRef.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.Common.Classes.Sensors
|
||||
{
|
||||
/// <summary>
|
||||
/// public helper class for ZeroRefence in SIFs, which is serialized to an int
|
||||
/// </summary>
|
||||
public class ZeroRef
|
||||
{
|
||||
public enum ZeroType
|
||||
{
|
||||
AverageOverTime,
|
||||
UsePreEventDiagnostics,
|
||||
UseZeroMv
|
||||
}
|
||||
|
||||
public ZeroType ZeroMethod { get; }
|
||||
|
||||
public ZeroRef(string zeroref)
|
||||
{
|
||||
switch (zeroref)
|
||||
{
|
||||
case "0":
|
||||
ZeroMethod = ZeroType.AverageOverTime;
|
||||
break;
|
||||
case "1":
|
||||
ZeroMethod = ZeroType.UsePreEventDiagnostics;
|
||||
break;
|
||||
case "2":
|
||||
ZeroMethod = ZeroType.UseZeroMv;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("TDAS::ZeroRef Invalid ZeroRef " + zeroref);
|
||||
}
|
||||
}
|
||||
public ZeroRef(ZeroType type) { ZeroMethod = type; }
|
||||
public override string ToString()
|
||||
{
|
||||
switch (ZeroMethod)
|
||||
{
|
||||
case ZeroType.AverageOverTime:
|
||||
return "0";
|
||||
case ZeroType.UsePreEventDiagnostics:
|
||||
return "1";
|
||||
case ZeroType.UseZeroMv:
|
||||
return "2";
|
||||
default:
|
||||
throw new NotSupportedException("TDAS::ZeroRef Invalid ZeroRef " + ZeroMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user