using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using DTS.Common.DAS.Concepts; using System.Data; using DTS.Common.Enums; using DTS.Common.Storage; using DTS.Common.Utilities.Logging; using DTS.Common.Interface.Sensors; using DTS.Common.Enums.Sensors; using DTS.Common.Classes.Sensors; using System.Data.SqlClient; using System.IO.Ports; using DTS.Common.Interface.Tags; using DTS.Common.Classes.DASFactory; using DTS.Common; using System.Globalization; using DTS.Common.Constant; namespace DTS.SensorDB { public class SensorData : SensorBase, IComparable, ISensorData, IUARTRecord { public new BridgeLeg BridgeLegMode { get => (BridgeLeg)base.BridgeLegMode; set => base.BridgeLegMode = (short)value; } public new int TimesUsed { get => Convert.ToInt32(base.TimesUsed); set => base.TimesUsed = value; } /// /// sets the first use date of the sensor in the db to today /// /// public static void SetFirstUseDate(ISensorData sensor) { using (var sql = DbOperations.GetSQLCommand(true)) { try { sql.CommandType = CommandType.StoredProcedure; sql.CommandText = "sp_SensorsAnalogFirstUseSet"; sql.Parameters.Add(new SqlParameter("@SensorId", SqlDbType.Int) { Value = sensor.DatabaseId }); sql.Parameters.Add(new SqlParameter("@FirstUseDate", SqlDbType.DateTime) { Value = DateTime.Today }); var errorNumber = new SqlParameter("@errorNumber", SqlDbType.Int) { Direction = ParameterDirection.Output }; sql.Parameters.Add(errorNumber); var errorMessage = new SqlParameter("@errorMessage", SqlDbType.NVarChar, 255) { Direction = ParameterDirection.Output }; sql.Parameters.Add(errorMessage); sql.ExecuteNonQuery(); if (!DBNull.Value.Equals(errorNumber.Value)) { if (Convert.ToInt32(errorNumber.Value) != 0) { throw new Exception( $"Failed to set sensor first use date {sensor.SerialNumber}, {Convert.ToString(errorMessage.Value)}"); } } } finally { sql.Connection.Dispose(); } } } //FB 43246 public static bool IsInspectBeforeUseSet(SensorData data) { if (data.InspectBeforeUseCleared) { return false; } SensorCalibrationList.Reload(); var sensorCalibrations = SensorCalibrationList.GetCalibrationsBySerialNumber(data); return sensorCalibrations.Any(p => p.SensitivityInspection == SensitivityInspectionType.Required); } public static bool IsInspectBeforeUseSet(int sensorId) { var hr = DbOperations.SensorCalibrationsGet(sensorId, null, out var calRecords); if (0 != hr || null == calRecords || !calRecords.Any()) { return false; } return calRecords.Any(p => p.SensitivityInspection == SensitivityInspectionType.Required); } /// /// sets the first use date of the sensor in the db to today /// /// public static void SetSensitivityInspection(ISensorData sensor, string clearedCalibrationNote = "") { int? sensorCalibrationId = null; if (sensor.Calibration.SensitivityInspection == SensitivityInspectionType.Cleared) { SensorCalibrationList.Reload(); var sensorCalibrations = SensorCalibrationList.GetCalibrationsBySerialNumber((SensorData)sensor); var sensorCalibration = sensorCalibrations.FirstOrDefault(p => p.SensitivityInspection == SensitivityInspectionType.Required); if (sensorCalibration == null) { return; } sensorCalibrationId = sensorCalibration.CalibrationId; } else if (sensor.Calibration.SensitivityInspection == SensitivityInspectionType.Required) { sensorCalibrationId = sensor.Calibration.CalibrationId; } else { return; } using (var sql = DbOperations.GetSQLCommand(true)) { try { sql.CommandType = CommandType.StoredProcedure; sql.CommandText = "sp_SensorCalibrationsSensitivityInspectionSet"; sql.Parameters.Add(new SqlParameter("@SensorId", SqlDbType.Int) { Value = sensor.DatabaseId }); sql.Parameters.Add(new SqlParameter("@SensorCalibrationId", SqlDbType.Int) {Value = sensorCalibrationId }); sql.Parameters.Add(new SqlParameter("@SensitivityInspection", SqlDbType.Int) { Value = sensor.Calibration.SensitivityInspection }); if (!string.IsNullOrEmpty(clearedCalibrationNote)) { sql.Parameters.Add(new SqlParameter("@CalibrationNote", SqlDbType.NVarChar, 2048) { Value = clearedCalibrationNote }); } else { sql.Parameters.Add(new SqlParameter("@CalibrationNote", SqlDbType.NVarChar, 2048) { Value = DBNull.Value}); } var errorNumber = new SqlParameter("@errorNumber", SqlDbType.Int) { Direction = ParameterDirection.Output }; sql.Parameters.Add(errorNumber); var errorMessage = new SqlParameter("@errorMessage", SqlDbType.NVarChar, 255) { Direction = ParameterDirection.Output }; sql.Parameters.Add(errorMessage); sql.ExecuteNonQuery(); if (!DBNull.Value.Equals(errorNumber.Value) && Convert.ToInt32(errorNumber.Value) != 0) { throw new Exception( $"Failed to set SensitivityInspection to {sensor.Calibration.SensitivityInspection} for sensor {sensor.SerialNumber}, {Convert.ToString(errorMessage.Value)}"); } } finally { sql.Connection.Dispose(); } } } public bool IsAnalog() { return !IsDigitalInput() && !IsDigitalOutput() && !IsSquib() && !IsUart() && !IsStreamInput() && !IsStreamOutput() && !IsThermocoupler() && !IsCan(); } /// /// initial offset information is stored in a sensor calibration at least in terms of possible settings for the sensor /// HOWEVER, the offset to use is stored here for convenience, this is the result of group or test parameters /// /// public InitialOffset InitialOffset { get; set; } = null; public ISensorCalibration GetLatestCalibration() { return SensorCalibrationList.GetLatestCalibrationBySerialNumber(this); } public ISensorCalibration NewEmbeddedSC(string units) { return SensorCalibrationList.NewEmbeddedSC(units); } public void Initialize(ISquibSettingDefaults defaults) { SquibFireDelayMS = defaults.FireDelayMS; SquibFireDurationMS = defaults.FireDurationMS; SquibFireMode = defaults.FireModeDefault; LimitSquibFireDuration = defaults.LimitDurationDefault; SquibOutputCurrent = defaults.OutputCurrentDefault; SquibToleranceHigh = defaults.ToleranceHighDefault; SquibToleranceLow = defaults.ToleranceLowDefault; } public void Initialize(IDigitalOutDefaults defaults) { DigitalOutputDelayMS = defaults.DelayMS; DigitalOutputDurationMS = defaults.DurationMS; DigitalOutputLimitDuration = defaults.LimitDuration; DigitalOutputMode = defaults.OutputMode; } public void Initialize(IUartSettingDefaults defaults) { UartBaudRate = defaults.BaudRate; UartDataBits = defaults.DataBits; UartStopBits = defaults.StopBits; UartParity = defaults.Parity; //FB 30486 Hardcode FlowControl to NONE for UART sensor type UartDataFormat = defaults.DataFormat; } public void Initialize(IStreamOutputSettingDefaults defaults) { StreamOutUDPProfile = defaults.Profile; StreamOutUDPAddress = defaults.UDPAddress; StreamOutUDPTimeChannelId = defaults.TimeChannelId; StreamOutUDPDataChannelId = defaults.DataChannelId; StreamOutUDPTmNSConfig = defaults.TmNSConfig; StreamOutIRIGTimeDataPacketIntervalMs = defaults.IRIGTimeDataPacketIntervalMs; StreamOutTMATSIntervalMs = StreamOutputRecord.DEFAULT_TMATS_INTERVAL_MS; } public void Initialize(ICanSettingDefaults defaults) { CanIsFD = defaults.IsFD; CanArbBaseBitrate = defaults.ArbBaseBitrate; CanArbBaseSJW = defaults.ArbBaseSJW; CanDataBitrate = defaults.DataBitrate; CanDataSJW = defaults.DataSJW; CanFileType = defaults.FileType; } public void Initialize(IStreamInputSettingDefaults defaults) { StreamInUDPAddress = defaults.UDPAddress; } public void InitializeTag(SensorConstants.BridgeType bridgeType) { SetTags(bridgeType == SensorConstants.BridgeType.DigitalInput ? new string[] { "Digital In" } : new string[] { "" }, DbOperations.GetSQLCommand, DbOperations.TagsGet, DbOperations.TagsGetId, DbOperations.TagsInsert); } public int DatabaseId { get => Id; set { Id = value; OnPropertyChanged("DatabaseId"); } } public short GetSensorType() { if (IsSquib()) { return 3; } if (IsDigitalInput()) { return 1; } if (IsDigitalOutput()) { return 2; } if (IsUart()) { return 4; } return 0; } public int SensorCalWarningPeriodDays { get; set; } public override TagTypes TagType => TagTypes.Sensors; /// /// gets the offset in terms of EU regardless of form /// /// the calibration to calculate with /// this is important as EU@mV is connected to a sensitivity value /// /// /// /// public static double GetInitialEUValue(ISensorCalibration sc, ExcitationVoltageOptions.ExcitationVoltageOption voltage, InitialOffset io) { switch (io.Form) { case InitialOffsetTypes.EU: return io.EU; case InitialOffsetTypes.None: return 0D; case InitialOffsetTypes.EUAtMV: { if (sc.NonLinear) { return 0D; } foreach (var r in sc.Records.Records) { if (r.Excitation != voltage) continue; //changed per takashi if (sc.IsProportional) { return io.EU - (io.MV / r.Sensitivity) / Test.Module.Channel.Sensor.GetExcitationVoltageMagnitudeFromEnum(voltage); } return io.EU - io.MV / r.Sensitivity; } } throw new NullReferenceException("No calibration record found for " + voltage); default: throw new NotSupportedException("InitialOffset::GetInitialEUValue unsupported form: " + io.Form); } } public bool IsTestSpecificDigitalOutput { get => SensorConstants.IsTestSpecificDigitalOut(SerialNumber); set { if (value) { SerialNumber = $"{SensorConstants.TEST_SPECIFIC_DOUT}{Guid.NewGuid()}"; } } } public bool IsTestSpecificSquib { get => SensorConstants.IsTestSpecificSquib(SerialNumber); set { if (value) { SerialNumber = $"{SensorConstants.TEST_SPECIFIC_SQUIB}{Guid.NewGuid()}"; } } } /// /// returns true if the sensor is a test specific digital input /// a digital input only created within a specific test /// public bool IsTestSpecificDigitalIn { get => SensorConstants.IsTestSpecificDigitalIn(SerialNumber); set { if (value) { SerialNumber = $"{SensorConstants.TEST_SPECIFIC_DIN}{Guid.NewGuid()}"; } } } /// /// returns true if the channel is test specific embedded /// public bool IsTestSpecificEmbedded { get => SensorConstants.IsTestSpecificEmbedded(SerialNumber); set { if (value) { SerialNumber = $"{SensorConstants.TEST_SPECIFIC_EMB}{Guid.NewGuid()}"; } } } /// /// returns true if the channel is a test specific thermocouple /// public bool IsTestSpecificThermo { get => SensorConstants.IsTestSpecificThermoCouple(SerialNumber); } public bool IsTestSpecificEmbeddedClock { get => SensorConstants.IsTestSpecificEmbeddedClock(SerialNumber); set { if (value) { SerialNumber = $"{SensorConstants.TEST_SPECIFIC_EMB_CLK}{Guid.NewGuid()}"; } } } public bool IsTestSpecificUart { get => SensorConstants.IsTestSpecificUart(SerialNumber); set { if (value) { SerialNumber = $"{SensorConstants.TEST_SPECIFIC_UART}{Guid.NewGuid()}"; } } } public bool IsTestSpecificStreamInput { get => SensorConstants.IsTestSpecificStreamIn(SerialNumber); set { if (value) { SerialNumber = $"{SensorConstants.TEST_SPECIFIC_STREAM_IN}{Guid.NewGuid()}"; } } } public bool IsTestSpecificStreamOutput { get => SensorConstants.IsTestSpecificStreamOut(SerialNumber); set { if (value) { SerialNumber = $"{SensorConstants.TEST_SPECIFIC_STREAM_OUT}{Guid.NewGuid()}"; } } } public bool IsTestSpecificCan { get => SensorConstants.IsTestSpecificCAN(SerialNumber); set { if (value) { SerialNumber = $"{SensorConstants.TEST_SPECIFIC_CAN}{Guid.NewGuid()}"; } } } /// /// At one time all the different DelayMS were using one underlying property for storage, _delayMS. /// Now, the individual SquibFireDelayMS, etc. are defined because we don't want controls that are sharing to limit each other. /// public double DelayMS { get => _delayMS; set => _delayMS = value; } public const double MINIMUM_DIGITALOUTPUT_DELAY_MS = 0D; public const double MAXIMUM_DIGITALOUTPUT_DELAY_MS = 99000D; private double _digitalOutputDelayMS; public double DigitalOutputDelayMS { get => _digitalOutputDelayMS; set { var d = value; if (d < MINIMUM_DIGITALOUTPUT_DELAY_MS) { d = MINIMUM_DIGITALOUTPUT_DELAY_MS; } else if (d > MAXIMUM_DIGITALOUTPUT_DELAY_MS) { d = MAXIMUM_DIGITALOUTPUT_DELAY_MS; } SetProperty(ref _digitalOutputDelayMS, d, "DigitalOutputDelayMS"); } } /// /// At one time all the different DurationMS were using one underlying property for storage, _durationMS. /// Now, the individual SquibFireDurationMS, etc. are defined because we don't want controls that are sharing to limit each other. /// public double DurationMS { get => _durationMS; set => SetProperty(ref _durationMS, value, "DurationMS"); } private double _digitalOutputDurationMS = 10D; public double DigitalOutputDurationMS { get => _digitalOutputDurationMS; set => SetProperty(ref _digitalOutputDurationMS, value, "DigitalOutputDurationMS"); } private DigitalOutputModes _digitalOutputMode = DigitalOutputModes.FVLH; public DigitalOutputModes DigitalOutputMode { get => _digitalOutputMode; set => SetProperty(ref _digitalOutputMode, value, "DigitalOutputMode"); } public bool DigitalOutputLimitDuration { get => _limitDuration; set => SetProperty(ref _limitDuration, value, "LimitDuration"); } private double _delayMS; public double SquibFireDelayMS { get => _delayMS; set => SetProperty(ref _delayMS, value, "SquibFireDelayMS"); } private double _durationMS = 10D; public double SquibFireDurationMS { get => _durationMS; set => SetProperty(ref _durationMS, value, "SquibFireDurationMS"); } /// /// right now all the Limit Duration mechanisms using the same underlying property for storage (_limitDuration), however /// the public access methods (LimitSquibDuration, etc) exist in case we separate them out in the future /// public bool LimitDuration { get => _limitDuration; set => SetProperty(ref _limitDuration, value, "LimitDuration"); } private bool _limitDuration = true; public bool LimitSquibFireDuration { get => _limitDuration; set => SetProperty(ref _limitDuration, value, "LimitSquibFireDuration"); } private bool _defineDelayInTest = false; public bool DefineDelayInTest { get => _defineDelayInTest; set => SetProperty(ref _defineDelayInTest, value, "DefineDelayInTest"); } 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 SquibMeasurementType _squibMeasurementType = SquibMeasurementType.VOLTAGE; public SquibMeasurementType SquibMeasurementType { get => _squibMeasurementType; set => SetProperty(ref _squibMeasurementType, value, "SquibMeasurementType"); } private double _squibOutputCurrent = 1.5D; public double SquibOutputCurrent { get => _squibOutputCurrent; set => SetProperty(ref _squibOutputCurrent, value, "SquibOutputCurrent"); } public new string DisplayUnit { get { if (IsSquib()) { switch (SquibMeasurementType) { case SquibMeasurementType.CURRENT: return "A"; default: return "V"; } } if (null == Calibration || 0 == Calibration.Records.Records.Length) { return ""; } return Calibration.Records.Records[0].EngineeringUnits; //6194 disable display units for the short term } //6194 disable display units for the short term set { } } public bool BypassCurrentFilter => false; public bool BypassVoltageFilter => false; private SquibFireMode _squibFireMode = SquibFireMode.NONE; public SquibFireMode SquibFireMode { get => _squibFireMode; set => SetProperty(ref _squibFireMode, value, "SquibFireMode"); } /// /// the input mode for this setting /// protected DigitalInputModes _inputMode = DigitalInputModes.CCNO; /// /// 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 /// protected DigitalInputScaleMultiplier _digitalInputScaleMultiplier = new DigitalInputScaleMultiplier(); /// /// the setting name allows us to refer to different settings and allow it to be more easily included in test setups and channel setups /// public string SettingName { get => SerialNumber; set { SerialNumber = value; OnPropertyChanged("SettingName"); } } public DigitalInputModes InputMode { get => _inputMode; set => SetProperty(ref _inputMode, value, "InputMode"); } public DigitalInputScaleMultiplier ScaleMultiplier { get => _digitalInputScaleMultiplier; set => SetProperty(ref _digitalInputScaleMultiplier, value, "ScaleMultiplier"); } protected uint _baudRate = DTS.Common.Constant.EmbeddedSensors.BAUD_RATE_DEFAULT; public uint UartBaudRate { get => _baudRate; set => SetProperty(ref _baudRate, value, "UartBaudRate"); } public const uint MINIMUM_UART_DATABITS = 5; public const uint MAXIMUM_UART_DATABITS = 9; protected uint _dataBits = UARTRecord.UART_DATABITS_DEFAULT; public uint UartDataBits { get => _dataBits; set => SetProperty(ref _dataBits, value, "UartDataBits"); } protected StopBits _stopBits = StopBits.None; public StopBits UartStopBits { get => _stopBits; set => SetProperty(ref _stopBits, value, "UartStopBits"); } protected Parity _parity = Parity.None; public Parity UartParity { get => _parity; set => SetProperty(ref _parity, value, "UartParity"); } protected Handshake _flowControl = Handshake.None; public Handshake UartFlowControl { //FB 30486 Hardcode FlowControl to NONE for UART sensor type get => Handshake.None; } protected UartDataFormat _dataFormat = UARTRecord.UART_DATAFORMAT_DEFAULT; public UartDataFormat UartDataFormat { get => _dataFormat; set => SetProperty(ref _dataFormat, value, "UartDataFormat"); } protected bool _canIsFd = EmbeddedSensors.CANISFD_DEFAULT; public bool CanIsFD { get => _canIsFd; set => SetProperty(ref _canIsFd, value, "CanIsFD"); } protected int _canArbBaseBitrate = EmbeddedSensors.CANFD_ARB_BASE_BITRATE_DEFAULT; public int CanArbBaseBitrate { get => _canArbBaseBitrate; set => SetProperty(ref _canArbBaseBitrate, value, "CanArbBaseBitrate"); } protected int _canArbBaseSJW = EmbeddedSensors.CANFD_1000000_ARB_BASE_SJW_MAX; public int CanArbBaseSJW { get => _canArbBaseSJW; set => SetProperty(ref _canArbBaseSJW, value, "CanArbBaseSJW"); } protected int _canDataBitrate = EmbeddedSensors.DATA_BITRATE_DEFAULT; public int CanDataBitrate { get => _canDataBitrate; set => SetProperty(ref _canDataBitrate, value, "CanDataBitrate"); } protected int _canDataSJW = EmbeddedSensors.DATA_SJW_DEFAULT; public int CanDataSJW { get => _canDataSJW; set => SetProperty(ref _canDataSJW, value, "CanDataSJW"); } protected string _canFileType = EmbeddedSensors.FILETYPE_DEFAULT; public string CanFileType { get => _canFileType; set => SetProperty(ref _canFileType, value, "CanFileType"); } protected UDPStreamProfile _outudpProfile = StreamOutputRecord.DEFAULT_UDP_PROFILE; public UDPStreamProfile StreamOutUDPProfile { get => _outudpProfile; set => SetProperty(ref _outudpProfile, value, "StreamOutUDPProfile"); } protected string _outudpAddress = StreamOutputRecord.DEFAULT_UDP_ADDRESS; public string StreamOutUDPAddress { get => _outudpAddress; set => SetProperty(ref _outudpAddress, value, "StreamOutUDPAddress"); } protected string _inudpAddress = StreamInputRecord.DEFAULT_UDP_ADDRESS; public string StreamInUDPAddress { get => _inudpAddress; set => SetProperty(ref _inudpAddress, value, "StreamInUDPAddress"); } protected ushort _udpTimeChannelId = StreamOutputRecord.DEFAULT_UDP_TIME_CHANNEL_ID; public ushort StreamOutUDPTimeChannelId { get => _udpTimeChannelId; set => SetProperty(ref _udpTimeChannelId, value, "StreamOutUDPTimeChannelId"); } protected ushort _udpDataChannelId = StreamOutputRecord.DEFAULT_UDP_DATA_CHANNEL_ID; public ushort StreamOutUDPDataChannelId { get => _udpDataChannelId; set => SetProperty(ref _udpDataChannelId, value, "StreamOutUDPDataChannelId"); } protected string _udpTmNSConfig = StreamOutputRecord.DEFAULT_UDPTMNS_CONFIG; public string StreamOutUDPTmNSConfig { get => _udpTmNSConfig; set => SetProperty(ref _udpTmNSConfig, value, "StreamOutUDPTmNSConfig"); } /// /// the TMNS sub frame id for output streaming /// public uint TMNS_SubFrameId { get { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); return tmns.TMNS_PCMSubFrameId; } set { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); tmns.TMNS_PCMSubFrameId = value; StreamOutUDPTmNSConfig = tmns.ToCSVString(); OnPropertyChanged("TMNS_SubFrameId"); } } /// /// the TMNS message id for output streaming /// public uint TMNS_MsgId { get { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); return tmns.TMNS_MsgId; } set { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); tmns.TMNS_MsgId = value; StreamOutUDPTmNSConfig = tmns.ToCSVString(); OnPropertyChanged("TMNS_MsgId"); } } /// /// the tMNS PCM minor per major for output streaming /// public uint TMNS_MinorPerMajor { get { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); return tmns.TMNS_PCMMinorPerMajor; } set { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); tmns.TMNS_PCMMinorPerMajor = value; StreamOutUDPTmNSConfig = tmns.ToCSVString(); OnPropertyChanged("TMNS_MinorPerMajor"); } } /// /// TMNS TMATs port for output streaming /// public uint TMNS_TMATSPort { get { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); return tmns.TMNS_TMATSPortNumber; } set { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); tmns.TMNS_TMATSPortNumber = value; StreamOutUDPTmNSConfig = tmns.ToCSVString(); OnPropertyChanged("TMNS_TMATSPort"); } } /// /// IENA source port for output streaming /// public uint IENA_SourcePort { get { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); return tmns.IENAUDP_PortNumber; } set { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); tmns.IENAUDP_PortNumber = value; StreamOutUDPTmNSConfig = tmns.ToCSVString(); OnPropertyChanged("IENA_SourcePort"); } } /// /// IENA key for output streaming /// public ushort IENA_Key { get { return StreamOutUDPDataChannelId; } set { StreamOutUDPDataChannelId = value; OnPropertyChanged("IENA_Key"); } } protected ushort _irigTimeDataPacketIntervalMs = StreamOutputRecord.DEFAULT_IRIG_TIME_DATA_PACKET_INTERVAL_MS; public ushort StreamOutIRIGTimeDataPacketIntervalMs { get => _irigTimeDataPacketIntervalMs; set => SetProperty(ref _irigTimeDataPacketIntervalMs, value, "StreamOutIRIGTimeDataPacketIntervalMs"); } protected ushort _streamOutTMATSIntervalMs = StreamOutputRecord.DEFAULT_TMATS_INTERVAL_MS; /// /// Time in ms between sending out tmats information while streaming /// http://manuscript.dts.local/f/cases/29987/Add-CG-DP-TMATS-interval-UI-support /// public ushort StreamOutTMATSIntervalMs { get => _streamOutTMATSIntervalMs; set => SetProperty(ref _streamOutTMATSIntervalMs, value, "StreamOutTMATSIntervalMs"); } public SensorData(SensorData copy) { if (null == copy) { copy = new SensorData(); } DatabaseId = copy.DatabaseId; _digitalOutputMode = copy._digitalOutputMode; _diUnits = copy._diUnits; _inputMode = copy._inputMode; SquibMeasurementType = copy.SquibMeasurementType; _digitalInputScaleMultiplier = new DigitalInputScaleMultiplier(copy._digitalInputScaleMultiplier); _delayMS = copy._delayMS; _digitalOutputDelayMS = copy._digitalOutputDelayMS; _durationMS = copy._durationMS; _digitalOutputDurationMS = copy._digitalOutputDurationMS; _limitDuration = copy._limitDuration; _defineDelayInTest = copy._defineDelayInTest; _squibToleranceHigh = copy._squibToleranceHigh; _squibToleranceLow = copy._squibToleranceLow; _squibFireMode = copy._squibFireMode; _squibOutputCurrent = copy._squibOutputCurrent; _baudRate = copy._baudRate; _dataBits = copy._dataBits; _stopBits = copy._stopBits; _parity = copy._parity; _flowControl = copy._flowControl; _dataFormat = copy._dataFormat; _inudpAddress = copy._inudpAddress; _outudpProfile = copy._outudpProfile; _outudpAddress = copy._outudpAddress; _udpTimeChannelId = copy._udpTimeChannelId; _udpDataChannelId = copy._udpDataChannelId; _udpTmNSConfig = copy._udpTmNSConfig; _irigTimeDataPacketIntervalMs = copy._irigTimeDataPacketIntervalMs; TagsBlobBytes = copy.TagsBlobBytes; DoNotUse = copy.DoNotUse; Broken = copy.Broken; SensitivityTolerancePercent = copy.SensitivityTolerancePercent; if (null != copy.Calibration) { Calibration = new SensorCalibration((SensorCalibration)copy.Calibration); } try { AssemblyName = copy.AssemblyName; AxisNumber = copy.AxisNumber; BridgeLegMode = copy.BridgeLegMode; BridgeResistance = copy.BridgeResistance; Bridge = copy.Bridge; ByPassFilter = copy.ByPassFilter; CheckCalibrationSignal = copy.CheckCalibrationSignal; CalInterval = copy.CalInterval; Capacity = copy.Capacity; CheckOffset = copy.CheckOffset; Comment = copy.Comment; CouplingMode = copy.CouplingMode; Created = copy.Created; ExternalShuntResistance = copy.ExternalShuntResistance; Filter = copy.Filter; //FB 13120 set filter class FilterClass = copy.FilterClass; 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; LastUpdatedBy = copy.LastUpdatedBy; 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; UserValue1 = copy.UserValue1; UserValue2 = copy.UserValue2; UserValue3 = copy.UserValue3; DiagnosticsMode = copy.DiagnosticsMode; Version = copy.Version; SetSupportedExcitationFromString(copy.GetSerializedSupportedExcitation()); TagsBlobBytes = copy.TagsBlobBytes; DoNotUse = copy.DoNotUse; Broken = copy.Broken; //FB 43046 SensitivityTolerancePercent = copy.SensitivityTolerancePercent; DontAllowDataCollectionIfOverused = copy.DontAllowDataCollectionIfOverused; UsageCount = copy.UsageCount; MaximumUsage = copy.MaximumUsage; } catch (Exception ex) { APILogger.Log(ex); } FilterClassIso = copy.FilterClassIso; MeasureExcitation = copy.MeasureExcitation; MeasureNoise = copy.MeasureNoise; LatestCalibrationId = copy.LatestCalibrationId; FirstUseDate = copy.FirstUseDate; } /// /// returns the calibration due date for sensor given a sensor calibration /// 13065 Sensor "First Use" Date /// public DateTime GetDueDate(ISensorCalibration sc) { if (null == sc) { return DateTime.MinValue; } if (SensorConstants.UseSensorFirstUseDate) { if (sc.CalibrationId != null && sc.CalibrationId == LatestCalibrationId) { if (null == FirstUseDate) { return DateTime.Today.AddDays(CalInterval); } return ((DateTime)FirstUseDate).AddDays(CalInterval); } } return sc.CalibrationDate.AddDays(CalInterval); } public override string ToString() { if (IsTestSpecificDigitalOutput) { return StringResources.Value_NA; } if (IsTestSpecificSquib) { return StringResources.Value_NA; } if (IsTestSpecificDigitalIn) { return StringResources.Value_NA; } return $"{GetSerialNumberWithAxis(StringResources.SensorAxis)} ({Comment})"; } /// /// Returns comment string. Returns serial number with axis if comment is not present. /// /// //FB 5960 New channels "Channel Name" in Non-ISO Group editor should only include Channel Name public string ToDisplayString() { return string.IsNullOrEmpty(Comment) ? GetSerialNumberWithAxis(StringResources.SensorAxis) : Comment; } private void CommonInit(IReadOnlyDictionary calLookup = null) { try { if (SensorConstants.UseSensorFirstUseDate) { if (null != calLookup && calLookup.ContainsKey(SerialNumber)) { LatestCalibrationId = calLookup[SerialNumber].CalibrationId; } else { LatestCalibrationId = GetLatestCalibrationId(DatabaseId); } } InitialOffset = new InitialOffset(); //Set the default if (SensorConstants.IsTestSpecificEmbedded(SerialNumber) || SensorConstants.IsTestSpecificThermoCouple(SerialNumber)) { BridgeResistance = -1; Shunt = ShuntMode.None; } } catch (Exception ex) { APILogger.Log("Failed to process: ", ex); } } public SensorData(IAnalogDbRecord record, IReadOnlyDictionary calLookup = null) : base(record) { CommonInit(calLookup); } //added an option parameter to prevent querying cals one by one by passing in a dictionary //17991 calspan speed ups for opening a test setup public SensorData(IDataReader reader, int actualDbVersion, IReadOnlyDictionary calLookup = null) : base(reader, actualDbVersion) { CommonInit(calLookup); } public static int GetLatestCalibrationId(int sensorId) { using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.Text; cmd.CommandText = $"SELECT TOP (1) [SensorCalibrationId] FROM [{RunTestVariables.DbName}].[dbo].[SensorCalibrations] WHERE [SensorId]=@1 ORDER BY [CalibrationDate] DESC, [ModifyDate] DESC"; cmd.Parameters.Add(new SqlParameter("@1", SqlDbType.Int) { Value = sensorId }); using (var reader = cmd.ExecuteReader()) { if (reader.Read()) { return Convert.ToInt32(reader["SensorCalibrationId"]); } } } catch (Exception ex) { APILogger.Log(ex); } finally { cmd.Connection.Dispose(); } return -1; } } public void ReadXML(System.Xml.XmlElement root) { foreach (var node in root.ChildNodes) { if (node is System.Xml.XmlElement) { ProcessXMLElement(node as System.Xml.XmlElement); } } } private void ProcessXMLElement(System.Xml.XmlElement node) { if (Enum.TryParse(node.Name, out AllSensorDataFields field)) { switch (field) { case AllSensorDataFields.AxisNumber: AxisNumber = Convert.ToInt16(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.BridgeLegMode: BridgeLegMode = (BridgeLeg)Enum.Parse(typeof(BridgeLeg), node.InnerText); break; case AllSensorDataFields.BridgeResistance: BridgeResistance = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.BridgeType: Bridge = (SensorConstants.BridgeType)Enum.Parse(typeof(SensorConstants.BridgeType), node.InnerText); break; case AllSensorDataFields.BypassFilter: ByPassFilter = Convert.ToBoolean(node.InnerText); break; case AllSensorDataFields.CalibrationSignal: CheckCalibrationSignal = Convert.ToBoolean(node.InnerText); break; case AllSensorDataFields.CalInterval: CalInterval = Convert.ToInt32(node.InnerText); break; case AllSensorDataFields.InitialEU: break; case AllSensorDataFields.Capacity: Capacity = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.CheckOffset: CheckOffset = Convert.ToBoolean(node.InnerText); break; case AllSensorDataFields.Comment: Comment = node.InnerText; break; case AllSensorDataFields.CouplingMode: CouplingMode = (SensorConstants.CouplingModes)Enum.Parse(typeof(SensorConstants.CouplingModes), node.InnerText); break; case AllSensorDataFields.Created: Created = DateTime.Parse(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.ExternalShuntResistance: ExternalShuntResistance = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.FilterClass: Filter = new FilterClass(node.InnerText); break; case AllSensorDataFields.Id: EID = node.InnerText; break; case AllSensorDataFields.InternalShuntResistance: InternalShuntResistance = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.Invert: Invert = Convert.ToBoolean(node.InnerText); break; case AllSensorDataFields.IsoCode: ISOCode = BuildIsoCodeFromFilter(node.InnerText, Filter.FClass); break; case AllSensorDataFields.IsoChannelName: ISOChannelName = node.InnerText; break; case AllSensorDataFields.UserCode: UserCode = node.InnerText; break; case AllSensorDataFields.UserChannelName: UserChannelName = node.InnerText; break; case AllSensorDataFields.LastModified: LastModified = DateTime.Parse(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.LocalOnly: _localOnly = Convert.ToBoolean(node.InnerText); break; case AllSensorDataFields.Manufacturer: Manufacturer = node.InnerText; break; case AllSensorDataFields.MeasurementUnit: DisplayUnit = node.InnerText; break; case AllSensorDataFields.Model: Model = node.InnerText; break; case AllSensorDataFields.ModifiedBy: LastUpdatedBy = node.InnerText; break; case AllSensorDataFields.NumberOfAxes: NumberOfAxes = Convert.ToInt16(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.OffsetToleranceHigh: OffsetToleranceHigh = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.OffsetToleranceLow: OffsetToleranceLow = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.RangeAve: RangeMedium = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.RangeHigh: RangeHigh = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.RangeLow: RangeLow = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.SensorCategory: SensorCategory = Convert.ToInt32(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.SerialNumber: SerialNumber = node.InnerText; break; case AllSensorDataFields.Shunt: Shunt = (ShuntMode)Enum.Parse(typeof(ShuntMode), node.InnerText); break; case AllSensorDataFields.Status: Status = (SensorStatus)Enum.Parse(typeof(SensorStatus), node.InnerText); break; case AllSensorDataFields.SupportedExcitation: { var tokens = node.InnerText.Split(new[] { System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None); SupportedExcitation = (from tok in tokens where !string.IsNullOrWhiteSpace(tok) select (ExcitationVoltageOptions.ExcitationVoltageOption)Enum.Parse(typeof(ExcitationVoltageOptions.ExcitationVoltageOption), tok)).ToArray(); } break; case AllSensorDataFields.TimesUsed: TimesUsed = Convert.ToInt32(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.UniPolar: UniPolar = Convert.ToBoolean(node.InnerText); break; case AllSensorDataFields.UserSerialNumber: UserSerialNumber = node.InnerText; break; case AllSensorDataFields.DiagnosticsMode: DiagnosticsMode = Convert.ToBoolean(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.UserValue1: UserValue1 = node.InnerText; break; case AllSensorDataFields.UserValue2: UserValue2 = node.InnerText; break; case AllSensorDataFields.UserValue3: UserValue3 = node.InnerText; break; case AllSensorDataFields.Version: Version = Convert.ToInt32(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.SquibSquibToleranceLow: SquibToleranceLow = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.SquibSquibToleranceHigh: SquibToleranceHigh = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.SquibSquibOutputCurrent: SquibOutputCurrent = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.SquibMeasurementType: { if (Enum.TryParse(node.InnerText, out SquibMeasurementType mType)) { SquibMeasurementType = mType; } } break; case AllSensorDataFields.SquibLimitDuration: LimitSquibFireDuration = Convert.ToBoolean(node.InnerText); break; case AllSensorDataFields.SquibISOCode: ISOCode = node.InnerText; break; case AllSensorDataFields.SquibFireMode: { if (Enum.TryParse(node.InnerText, out SquibFireMode fireMode)) { SquibFireMode = fireMode; } } break; case AllSensorDataFields.SquibDurationMS: SquibFireDurationMS = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.SquibDescription: //SerialNumber break; case AllSensorDataFields.SquibDelayMS: var fireDelayMs = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); // FB14777 Update the logic since -1 is a valid delay now if (DASLib.Service.OutputSquibChannel.DEFAULT_DEFINEINTEST_FIRE_DELAY_FLAG == fireDelayMs) { fireDelayMs = DASLib.Service.OutputSquibChannel.DEFAULT_DEFINEINTEST_FIRE_DELAY_FLAG; } // FB 5827; Saving squibs with invalid delay settings else if (DASLib.Service.OutputSquibChannel.DEFAULT_MIN_FIRE_DELAY_MS > fireDelayMs) { fireDelayMs = DASLib.Service.OutputSquibChannel.DEFAULT_MIN_FIRE_DELAY_MS; } SquibFireDelayMS = fireDelayMs; break; case AllSensorDataFields.SquibBypassVoltageFilter: break; case AllSensorDataFields.SquibBypassCurrentFilter: break; case AllSensorDataFields.SquibArticleId: if (Bridge == SensorConstants.BridgeType.SQUIB) { EID = node.InnerText; } break; case AllSensorDataFields.UserTags: if (Bridge == SensorConstants.BridgeType.DigitalInput && string.IsNullOrEmpty(node.InnerText)) { //When creating Digital Input sensors without a Tag, set to "Digital In" (FB 12941) SetTags(new string[] { StringResources.Digital_In }, DbOperations.GetSQLCommand, DbOperations.TagsGet, DbOperations.TagsGetId, DbOperations.TagsInsert); } else { SetTagsFromCommaSeparatedString(node.InnerText, DbOperations.GetSQLCommand, DbOperations.TagsGet, DbOperations.TagsGetId, DbOperations.TagsInsert); } break; case AllSensorDataFields.DigitalInputScaleMultiplier: ScaleMultiplier.FromDbSerializeString(node.InnerText); break; case AllSensorDataFields.DigitalInputUnits: DIUnits = node.InnerText; break; case AllSensorDataFields.DigitalInputSettingMode: { if (Enum.TryParse(node.InnerText, out DigitalInputModes iMode)) { InputMode = iMode; } } break; case AllSensorDataFields.DigitalInputSettingName: //SerialNumber; break; case AllSensorDataFields.DigitalOutputChannelDescription: //SerialNumber break; case AllSensorDataFields.DigitalOutputDelayMS: DigitalOutputDelayMS = Convert.ToDouble(node.InnerText); break; case AllSensorDataFields.DigitalOutputDurationMS: DigitalOutputDurationMS = Convert.ToDouble(node.InnerText); break; case AllSensorDataFields.DigitalOutputLimitDuration: DigitalOutputLimitDuration = Convert.ToBoolean(node.InnerText); break; case AllSensorDataFields.DigitalOutputOutputMode: { if (Enum.TryParse(node.InnerText, out DigitalOutputModes oMode)) { DigitalOutputMode = oMode; } } break; case AllSensorDataFields.UartBaudRate: UartBaudRate = Convert.ToUInt32(node.InnerText); break; case AllSensorDataFields.UartDataBits: UartDataBits = Convert.ToUInt32(node.InnerText); break; case AllSensorDataFields.UartStopBits: UartStopBits = (StopBits)Enum.Parse(typeof(StopBits), node.InnerText); break; case AllSensorDataFields.UartParity: UartParity = (Parity)Enum.Parse(typeof(Parity), node.InnerText); break; case AllSensorDataFields.UartFlowControl: //FB 30486 Hardcode FlowControl to NONE for UART sensor type break; case AllSensorDataFields.UartDataFormat: UartDataFormat = (UartDataFormat)Enum.Parse(typeof(UartDataFormat), node.InnerText); break; case AllSensorDataFields.StreamInUDPAddress: StreamInUDPAddress = node.InnerText; break; case AllSensorDataFields.StreamOutUDPAddress: StreamOutUDPAddress = node.InnerText; break; case AllSensorDataFields.StreamOutUDPProfile: StreamOutUDPProfile = (UDPStreamProfile)Enum.Parse(typeof(UDPStreamProfile), node.InnerText); break; case AllSensorDataFields.StreamOutUDPDataChannelId: StreamOutUDPDataChannelId = Convert.ToUInt16(node.InnerText); break; case AllSensorDataFields.StreamOutUDPTimeChannelId: StreamOutUDPTimeChannelId = Convert.ToUInt16(node.InnerText); break; case AllSensorDataFields.StreamOutUDPTmNSConfig: StreamOutUDPTmNSConfig = node.InnerText; break; case AllSensorDataFields.StreamOutIRIGTimeDataPacketIntervalMs: StreamOutIRIGTimeDataPacketIntervalMs = Convert.ToUInt16(node.InnerText); break; case AllSensorDataFields.StreamOutTMATSIntervalMs: if (ushort.TryParse(node.InnerText, out ushort uTmp)) { StreamOutTMATSIntervalMs = uTmp; } else { StreamOutTMATSIntervalMs = StreamOutputRecord.DEFAULT_TMATS_INTERVAL_MS; } break; case AllSensorDataFields.Broken: Broken = Convert.ToBoolean(node.InnerText); break; case AllSensorDataFields.DoNotUse: DoNotUse = Convert.ToBoolean(node.InnerText); break; case AllSensorDataFields.DatabaseId: DatabaseId = Convert.ToInt32(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case AllSensorDataFields.FirstUseDate: if (node.InnerText.Equals(INVALID_FIRSTUSEDATE)) { FirstUseDate = null; } else { if (DateTime.TryParse(node.InnerText, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out var dtTemp)) { FirstUseDate = dtTemp; } else { APILogger.Log($"possible invalid first use date data: {node.InnerText}"); FirstUseDate = null; } } break; case AllSensorDataFields.LatestCalibrationId: if (int.TryParse(node.InnerText, out int iTemp)) { LatestCalibrationId = iTemp == INVALID_CALIBRATION_ID ? null : (int?)iTemp; } else { LatestCalibrationId = null; APILogger.Log($"possible invalid latest calibration id: {node.InnerText}"); } break; case AllSensorDataFields.ACCouplingModeEnabled: if (bool.TryParse(node.InnerText, out var b)) { ACCouplingModeEnabled = b; } break; case AllSensorDataFields.AssemblyName: AssemblyName = node.InnerText; break; case AllSensorDataFields.UsageCount: if (int.TryParse(node.InnerText, out int iUsageCount)) { if (iUsageCount == INVALID_USAGE_COUNT) { UsageCount = 0; APILogger.Log($"Invalid usage count: {node.InnerText}"); } else { UsageCount = iUsageCount; } } else { UsageCount = 0; APILogger.Log($"Possible invalid usage count: {node.InnerText}"); } break; case AllSensorDataFields.MaximumUsage: if (int.TryParse(node.InnerText, out int iMaxUsage)) { if (iMaxUsage == INVALID_MAXIMUM_USAGE) { MaximumUsage = 0; APILogger.Log($"Invalid maximum usage: {node.InnerText}"); } else { MaximumUsage = iMaxUsage; } } else { MaximumUsage = 0; APILogger.Log($"Possible invalid maximum usage: {node.InnerText}"); } break; //FB 43267 case AllSensorDataFields.SensitivityTolerancePercent: if (double.TryParse(node.InnerText, NumberStyles.Any, CultureInfo.InvariantCulture, out double dSensitivityTolerancePercent)) { if (dSensitivityTolerancePercent == INVALID_TOLERANCE_PERCENT) { SensitivityTolerancePercent = Constants.SENSITIVITY_CHANGE_TOLERANCE_PERCENT_DEFAULT; APILogger.Log($"Invalid SensitivityTolerancePercent: {node.InnerText}"); } else { SensitivityTolerancePercent = dSensitivityTolerancePercent; } } else { SensitivityTolerancePercent = Constants.SENSITIVITY_CHANGE_TOLERANCE_PERCENT_DEFAULT; APILogger.Log($"Possible invalid SensitivityTolerancePercent: {node.InnerText}"); } break; default: throw new NotSupportedException("SensorData::ProcessXMLElement unsupported field: " + field); } } } private enum AllSensorDataFields { SerialNumber = 1, UserSerialNumber, Model, Manufacturer, Status, MeasurementUnit, OffsetToleranceLow, OffsetToleranceHigh, Id, Capacity, Comment, BridgeType, BridgeLegMode, Shunt, Invert, UserValue1, UserValue2, UserValue3, FilterClass, BridgeResistance, IsoCode, CheckOffset, SupportedExcitation, InitialEU, CalInterval, CalibrationSignal, InternalShuntResistance, ExternalShuntResistance, UniPolar, RangeLow, RangeAve, RangeHigh, Created, TimesUsed, SensorCategory, BypassFilter, CouplingMode, Version, LastModified, ModifiedBy, LocalOnly, AxisNumber, NumberOfAxes, //digitaloutputs DigitalOutputChannelDescription, DigitalOutputDelayMS, DigitalOutputDurationMS, DigitalOutputOutputMode, DigitalOutputLimitDuration, //squibs SquibDescription, SquibBypassCurrentFilter, SquibBypassVoltageFilter, SquibDelayMS, SquibDurationMS, SquibFireMode, SquibISOCode, SquibMeasurementType, SquibSquibOutputCurrent, SquibSquibToleranceLow, SquibSquibToleranceHigh, SquibLimitDuration, SquibArticleId, //digital inputs DigitalInputSettingName, DigitalInputSettingMode, DigitalInputScaleMultiplier, DigitalInputUnits, //uarts UartBaudRate, UartDataBits, UartStopBits, UartParity, UartFlowControl, UartDataFormat, //streamins StreamInUDPAddress, //streamouts StreamOutUDPAddress, StreamOutUDPProfile, StreamOutUDPDataChannelId, StreamOutUDPTimeChannelId, StreamOutUDPTmNSConfig, StreamOutIRIGTimeDataPacketIntervalMs, //tags UserTags, Broken, DoNotUse, DiagnosticsMode, IsoChannelName, UserCode, UserChannelName, DatabaseId, LatestCalibrationId, FirstUseDate, ACCouplingModeEnabled, AssemblyName, UsageCount, MaximumUsage, StreamOutTMATSIntervalMs, SensitivityTolerancePercent } private const string INVALID_FIRSTUSEDATE = "---"; public void WriteXML(ref System.Xml.XmlWriter writer, bool exportFirstUseDate = true) { writer.WriteStartElement("SensorData"); var fields = Enum.GetValues(typeof(AllSensorDataFields)).Cast().ToArray(); foreach (var f in fields) { if (!exportFirstUseDate && (f == AllSensorDataFields.LatestCalibrationId || f == AllSensorDataFields.FirstUseDate)) { continue;//skip, don't export } writer.WriteStartElement(f.ToString()); switch (f) { case AllSensorDataFields.AxisNumber: writer.WriteString(AxisNumber.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.BridgeLegMode: writer.WriteString(BridgeLegMode.ToString()); break; case AllSensorDataFields.BridgeResistance: writer.WriteString(BridgeResistance.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.BridgeType: writer.WriteString(Bridge.ToString()); break; case AllSensorDataFields.BypassFilter: writer.WriteString(ByPassFilter.ToString()); break; case AllSensorDataFields.InitialEU: break; case AllSensorDataFields.CalibrationSignal: writer.WriteString(CheckCalibrationSignal.ToString()); break; case AllSensorDataFields.CalInterval: writer.WriteString(CalInterval.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.Capacity: writer.WriteString(Capacity.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.CheckOffset: writer.WriteString(CheckOffset.ToString()); break; case AllSensorDataFields.Comment: writer.WriteString(Comment); break; case AllSensorDataFields.CouplingMode: writer.WriteString(CouplingMode.ToString()); break; case AllSensorDataFields.Created: writer.WriteString(Created.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.ExternalShuntResistance: writer.WriteString(ExternalShuntResistance.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.FilterClass: writer.WriteString(Filter.ToString()); break; case AllSensorDataFields.Id: writer.WriteString(EID); break; case AllSensorDataFields.InternalShuntResistance: writer.WriteString(InternalShuntResistance.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.Invert: writer.WriteString(Invert.ToString()); break; case AllSensorDataFields.IsoCode: writer.WriteString(ISOCode); break; case AllSensorDataFields.IsoChannelName: writer.WriteString(ISOChannelName); break; case AllSensorDataFields.LastModified: writer.WriteString(LastModified.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.LocalOnly: writer.WriteString(LocalOnly.ToString()); break; case AllSensorDataFields.Manufacturer: writer.WriteString(Manufacturer); break; case AllSensorDataFields.MeasurementUnit: writer.WriteString(DisplayUnit); break; case AllSensorDataFields.Model: writer.WriteString(Model); break; case AllSensorDataFields.ModifiedBy: writer.WriteString(LastUpdatedBy); break; case AllSensorDataFields.NumberOfAxes: writer.WriteString(NumberOfAxes.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.OffsetToleranceHigh: writer.WriteString(OffsetToleranceHigh.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.OffsetToleranceLow: writer.WriteString(OffsetToleranceLow.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.RangeAve: writer.WriteString(RangeMedium.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.RangeHigh: writer.WriteString(RangeHigh.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.RangeLow: writer.WriteString(RangeLow.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.SensorCategory: writer.WriteString(SensorCategory.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.SerialNumber: writer.WriteString(SerialNumber); break; case AllSensorDataFields.Shunt: writer.WriteString(Shunt.ToString()); break; case AllSensorDataFields.Status: writer.WriteString(Status.ToString()); break; case AllSensorDataFields.SupportedExcitation: { writer.WriteString(string.Join(System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator, SupportedExcitation.Select(se => se.ToString()).ToArray())); } break; case AllSensorDataFields.TimesUsed: writer.WriteString(TimesUsed.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.UniPolar: writer.WriteString(UniPolar.ToString()); break; case AllSensorDataFields.UserCode: writer.WriteString(UserCode); break; case AllSensorDataFields.UserChannelName: writer.WriteString(UserChannelName); break; case AllSensorDataFields.UserSerialNumber: writer.WriteString(UserSerialNumber); break; case AllSensorDataFields.DiagnosticsMode: writer.WriteString(DiagnosticsMode.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.UserValue1: writer.WriteString(UserValue1); break; case AllSensorDataFields.UserValue2: writer.WriteString(UserValue2); break; case AllSensorDataFields.UserValue3: writer.WriteString(UserValue3); break; case AllSensorDataFields.Version: writer.WriteString(Version.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.SquibArticleId: writer.WriteString(EID); break;//shares Id property case AllSensorDataFields.SquibBypassCurrentFilter: writer.WriteValue(BypassCurrentFilter); break; case AllSensorDataFields.SquibBypassVoltageFilter: writer.WriteValue(BypassVoltageFilter); break; case AllSensorDataFields.SquibDelayMS: writer.WriteString(SquibFireDelayMS.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.SquibDescription: writer.WriteString(SerialNumber); break; case AllSensorDataFields.SquibDurationMS: writer.WriteString(SquibFireDurationMS.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.SquibFireMode: writer.WriteString(SquibFireMode.ToString()); break; case AllSensorDataFields.SquibISOCode: writer.WriteString(ISOCode); break; case AllSensorDataFields.SquibLimitDuration: writer.WriteValue(LimitDuration); break; case AllSensorDataFields.SquibMeasurementType: writer.WriteString(SquibMeasurementType.ToString()); break; case AllSensorDataFields.SquibSquibOutputCurrent: writer.WriteString(SquibOutputCurrent.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.SquibSquibToleranceHigh: writer.WriteString(SquibToleranceHigh.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.SquibSquibToleranceLow: writer.WriteString(SquibToleranceLow.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.DigitalInputScaleMultiplier: writer.WriteString(ScaleMultiplier.ToSerializeDbString()); break; case AllSensorDataFields.UserTags: writer.WriteString(GetTagsAsCommaSeparatedString(DbOperations.TagsGet)); break; case AllSensorDataFields.DigitalInputSettingMode: writer.WriteString(InputMode.ToString()); break; case AllSensorDataFields.DigitalInputUnits: writer.WriteString(DIUnits.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.DigitalInputSettingName: writer.WriteString(SerialNumber); break; case AllSensorDataFields.DigitalOutputChannelDescription: writer.WriteString(SerialNumber); break; case AllSensorDataFields.DigitalOutputDelayMS: writer.WriteString(DigitalOutputDelayMS.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.DigitalOutputDurationMS: writer.WriteString(DigitalOutputDurationMS.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.DigitalOutputLimitDuration: writer.WriteValue(DigitalOutputLimitDuration); break; case AllSensorDataFields.DigitalOutputOutputMode: writer.WriteString(DigitalOutputMode.ToString()); break; case AllSensorDataFields.UartBaudRate: writer.WriteString(UartBaudRate.ToString()); break; case AllSensorDataFields.UartDataBits: writer.WriteString(UartDataBits.ToString()); break; case AllSensorDataFields.UartStopBits: writer.WriteString(UartStopBits.ToString()); break; case AllSensorDataFields.UartParity: writer.WriteString(UartParity.ToString()); break; case AllSensorDataFields.UartFlowControl: writer.WriteString(UartFlowControl.ToString()); break; case AllSensorDataFields.UartDataFormat: writer.WriteString(UartDataFormat.ToString()); break; case AllSensorDataFields.StreamInUDPAddress: writer.WriteString(StreamInUDPAddress); break; case AllSensorDataFields.StreamOutUDPAddress: writer.WriteString(StreamOutUDPAddress); break; case AllSensorDataFields.StreamOutUDPProfile: writer.WriteString(StreamOutUDPProfile.ToString()); break; case AllSensorDataFields.StreamOutUDPDataChannelId: writer.WriteString(StreamOutUDPDataChannelId.ToString()); break; case AllSensorDataFields.StreamOutUDPTimeChannelId: writer.WriteString(StreamOutUDPTimeChannelId.ToString()); break; case AllSensorDataFields.StreamOutTMATSIntervalMs: writer.WriteString(StreamOutTMATSIntervalMs.ToString()); break; case AllSensorDataFields.StreamOutUDPTmNSConfig: writer.WriteString(StreamOutUDPTmNSConfig); break; case AllSensorDataFields.StreamOutIRIGTimeDataPacketIntervalMs: writer.WriteString(StreamOutIRIGTimeDataPacketIntervalMs.ToString()); break; case AllSensorDataFields.Broken: writer.WriteString(Broken.ToString()); break; case AllSensorDataFields.DoNotUse: writer.WriteString(DoNotUse.ToString()); break; case AllSensorDataFields.DatabaseId: writer.WriteString(DatabaseId.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.LatestCalibrationId: if (null == LatestCalibrationId) { writer.WriteString( INVALID_CALIBRATION_ID.ToString(System.Globalization.CultureInfo.InvariantCulture)); } else { writer.WriteString( ((int)LatestCalibrationId).ToString(System.Globalization.CultureInfo .InvariantCulture)); } break; case AllSensorDataFields.FirstUseDate: if (null == FirstUseDate) { writer.WriteString(INVALID_FIRSTUSEDATE); } else { writer.WriteString(((DateTime)FirstUseDate).ToString("d", System.Globalization.CultureInfo.InvariantCulture)); } break; case AllSensorDataFields.ACCouplingModeEnabled: writer.WriteString(ACCouplingModeEnabled.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case AllSensorDataFields.AssemblyName: writer.WriteString(AssemblyName); break; case AllSensorDataFields.UsageCount: writer.WriteString(UsageCount.ToString(System.Globalization.CultureInfo .InvariantCulture)); break; case AllSensorDataFields.MaximumUsage: writer.WriteString(MaximumUsage.ToString(System.Globalization.CultureInfo .InvariantCulture)); break; //FB 43267 case AllSensorDataFields.SensitivityTolerancePercent: writer.WriteString(SensitivityTolerancePercent.ToString(System.Globalization.CultureInfo .InvariantCulture)); break; default: throw new NotSupportedException("SensorData::WriteXML unsupported field: " + f); } writer.WriteEndElement(); } writer.WriteEndElement(); } private const int INVALID_CALIBRATION_ID = -1; private const int INVALID_USAGE_COUNT = -1; private const int INVALID_MAXIMUM_USAGE = -1; private const double INVALID_TOLERANCE_PERCENT = -1; public enum ExchangeFields { SerialNumber = 1, UserSerialNumber, Model, Manufacturer, Status, MeasurementUnit, Id, Capacity, Comment, IsProportional, BridgeType, Shunt, Invert, RemoveOffset, UserValue1, UserValue2, UserValue3, FilterClass, BridgeResistance, IsoCode, IsoLongName, CheckOffset, ExcitationVoltage, InitialEU, CalibrationDate, CalibrationDueDate, Sensitivity, CalUser, CalZMO, OffsetToleranceLow, OffsetToleranceHigh, OffsetMethod, FiringDelay, FiringDuration, FireMode, CurrentLimit, InputMode, SWOffsetCalculationStartSec, SWOffsetCalculationEndSec, SWOffsetCompensationType } private string _UUID = ""; public string UUID { get => _UUID; set => _UUID = value; } public string GetSerialNumberWithAxis(string format) { if (SensorConstants.IsTestSpecificSquib(SerialNumber)) { return StringResources.Value_NA; } if (SensorConstants.IsTestSpecificDigitalOut(SerialNumber)) { return StringResources.Value_NA; } if (SensorConstants.IsTestSpecificEmbedded(SerialNumber) ||SensorConstants.IsTestSpecificThermoCouple(SerialNumber) ||SensorConstants.IsTestSpecificCAN(SerialNumber)) { return StringResources.Value_NA; } if (1 == NumberOfAxes) { return SerialNumber; } var serial = SerialNumber; var axis = AxisNumber; if (0 == axis) { } else { var key = $"_axis_{axis}"; serial = serial.Replace(key, ""); } return string.Format(format, serial, 1 + axis); } private string _diUnits = "V"; //Initialize to "V" because that's what data exports of DI channels have defaulted to in the past public string DIUnits { get => _diUnits; set { if (value == null) { value = ""; } SetProperty(ref _diUnits, value, "DIUnits"); } } public string EID { get => EId; set { if (value == null) { value = ""; } EId = value; OnPropertyChanged("EID"); } } private const double INVALID_SHUNT = 0D; public bool PerformShuntEmulation { get { if (Shunt == ShuntMode.Emulation) { if (BridgeResistance == INVALID_SHUNT) { return false; } switch (Bridge) { case SensorConstants.BridgeType.FullBridge: case SensorConstants.BridgeType.HalfBridge: case SensorConstants.BridgeType.QuarterBridge: return true; case SensorConstants.BridgeType.HalfBridge_SigPlus: default: return false; } } return false; } } public bool CalSignal { get => base.CalibrationSignal; set { base.CalibrationSignal = value; OnPropertyChanged("CalSignal"); } } public string GetSerializedSupportedExcitation() { return string.Join(System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator, SupportedExcitation.Select(sp => sp.ToString()).ToArray()); } public bool ByPassFilter { get => BypassFilter; set { BypassFilter = value; OnPropertyChanged("ByPassFilter"); } } public bool CheckCalibrationSignal { get => base.CalibrationSignal; set { base.CalibrationSignal = value; OnPropertyChanged("CheckCalibrationSignal"); } } public string TestObject { get => new IsoCode(ISOCode).TestObject; set { var ic = new IsoCode(ISOCode) { TestObject = value }; ISOCode = ic.StringRepresentation; OnPropertyChanged("TestObject"); } } public string OriginalPosition { get; set; } public string Position { get { var ic = new IsoCode(ISOCode); return ic.Position; } set { var ic = new IsoCode(ISOCode); ic.Position = value; ISOCode = ic.StringRepresentation; OnPropertyChanged("Position"); } } public string MainLocation { get { var ic = new IsoCode(ISOCode); return ic.MainLocation; } set { var ic = new IsoCode(ISOCode); ic.MainLocation = value; ISOCode = ic.StringRepresentation; OnPropertyChanged("MainLocation"); } } public string FineLocation1 { get { var ic = new IsoCode(ISOCode); return ic.FineLocation1; } set { var ic = new IsoCode(ISOCode); ic.FineLocation1 = value; ISOCode = ic.StringRepresentation; OnPropertyChanged("FineLocation1"); } } public string FineLocation2 { get { var ic = new IsoCode(ISOCode); return ic.FineLocation2; } set { var ic = new IsoCode(ISOCode); ic.FineLocation2 = value; ISOCode = ic.StringRepresentation; OnPropertyChanged("FineLocation2"); } } public string FineLocation3 { get { var ic = new IsoCode(ISOCode); return ic.FineLocation3; } set { var ic = new IsoCode(ISOCode); ic.FineLocation3 = value; ISOCode = ic.StringRepresentation; OnPropertyChanged("FineLocation3"); } } public SensorData() { //13034 Partial list of available ISO codes with Default Filter when adding new sensors //ISOCode = BuildIsoCodeFromFilter(null, Filter.FClass); } public int CompareTo(SensorData other) { return string.Compare(SerialNumber, other.SerialNumber, StringComparison.Ordinal); } public static bool IsValid(XElement elem) { try { var dummy = new SensorData(elem); return true; } catch (Exception ex) { APILogger.Log(ex); return false; } } internal const string TOP_LEVEL_TAG = "SensorData"; internal const string SENSOR_TAG = "Sensor"; public enum SensorXMLFields { Version, SerialNumber, UserSerialNumber, Model, Status, MeasurementUnit, Sensitivity, ID, Capacity, Comment, IsPropotional, Bridge, CalSignal, Shunt, InternalShuntResistance, ExternalShuntResistance, BridgeResistance, BridgeLegMode, OffsetTolerance, Invert, RemoveOffset, UserValue1, UserValue2, UserValue3, Range, Excitation, Filter, Zero, InitialEU, Created, TimesUsed, Zmo, ISOCode, ISOChannelName, UserCode, UserChannelName, CheckOffset, SIFFile, IRTraccExponent, SensorCategory, FilterOption, OriginalShuntMode, OriginalZeroMethod, Manufacturer, CouplingMode, IgnoreRange, UniPolar, NonLinear, PolyStyle, Dimension, IRTraccFormat }; public const string DATA_TABLE_FILENAME = "Data.SensorDB.xml"; private string _tableName; internal void Init(XElement elem) { Calibration = new SensorCalibration(); _tableName = DATA_TABLE_FILENAME; var ver = 0; try { ver = (int)elem.Element(SensorXMLFields.Version.ToString()); } catch (ArgumentNullException) { throw new Exception("SensorData: Can't find version tag in DB file"); } Version = 1; SensorDBBase.GetValue(elem, SensorXMLFields.SerialNumber.ToString(), out _serialNumber, null, _tableName); SensorDBBase.GetValueSafe(elem, SensorXMLFields.UserSerialNumber.ToString(), out _userSerialNumber, SerialNumber, _tableName); SensorDBBase.GetValueSafe(elem, SensorXMLFields.Model.ToString(), out _model, SerialNumber, _tableName); SensorDBBase.GetValue(elem, SensorXMLFields.Status.ToString(), out _status, SerialNumber, _tableName); SensorDBBase.GetValueSafe(elem, SensorXMLFields.MeasurementUnit.ToString(), out _displayUnit, SerialNumber, _tableName); // This call insures that the display unit will be added to the list. MeasurementUnitList.GetMeasurementUnit(_displayUnit); // FB16398: set units on all records, not just first Array.ForEach(Calibration.Records.Records, record => record.EngineeringUnits = _displayUnit); // FB6247 Sensor table not displaying Units correctly. SensorDBBase.GetValueSafe(elem, SensorXMLFields.ID.ToString(), out var s, SerialNumber, _tableName); //http://manuscript.dts.local/f/cases/31832/SLICEWare-to-DataPRO-Sensor-Database-EIDs-not-imported EID = s; SensorDBBase.GetValue(elem, SensorXMLFields.Capacity.ToString(), out _capacity, SerialNumber, _tableName); SensorDBBase.GetValueSafe(elem, SensorXMLFields.Comment.ToString(), out string comment, SerialNumber, _tableName); Comment = comment; SensorDBBase.GetValue(elem, SensorXMLFields.IsPropotional.ToString(), out bool isProportional, SerialNumber, _tableName); Calibration.IsProportional = isProportional; SensorDBBase.GetValue(elem, SensorXMLFields.Bridge.ToString(), out _bridge, SerialNumber, _tableName); SensorDBBase.GetValue(elem, SensorXMLFields.Shunt.ToString(), out ShuntMode shunt, SerialNumber, _tableName); Shunt = shunt; try { var newEl = SensorDBBase.GetTagValueSafe(elem, SensorXMLFields.CalSignal.ToString(), SerialNumber, _tableName); if (null != newEl) { CalSignal = (bool)newEl; } else { CalSignal = false; } } catch (Exception ex) { APILogger.Log("Could not get ", SensorXMLFields.CalSignal.ToString(), " for ", SerialNumber, ex); CalSignal = false; } SensorDBBase.GetValue(elem, SensorXMLFields.InternalShuntResistance.ToString(), out _internalShuntResistance, SerialNumber, _tableName); SensorDBBase.GetValue(elem, SensorXMLFields.ExternalShuntResistance.ToString(), out _externalShuntResistance, SerialNumber, _tableName); SensorDBBase.GetValue(elem, SensorXMLFields.BridgeResistance.ToString(), out _bridgeResistance, SerialNumber, _tableName); if (double.IsNaN(BridgeResistance)) { BridgeResistance = 0D; } BridgeLeg leg; SensorDBBase.GetValue(elem, SensorXMLFields.BridgeLegMode.ToString(), out leg, SerialNumber, _tableName); BridgeLegMode = leg; var lowHi = new LowHigh(elem, SensorXMLFields.OffsetTolerance.ToString(), DATA_TABLE_FILENAME, SerialNumber); _offsetToleranceLow = lowHi.Low; _offsetToleranceHigh = lowHi.High; var range = new SensorRange(elem, SensorXMLFields.Range.ToString(), DATA_TABLE_FILENAME, SerialNumber); RangeMedium = range.Medium; RangeHigh = range.High; RangeLow = range.Low; Filter = new FilterClass(elem, SensorXMLFields.Filter.ToString(), DATA_TABLE_FILENAME, SerialNumber); Calibration.ZeroMethods = new ZeroMethods(new ZeroMethod(elem, SensorXMLFields.Zero.ToString(), DATA_TABLE_FILENAME, SerialNumber)); SensorDBBase.GetValue(elem, SensorXMLFields.Invert.ToString(), out string temp, SerialNumber, _tableName); Invert = Convert.ToBoolean(temp); SensorDBBase.GetValue(elem, SensorXMLFields.RemoveOffset.ToString(), out bool removeOffset, SerialNumber, _tableName); Calibration.RemoveOffset = removeOffset; SensorDBBase.GetValue(elem, SensorXMLFields.UserValue1.ToString(), out _userValue1, SerialNumber, _tableName); SensorDBBase.GetValue(elem, SensorXMLFields.UserValue2.ToString(), out _userValue2, SerialNumber, _tableName); SensorDBBase.GetValue(elem, SensorXMLFields.UserValue3.ToString(), out _userValue3, SerialNumber, _tableName); SensorDBBase.GetValue(elem, SensorXMLFields.Excitation.ToString(), out ExcitationVoltageOptions.ExcitationVoltageOption option, SerialNumber, _tableName); if (0 == option) { option = ExcitationVoltageOptions.ExcitationVoltageOption.Volt5; } SupportedExcitation = new[] { option }; Calibration.Records.Records[0].Excitation = option; SensorDBBase.GetValue(elem, SensorXMLFields.InitialEU.ToString(), out double initialeu, SerialNumber, _tableName); Calibration.InitialOffsets.Offsets[0].Form = InitialOffsetTypes.EU; Calibration.InitialOffsets.Offsets[0].EU = initialeu; var bNonLinear = false; //FB 6343 Old SLICEWare XML will not import. try { var newEl = SensorDBBase.GetTagValueSafe(elem, SensorXMLFields.NonLinear.ToString(), SerialNumber, _tableName); if (null != newEl) { bNonLinear = (bool)newEl; } else { bNonLinear = false; } } catch (Exception ex) { bNonLinear = false; APILogger.Log(ex); } Calibration.NonLinear = bNonLinear; SensorDBBase.GetValue(elem, SensorXMLFields.Created.ToString(), out _created, SerialNumber, _tableName); SensorDBBase.GetValue(elem, SensorXMLFields.TimesUsed.ToString(), out int iTemp, SerialNumber, _tableName); _timesUsed = iTemp; //GetValue(elem, SensorXMLFields.Zmo.ToString(), out _Zmo, SerialNumber); SensorDBBase.GetValue(elem, SensorXMLFields.ISOCode.ToString(), out temp, SerialNumber, _tableName); ISOCode = temp; SensorDBBase.GetValueSafe(elem, SensorXMLFields.ISOChannelName.ToString(), out temp, SerialNumber, _tableName); ISOChannelName = temp ?? string.Empty; SensorDBBase.GetValueSafe(elem, SensorXMLFields.UserCode.ToString(), out temp, SerialNumber, _tableName); UserCode = temp ?? string.Empty; SensorDBBase.GetValueSafe(elem, SensorXMLFields.UserChannelName.ToString(), out temp, SerialNumber, _tableName); UserChannelName = temp ?? string.Empty; SensorDBBase.GetValue(elem, SensorXMLFields.CheckOffset.ToString(), out temp, SerialNumber, _tableName); CheckOffset = Convert.ToBoolean(temp); try { var newEl = SensorDBBase.GetTagValueSafe(elem, SensorXMLFields.SensorCategory.ToString(), SerialNumber, _tableName); if (null != newEl) { _sensorCategory = (int)newEl; } else { _sensorCategory = 0; } } catch (Exception) { _sensorCategory = 0; } try { var newEl = SensorDBBase.GetTagValueSafe(elem, SensorXMLFields.FilterOption.ToString(), SerialNumber, _tableName); if (null != newEl) { _bypassFilter = (bool)newEl; } else { _bypassFilter = false; } } catch (Exception) { _bypassFilter = false; } try { var newEl = SensorDBBase.GetTagValueSafe(elem, SensorXMLFields.CouplingMode.ToString(), SerialNumber, _tableName); if (null != newEl) { _couplingMode = (SensorConstants.CouplingModes)Enum.Parse(typeof(SensorConstants.CouplingModes), (string)newEl); } else { _couplingMode = SensorConstants.CouplingModes.DC; } } catch (Exception ex) { APILogger.Log("Could not get ", SensorXMLFields.CouplingMode.ToString(), " for ", SerialNumber, ex); _couplingMode = SensorConstants.CouplingModes.DC; } try { var newEl = SensorDBBase.GetTagValueSafe(elem, SensorXMLFields.Manufacturer.ToString(), SerialNumber, _tableName); if (null != newEl) { _manufacturer = (string)newEl; } } catch (Exception) { _manufacturer = "unknown"; } try { XElement tmp = null; try { tmp = elem.Element(SensorXMLFields.IgnoreRange.ToString()); } catch (Exception ex) { APILogger.Log(ex); } if (null != tmp) { _IgnoreRange = (bool)tmp; } } catch (Exception ex) { APILogger.Log(ex); } try { var tmp = elem.Element(SensorXMLFields.UniPolar.ToString()); if (null != tmp) { _uniPolar = (bool)tmp; } } catch (Exception ex) { APILogger.Log(ex); } try { var tmp = elem.Element(SensorXMLFields.IRTraccFormat.ToString()); if (null == tmp) return; if (Enum.TryParse((string)tmp, out NonLinearStyles style)) { Calibration.Records.Records[0].Poly.NonLinearStyle = style; } } catch (Exception ex) { APILogger.Log(ex); } } public SensorData(XElement elem) { Init(elem); } public bool SimpleEquals(SensorData rhs) { if (null == rhs) { return false; } var fields = Enum.GetValues(typeof(AllSensorDataFields)).Cast().ToArray(); if (Bridge == rhs.Bridge) { switch (Bridge) { case SensorConstants.BridgeType.DigitalInput: return SerialNumber == rhs.SerialNumber && InputMode == rhs.InputMode && EID == rhs.EID && _digitalInputScaleMultiplier.Equals(rhs._digitalInputScaleMultiplier); case SensorConstants.BridgeType.SQUIB: return SerialNumber == rhs.SerialNumber && LimitSquibFireDuration == rhs.LimitSquibFireDuration && SquibFireDelayMS == rhs.SquibFireDelayMS && SquibFireMode == rhs.SquibFireMode && EID == rhs.EID && SquibMeasurementType == rhs.SquibMeasurementType && SquibOutputCurrent == rhs.SquibOutputCurrent && SquibToleranceHigh == rhs.SquibToleranceHigh && SquibToleranceLow == rhs.SquibToleranceLow; case SensorConstants.BridgeType.TOMDigital: return SerialNumber == rhs.SerialNumber && DigitalOutputDelayMS == rhs.DigitalOutputDelayMS && DigitalOutputDurationMS == rhs.DigitalOutputDurationMS && DigitalOutputLimitDuration == rhs.DigitalOutputLimitDuration && DigitalOutputMode == rhs.DigitalOutputMode; case SensorConstants.BridgeType.FullBridge: case SensorConstants.BridgeType.HalfBridge: case SensorConstants.BridgeType.HalfBridge_SigPlus: case SensorConstants.BridgeType.QuarterBridge: case SensorConstants.BridgeType.IEPE: default: foreach (var field in fields) { switch (field) { case AllSensorDataFields.AxisNumber: if (AxisNumber != rhs.AxisNumber) { return false; } break; case AllSensorDataFields.BridgeResistance: if (BridgeResistance != rhs.BridgeResistance) { return false; } break; case AllSensorDataFields.CalInterval: if (CalInterval != rhs.CalInterval) { return false; } break; case AllSensorDataFields.Capacity: if (Capacity != rhs.Capacity) { return false; } break; case AllSensorDataFields.CheckOffset: if (CheckOffset != rhs.CheckOffset) { return false; } break; case AllSensorDataFields.Comment: if (Comment != rhs.Comment) { return false; } break; case AllSensorDataFields.MeasurementUnit: if (DisplayUnit != rhs.DisplayUnit) { return false; } break; case AllSensorDataFields.Id: if (EID != rhs.EID) { return false; } break; case AllSensorDataFields.Invert: if (Invert != rhs.Invert) { return false; } break; case AllSensorDataFields.IsoCode: if (ISOCode != rhs.ISOCode) { return false; } break; case AllSensorDataFields.NumberOfAxes: if (NumberOfAxes != rhs.NumberOfAxes) { return false; } break; case AllSensorDataFields.SerialNumber: if (SerialNumber != rhs.SerialNumber) { return false; } break; case AllSensorDataFields.Shunt: if (Shunt != rhs.Shunt) { return false; } break; case AllSensorDataFields.Status: if (Status != rhs.Status) { return false; } break; case AllSensorDataFields.OffsetToleranceHigh: if (OffsetToleranceHigh != rhs.OffsetToleranceHigh) { return false; } break; case AllSensorDataFields.OffsetToleranceLow: if (OffsetToleranceLow != rhs.OffsetToleranceLow) { return false; } break; case AllSensorDataFields.SupportedExcitation: if (SupportedExcitation.Length == rhs.SupportedExcitation.Length) { foreach (var se in SupportedExcitation) { if (!rhs.SupportedExcitation.Contains(se)) { return false; } } } else { return false; } break; } } return true; } } return false; } public bool IncompatibleSensorAssignment(string sensorDimension, string channelDimension) { return sensorDimension != channelDimension && sensorDimension != "00" && sensorDimension != "SE" && !sensorDimension.Contains("?") && channelDimension != "00" && channelDimension != "SE" && !channelDimension.Contains("?"); } public double InputActiveValue { get => ScaleMultiplier.ActiveValue; set => ScaleMultiplier.ActiveValue = value; } public double InputDefaultValue { get => ScaleMultiplier.DefaultValue; set => ScaleMultiplier.DefaultValue = value; } } }