Files
DP44/Common/DTS.CommonCore/.svn/pristine/f3/f3356572da32ea7c0e53829f5db14c679af63622.svn-base

732 lines
28 KiB
Plaintext
Raw Normal View History

2026-04-17 14:55:32 -04:00
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");
}
}
}