using System; using System.Collections.Generic; using System.Linq; using DTS.Common.DAS.Concepts; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using DTS.Common.Enums; using DTS.Common.Storage; using DTS.Common.Utilities.Logging; using DTS.Common.Classes.Sensors; using DTS.Common.Enums.Sensors; using DTS.Common.Interface.Sensors; using DTS.Common.Interface.Sensors.SoftwareFilters; using DTS.Common.Classes; // ReSharper disable InconsistentNaming namespace DTS.SensorDB { public abstract class SensorBase : AnalogDbRecord, ISensorBase { public int CompareTo(SensorModel rhs) { if (null == Model) { Model = ""; } if (null == rhs.Model) { rhs.Model = ""; } return Model.CompareTo(rhs.Model); } public virtual bool IsDigitalInput() { return Bridge == SensorConstants.BridgeType.DigitalInput; } public virtual bool IsDigitalOutput() { return Bridge == SensorConstants.BridgeType.TOMDigital; } public virtual bool IsSquib() { return Bridge == SensorConstants.BridgeType.SQUIB; } public virtual bool IsUart() { return Bridge == SensorConstants.BridgeType.UART; } public virtual bool IsStreamOutput() { return Bridge == SensorConstants.BridgeType.StreamOut; } public virtual bool IsStreamInput() { return Bridge == SensorConstants.BridgeType.StreamIn; } public virtual bool IsThermocoupler() { return Bridge == SensorConstants.BridgeType.Thermocoupler; } public virtual bool IsCan() { return Bridge == SensorConstants.BridgeType.CAN; } public SensorBase() : base() { } public SensorBase(IDataReader reader, int actualDbVersion) : base(reader, actualDbVersion) { } public SensorBase(IAnalogDbRecord record) : base(record) { } public virtual void CopyValues(ISensorBase iCopy, bool copyCalibration = true) { var copy = (SensorBase)iCopy; AxisNumber = copy.AxisNumber; Bridge = copy.Bridge; BridgeResistance = copy.BridgeResistance; if (copyCalibration) { Calibration.CopyValues(copy.Calibration); } CalInterval = copy.CalInterval; Capacity = copy.Capacity; CheckOffset = copy.CheckOffset; CouplingMode = copy.CouplingMode; Direction = copy.Direction; Filter = new FilterClass(copy.Filter.FClass, copy.Filter.Frequency); IgnoreRange = copy.IgnoreRange; Invert = copy.Invert; ISOCode = copy.ISOCode; ISOChannelName = copy.ISOChannelName; UserCode = copy.UserCode; UserChannelName = copy.UserChannelName; LastModified = copy.LastModified; LastUpdatedBy = copy.LastUpdatedBy; _localOnly = copy.LocalOnly; Manufacturer = copy.Manufacturer; DisplayUnit = copy.DisplayUnit; Model = copy.Model; NumberOfAxes = copy.NumberOfAxes; OffsetToleranceHigh = copy.OffsetToleranceHigh; OffsetToleranceLow = copy.OffsetToleranceLow; PhysicalDimension = copy.PhysicalDimension; Polarity = copy.Polarity; RangeHigh = copy.RangeHigh; RangeLow = copy.RangeLow; RangeMedium = copy.RangeMedium; Shunt = copy.Shunt; _supportedExcitation = copy.SupportedExcitation; UniPolar = copy.UniPolar; UserPartNumber = copy.UserPartNumber; Broken = copy.Broken; DoNotUse = copy.DoNotUse; //43046 SensitivityTolerancePercent = copy.SensitivityTolerancePercent; MeasureExcitation = copy.MeasureExcitation; MeasureNoise = copy.MeasureNoise; } protected bool _measureNoise = true; public bool MeasureNoise { get => _measureNoise; set => SetProperty(ref _measureNoise, value, "MeasureNoise"); } protected bool _measureExcitation = true; public bool MeasureExcitation { get => _measureExcitation; set => SetProperty(ref _measureExcitation, value, "MeasureExcitation"); } protected string _UserPartNumber = ""; public string UserPartNumber { get => _UserPartNumber; set => SetProperty(ref _UserPartNumber, value, "UserPartNumber"); } public double FullScaleCapacity => 2400D; public virtual void SetDisplayUnitNoNotify(string unit) { _displayUnit = unit; } public virtual void SetExcitationsNoNotify(ExcitationVoltageOptions.ExcitationVoltageOption[] excitations) { _supportedExcitation = excitations; } protected SensorCalibration _calibration = new SensorCalibration(); /// /// sensor models shouldn't have a cal date, but this is the min cal date we can use and not cause problems unintentionally somewhere else /// public virtual ISensorCalibration Calibration { get => _calibration; set => SetProperty(ref _calibration, (SensorCalibration)value, "Calibration"); } public new ShuntMode Shunt { get => (ShuntMode)base.Shunt; set => base.Shunt = (short)value; } // http://manuscript.dts.local/f/cases/18743/Unable-to-enter-bridge-resistance-on-a-half-bridge-sensor private const double HALF_BRIDGE_RESISTANCE = 3000.0D; public new double BridgeResistance { get { double rv; switch (Bridge) { // http://manuscript.dts.local/f/cases/18743/Unable-to-enter-bridge-resistance-on-a-half-bridge-sensor case SensorConstants.BridgeType.HalfBridge: case SensorConstants.BridgeType.HalfBridge_SigPlus: rv = HALF_BRIDGE_RESISTANCE; break; default: rv = base.BridgeResistance; break; } return rv; } set => base.BridgeResistance = value; } protected IFilterClass _filterClass; // FB 13120 Define filter class public IFilterClass FilterClass { get { return _filterClass == null ? Filter : _filterClass; } set => SetProperty(ref _filterClass, value, "FilterClass"); } public FilterClassType FilterType { get => Filter.FClass; } public void SetFilterAndFilterClassISO(IFilterClass f, bool useZeroForUnfiltered, bool digitalIn) { Filter = f; var ic = new IsoCode(ISOCode); if (digitalIn) { ic.FilterClass = "0"; } else { switch (f.FClass) { case FilterClassType.CFC1000: ic.FilterClass = "A"; break; case FilterClassType.CFC180: ic.FilterClass = "C"; break; case FilterClassType.CFC60: ic.FilterClass = "D"; break; case FilterClassType.CFC600: ic.FilterClass = "B"; break; case FilterClassType.AdHoc: ic.FilterClass = "S"; break; case FilterClassType.Unfiltered: ic.FilterClass = useZeroForUnfiltered ? "0" : "P"; break; default: ic.FilterClass = "P"; break; } } ISOCode = ic.StringRepresentation; } public double Frequency { get => Filter.Frequency; set { Filter.Frequency = value; OnPropertyChanged("Frequency"); } } // FB 5843 - Surface the CFC Setting Option for a sensor in the SensorDB UI public string FilterClassIso { get { switch (Filter.FClass) { case FilterClassType.Unfiltered: return "0"; case FilterClassType.CFC1000: return "A"; case FilterClassType.CFC600: return "B"; case FilterClassType.CFC180: return "C"; case FilterClassType.CFC60: return "D"; case FilterClassType.None: return "P"; case FilterClassType.AdHoc: return "S"; default: return "?"; } } set { //var ic = new IsoCode(ISOCode) { FilterClass = value }; //ISOCode = ic.StringRepresentation; switch (value) { case "0": Filter = new FilterClass(FilterClassType.Unfiltered); break; case "A": Filter = new FilterClass(FilterClassType.CFC1000); break; case "B": Filter = new FilterClass(FilterClassType.CFC600); break; case "C": Filter = new FilterClass(FilterClassType.CFC180); break; case "D": Filter = new FilterClass(FilterClassType.CFC60); break; case "P": Filter = new FilterClass(FilterClassType.None); break; case "S": //FB 13120 use frecuency for adhoc Filter = new FilterClass(FilterClassType.AdHoc, Frequency); break; default: Filter = new FilterClass(FilterClassType.CFC1000); break; } OnPropertyChanged("FilterClassIso"); } } protected bool _IgnoreRange = false; public bool IgnoreRange { get => _IgnoreRange; set => SetProperty(ref _IgnoreRange, value, "IgnoreRange"); } public string LastUpdatedBy { get => ModifiedBy; set { ModifiedBy = value; OnPropertyChanged("LastUpdatedBy"); } } public new bool LocalOnly { get => base.LocalOnly; } public void SetLocalOnly(bool bLocalOnly) { base.LocalOnly = bLocalOnly; } public string Polarity { get => Invert ? "-" : "+"; set { Invert = value == "-"; OnPropertyChanged("Polarity"); } } protected string _physicalDimension = string.Empty; public string PhysicalDimension { get => _physicalDimension; set => _physicalDimension = value; } protected string _direction = string.Empty; public string Direction { get => _direction; set => _direction = value; } private bool _outOfDate = false; public bool OutOfDate { get => _outOfDate; set => SetProperty(ref _outOfDate, value, "OutOfDate"); } private bool _inWarningPeriod = false; public bool InWarningPeriod { get => _inWarningPeriod; set => SetProperty(ref _inWarningPeriod, value, "InWarningPeriod"); } //FB 43246 private bool _inspectBeforeUse = false; public bool InspectBeforeUse { get => _inspectBeforeUse; set => SetProperty(ref _inspectBeforeUse, value, "InspectBeforeUse"); } public enum SensorBaseFields { CheckOffset, Invert, Model, Manufacturer, UserPartNumber, Capacity, CouplingMode, OffsetToleranceLow, OffsetToleranceHigh, MeasurementUnit, RangeLow, RangeMedium, RangeHigh, SupportedExcitation, Calibration, Bridge, Shunt, BridgeResistance, Filter, UniPolar, IgnoreRange, LastUpdatedBy, Version, LocalOnly, AxisNumber, NumberOfAxes, CalInterval, Polarity, LastModified, ISOCode, PhysicalDimension, Direction, Broken, DoNotUse } /// /// modifies an isocode's Filter Class based on a sensor's Filter if the isocode's Filter Class is "?" /// FB 8037 - sensor's default filter not displayed after SIF import /// /// the starting ISO code which may or may not already have a filter /// the sensor's filter class to be used if the channel doesn't already have one /// a string representation of the ISO code with a non-'?' Filter Class if the sensor's Filter is one of the ISO values public string BuildIsoCodeFromFilter(string importingIsoCode, FilterClassType sensorFilterClass) { var isoCodeWithFilter = new IsoCode(importingIsoCode); if (isoCodeWithFilter.FilterClass == "?") { isoCodeWithFilter.FilterClass = FClassToIsoFilterCode(sensorFilterClass); }; return isoCodeWithFilter.StringRepresentation; } /// /// returns the ISO Code for a Filter Class /// private static string FClassToIsoFilterCode(FilterClassType fClass) { switch (fClass) { case FilterClassType.Unfiltered: return "0"; case FilterClassType.CFC1000: return "A"; case FilterClassType.CFC600: return "B"; case FilterClassType.CFC180: return "C"; case FilterClassType.CFC60: return "D"; case FilterClassType.None: return "P"; case FilterClassType.AdHoc: return "S"; default: throw new ArgumentOutOfRangeException("fClass", fClass, null); } } } public class SensorModel : SensorBase, IComparable { public override ISensorCalibration Calibration { get { if (null == base.Calibration) { return null; } base.Calibration.CalibrationDate = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue; return base.Calibration; } set => base.Calibration = value; } public enum IRTraccFormats { Manual, DiagnosticZeroMMmV, ZeroMMmV, AverageOverTime, Polynomial } public enum PolynomialStyles { IRTRacc, POT, Thermocoupler, Equation } public SensorModel() { } public SensorModel(SensorModel copy) { if (null == copy) { copy = new SensorModel(); } Polarity = copy.Polarity; AxisNumber = copy.AxisNumber; Bridge = copy.Bridge; BridgeResistance = copy.BridgeResistance; CalInterval = copy.CalInterval; Capacity = copy.Capacity; CouplingMode = copy.CouplingMode; Filter = new FilterClass(copy.Filter.ToString()); IgnoreRange = copy.IgnoreRange; /*case DbOperations.SensorDB.SensorModelFields.InitialEU: InitialEU = copy.InitialEU; break;*/ Invert = copy.Invert; CheckOffset = copy.CheckOffset; LastModified = copy.LastModified; SetLocalOnly(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; Shunt = copy.Shunt; UniPolar = copy.UniPolar; UserPartNumber = copy.UserPartNumber; Version = copy.Version; Calibration = new SensorCalibration(copy.Calibration); ISOCode = copy.ISOCode; ISOChannelName = copy.ISOChannelName; UserCode = copy.UserCode; UserChannelName = copy.UserChannelName; _supportedExcitation = copy.SupportedExcitation; } 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) { double initialEU = 0; if (Enum.TryParse(node.Name, out DbOperations.SensorDB.SensorModelFields field)) { switch (field) { case DbOperations.SensorDB.SensorModelFields.AxisNumber: AxisNumber = Convert.ToInt16(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.Bridge: Bridge = (SensorConstants.BridgeType)Enum.Parse(typeof(SensorConstants.BridgeType), node.InnerText); break; case DbOperations.SensorDB.SensorModelFields.BridgeResistance: BridgeResistance = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.CalibrationRecord: Calibration = new SensorCalibration(node.InnerText); break; case DbOperations.SensorDB.SensorModelFields.CalInterval: CalInterval = Convert.ToInt32(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.Capacity: Capacity = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.CheckOffset: CheckOffset = Convert.ToBoolean(node.InnerText); break; case DbOperations.SensorDB.SensorModelFields.CouplingMode: CouplingMode = (SensorConstants.CouplingModes)Enum.Parse(typeof(SensorConstants.CouplingModes), node.InnerText); break; case DbOperations.SensorDB.SensorModelFields.FilterClass: Filter = new FilterClass(node.InnerText); break; case DbOperations.SensorDB.SensorModelFields.IgnoreRange: IgnoreRange = Convert.ToBoolean(node.InnerText); break; case DbOperations.SensorDB.SensorModelFields.Invert: Invert = Convert.ToBoolean(node.InnerText); break; case DbOperations.SensorDB.SensorModelFields.ISOCode: ISOCode = BuildIsoCodeFromFilter(node.InnerText, Filter.FClass); break; case DbOperations.SensorDB.SensorModelFields.ISOChannelName: ISOChannelName = node.InnerText; break; case DbOperations.SensorDB.SensorModelFields.UserCode: UserCode = node.InnerText; break; case DbOperations.SensorDB.SensorModelFields.UserChannelName: UserChannelName = node.InnerText; break; case DbOperations.SensorDB.SensorModelFields.LastModified: LastModified = Convert.ToDateTime(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.LocalOnly: _localOnly = Convert.ToBoolean(node.InnerText); break; case DbOperations.SensorDB.SensorModelFields.Manufacturer: Manufacturer = node.InnerText; break; case DbOperations.SensorDB.SensorModelFields.MeasurementUnit: DisplayUnit = node.InnerText; break; case DbOperations.SensorDB.SensorModelFields.Model: Model = node.InnerText; break; case DbOperations.SensorDB.SensorModelFields.ModifiedBy: LastUpdatedBy = node.InnerText; break; case DbOperations.SensorDB.SensorModelFields.NumberOfAxes: NumberOfAxes = Convert.ToInt16(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.OffsetToleranceHigh: OffsetToleranceHigh = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.OffsetToleranceLow: OffsetToleranceLow = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.Polarity: Polarity = node.InnerText; break; case DbOperations.SensorDB.SensorModelFields.RangeAve: RangeMedium = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.RangeHigh: RangeHigh = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.RangeLow: RangeLow = Convert.ToDouble(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case DbOperations.SensorDB.SensorModelFields.Shunt: Shunt = (ShuntMode)Enum.Parse(typeof(ShuntMode), node.InnerText); break; case DbOperations.SensorDB.SensorModelFields.SupportedExcitation: { var tokens = node.InnerText.Split(new string[] { System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None); SupportedExcitation = tokens.Select(token => (ExcitationVoltageOptions.ExcitationVoltageOption)Enum.Parse(typeof(ExcitationVoltageOptions.ExcitationVoltageOption), token)).ToArray(); } break; case DbOperations.SensorDB.SensorModelFields.UniPolar: UniPolar = Convert.ToBoolean(node.InnerText); break; case DbOperations.SensorDB.SensorModelFields.UserPartNumber: UserPartNumber = node.InnerText; break; case DbOperations.SensorDB.SensorModelFields.Version: Version = Convert.ToInt32(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; default: throw new NotSupportedException("SensorModel::ProcessXMLElement unsupported field: " + field.ToString()); } } Calibration.InitialOffsets = new InitialOffsets(new InitialOffset(initialEU)); } public void WriteXML(ref System.Xml.XmlWriter writer) { writer.WriteStartElement("SensorModel"); var fields = Enum.GetValues(typeof(DbOperations.SensorDB.SensorModelFields)).Cast().ToArray(); foreach (var f in fields) { writer.WriteStartElement(f.ToString()); switch (f) { case DbOperations.SensorDB.SensorModelFields.AxisNumber: writer.WriteString(AxisNumber.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.Bridge: writer.WriteString(Bridge.ToString()); break; case DbOperations.SensorDB.SensorModelFields.BridgeResistance: writer.WriteString(BridgeResistance.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.CalibrationRecord: writer.WriteString(Calibration.ToSerializedString()); break; case DbOperations.SensorDB.SensorModelFields.CalInterval: writer.WriteString(CalInterval.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.Capacity: writer.WriteString(Capacity.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.CheckOffset: writer.WriteString(CheckOffset.ToString()); break; case DbOperations.SensorDB.SensorModelFields.CouplingMode: writer.WriteString(CouplingMode.ToString()); break; case DbOperations.SensorDB.SensorModelFields.FilterClass: writer.WriteString(Filter.ToString()); break; case DbOperations.SensorDB.SensorModelFields.IgnoreRange: writer.WriteString(IgnoreRange.ToString()); break; case DbOperations.SensorDB.SensorModelFields.Invert: writer.WriteString(Invert.ToString()); break; case DbOperations.SensorDB.SensorModelFields.ISOCode: writer.WriteString(ISOCode); break; case DbOperations.SensorDB.SensorModelFields.ISOChannelName: writer.WriteString(ISOChannelName); break; case DbOperations.SensorDB.SensorModelFields.UserCode: writer.WriteString(UserCode); break; case DbOperations.SensorDB.SensorModelFields.UserChannelName: writer.WriteString(UserChannelName); break; case DbOperations.SensorDB.SensorModelFields.LastModified: writer.WriteString(LastModified.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.LocalOnly: writer.WriteString(LocalOnly.ToString()); break; case DbOperations.SensorDB.SensorModelFields.Manufacturer: writer.WriteString(Manufacturer); break; case DbOperations.SensorDB.SensorModelFields.MeasurementUnit: writer.WriteString(DisplayUnit); break; case DbOperations.SensorDB.SensorModelFields.Model: writer.WriteString(Model); break; case DbOperations.SensorDB.SensorModelFields.ModifiedBy: writer.WriteString(LastUpdatedBy); break; case DbOperations.SensorDB.SensorModelFields.NumberOfAxes: writer.WriteString(NumberOfAxes.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.OffsetToleranceHigh: writer.WriteString(OffsetToleranceHigh.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.OffsetToleranceLow: writer.WriteString(OffsetToleranceLow.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.Polarity: writer.WriteString(Polarity); break; case DbOperations.SensorDB.SensorModelFields.RangeAve: writer.WriteString(RangeMedium.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.RangeHigh: writer.WriteString(RangeHigh.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.RangeLow: writer.WriteString(RangeLow.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; case DbOperations.SensorDB.SensorModelFields.Shunt: writer.WriteString(Shunt.ToString()); break; case DbOperations.SensorDB.SensorModelFields.SupportedExcitation: { List s = new List(); foreach (var se in SupportedExcitation) { s.Add(se.ToString()); } writer.WriteString(string.Join(System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator, s.ToArray())); } break; case DbOperations.SensorDB.SensorModelFields.UniPolar: writer.WriteString(UniPolar.ToString()); break; case DbOperations.SensorDB.SensorModelFields.UserPartNumber: writer.WriteString(UserPartNumber); break; case DbOperations.SensorDB.SensorModelFields.Version: writer.WriteString(Version.ToString(System.Globalization.CultureInfo.InvariantCulture)); break; default: throw new NotSupportedException("SensorModel::WriteXML unsupported field: " + f.ToString()); } writer.WriteEndElement(); } writer.WriteEndElement(); } private enum XMLFields { Model, Manufacturer, UserPartNumber, Capacity, OffsetTolerance, MeasurementUnit, SensorRange, Sensitivity, Excitation, IsProportional, Bridge, Shunt, BridgeResistance, RemoveOffset, FilterClass, ZeroMethod, InitialEU, NonLinear, UniPolar, PolynomialStyle, IRTraccFormat, LinearizationFormula, PhysicalDimension, IgnoreRange, Invert, CouplingMode, CheckOffset } public SensorModel(System.Xml.XmlElement node) { var initialEU = 0D; foreach (var childnode in node.ChildNodes) { if (!(childnode is System.Xml.XmlElement elem)) { continue; } try { if (elem.Name == "Unipolar") { UniPolar = bool.Parse(elem.InnerText); continue; } var field = (XMLFields)Enum.Parse(typeof(XMLFields), elem.Name); var value = elem.InnerText; switch (field) { case XMLFields.Bridge: Bridge = (SensorConstants.BridgeType)Enum.Parse(typeof(SensorConstants.BridgeType), value); break; case XMLFields.BridgeResistance: if (double.TryParse(value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var newD)) { BridgeResistance = newD; } break; case XMLFields.Capacity: Capacity = double.Parse(value, System.Globalization.CultureInfo.InvariantCulture); break; case XMLFields.Excitation: SupportedExcitation = new ExcitationVoltageOptions.ExcitationVoltageOption[] { (ExcitationVoltageOptions.ExcitationVoltageOption)Enum.Parse(typeof(ExcitationVoltageOptions.ExcitationVoltageOption), value) }; break; case XMLFields.FilterClass: Filter = new FilterClass(value); break; case XMLFields.IgnoreRange: IgnoreRange = bool.Parse(value); break; case XMLFields.Invert: Invert = bool.Parse(value); break; case XMLFields.InitialEU: initialEU = double.Parse(value, System.Globalization.CultureInfo.InvariantCulture); //InitialEU = double.Parse(value, System.Globalization.CultureInfo.InvariantCulture); break; case XMLFields.IsProportional: Calibration.IsProportional = bool.Parse(value); break; case XMLFields.LinearizationFormula: Calibration.Records.Records[0].Poly = new DTS.Common.Classes.Sensors.LinearizationFormula(); Calibration.Records.Records[0].Poly.FromSerializeString(value); break; case XMLFields.Manufacturer: Manufacturer = value; //System.Diagnostics.Trace.WriteLine(Manufacturer); break; case XMLFields.MeasurementUnit: DisplayUnit = value; break; case XMLFields.Model: Model = value; //System.Diagnostics.Trace.WriteLine(Model); break; case XMLFields.NonLinear: Calibration.NonLinear = bool.Parse(value); break; case XMLFields.OffsetTolerance: { if (!string.IsNullOrWhiteSpace(value)) { try { var tol = new LowHigh(value); OffsetToleranceHigh = tol.High; OffsetToleranceLow = tol.Low; } catch (Exception ex) { APILogger.Log(ex); } } } break; case XMLFields.PhysicalDimension: PhysicalDimension = value; break; case XMLFields.PolynomialStyle: //var polystyle = (PolynomialStyles)Enum.Parse(typeof(PolynomialStyles), value); //switch (polystyle) //{ // case PolynomialStyles. //} //don't need this anymore? break; case XMLFields.IRTraccFormat: var irFormat = (IRTraccFormats)Enum.Parse(typeof(IRTraccFormats), value); switch (irFormat) { case IRTraccFormats.AverageOverTime: Calibration.Records.Records[0].Poly.NonLinearStyle = NonLinearStyles.IRTraccAverageOverTime; break; case IRTraccFormats.DiagnosticZeroMMmV: Calibration.Records.Records[0].Poly.NonLinearStyle = NonLinearStyles.IRTraccDiagnosticsZero; break; case IRTraccFormats.Manual: Calibration.Records.Records[0].Poly.NonLinearStyle = NonLinearStyles.IRTraccManual; break; case IRTraccFormats.ZeroMMmV: Calibration.Records.Records[0].Poly.NonLinearStyle = NonLinearStyles.IRTraccZeroMMmV; break; case IRTraccFormats.Polynomial: Calibration.Records.Records[0].Poly.NonLinearStyle = NonLinearStyles.Polynomial; break; } break; case XMLFields.RemoveOffset: Calibration.RemoveOffset = bool.Parse(value); break; case XMLFields.Sensitivity: Calibration.Records.Records[0].Sensitivity = double.Parse(value, System.Globalization.CultureInfo.InvariantCulture); break; case XMLFields.SensorRange: { var Range = new SensorRange(value); RangeHigh = Range.High; RangeLow = Range.Low; RangeMedium = Range.Medium; } break; case XMLFields.Shunt: Shunt = (ShuntMode)Enum.Parse(typeof(ShuntMode), value); break; case XMLFields.UniPolar: UniPolar = bool.Parse(value); break; case XMLFields.UserPartNumber: UserPartNumber = value; break; case XMLFields.ZeroMethod: { Calibration.ZeroMethods = new ZeroMethods(new ZeroMethod(value)); } break; case XMLFields.CouplingMode: CouplingMode = (SensorConstants.CouplingModes)Enum.Parse(typeof(SensorConstants.CouplingModes), value); break; case XMLFields.CheckOffset: CheckOffset = Boolean.Parse(value); break; default: throw new NotSupportedException("field :" + field.ToString()); } } catch (Exception ex) { APILogger.Log("Failed to parse xml", ex, elem.Name, elem.Value); } Calibration.InitialOffsets = new InitialOffsets(new InitialOffset(initialEU)); } } public override string ToString() { return Model; } private SensorConstants.BridgeType ConvertToBridge(int bridge) { switch (bridge) { case 0: return SensorConstants.BridgeType.IEPE; case 4: return SensorConstants.BridgeType.HalfBridge_SigPlus; case 3: return SensorConstants.BridgeType.FullBridge; case 2: return SensorConstants.BridgeType.HalfBridge; case 1: return SensorConstants.BridgeType.QuarterBridge; default: return SensorConstants.BridgeType.FullBridge; } } internal SensorModel(DataRow dr) { try { Polarity = (string)dr[DbOperations.SensorDB.SensorModelFields.Polarity.ToString()]; AxisNumber = Convert.ToInt16(dr[DbOperations.SensorDB.SensorModelFields.AxisNumber.ToString()]); Bridge = ConvertToBridge(Convert.ToInt32(dr[DbOperations.SensorDB.SensorModelFields.Bridge.ToString()])); BridgeResistance = Convert.ToDouble(dr[DbOperations.SensorDB.SensorModelFields.BridgeResistance.ToString()]); CalInterval = Convert.ToInt32(dr[DbOperations.SensorDB.SensorModelFields.CalInterval.ToString()]); Capacity = Convert.ToDouble(dr[DbOperations.SensorDB.SensorModelFields.Capacity.ToString()]); CouplingMode = (SensorConstants.CouplingModes)Convert.ToInt32(dr[DbOperations.SensorDB.SensorModelFields.CouplingMode.ToString()]); Filter = new FilterClass((string)dr[DbOperations.SensorDB.SensorModelFields.FilterClass.ToString()]); IgnoreRange = Convert.ToBoolean(dr[DbOperations.SensorDB.SensorModelFields.IgnoreRange.ToString()]); CheckOffset = Convert.ToBoolean(dr[DbOperations.SensorDB.SensorModelFields.CheckOffset.ToString()]); Invert = Convert.ToBoolean(dr[DbOperations.SensorDB.SensorModelFields.Invert.ToString()]); LastModified = (DateTime)dr[DbOperations.SensorDB.SensorModelFields.LastModified.ToString()]; SetLocalOnly(Convert.ToBoolean(dr[DbOperations.SensorDB.SensorModelFields.LocalOnly.ToString()])); Manufacturer = (string)dr[DbOperations.SensorDB.SensorModelFields.Manufacturer.ToString()]; DisplayUnit = (string)dr[DbOperations.SensorDB.SensorModelFields.MeasurementUnit.ToString()]; Model = (string)dr[DbOperations.SensorDB.SensorModelFields.Model.ToString()]; LastUpdatedBy = (string)dr[DbOperations.SensorDB.SensorModelFields.ModifiedBy.ToString()]; NumberOfAxes = Convert.ToInt16(dr[DbOperations.SensorDB.SensorModelFields.NumberOfAxes.ToString()]); OffsetToleranceHigh = Convert.ToDouble(dr[DbOperations.SensorDB.SensorModelFields.OffsetToleranceHigh.ToString()]); OffsetToleranceLow = Convert.ToDouble(dr[DbOperations.SensorDB.SensorModelFields.OffsetToleranceLow.ToString()]); RangeMedium = Convert.ToDouble(dr[DbOperations.SensorDB.SensorModelFields.RangeAve.ToString()]); RangeHigh = Convert.ToDouble(dr[DbOperations.SensorDB.SensorModelFields.RangeHigh.ToString()]); RangeLow = Convert.ToDouble(dr[DbOperations.SensorDB.SensorModelFields.RangeLow.ToString()]); Shunt = (ShuntMode)Convert.ToInt32(dr[DbOperations.SensorDB.SensorModelFields.Shunt.ToString()]); UniPolar = Convert.ToBoolean(dr[DbOperations.SensorDB.SensorModelFields.UniPolar.ToString()]); UserPartNumber = (string)dr[DbOperations.SensorDB.SensorModelFields.UserPartNumber.ToString()]; Version = Convert.ToInt32(dr[DbOperations.SensorDB.SensorModelFields.Version.ToString()]); ISOCode = (string)dr[DbOperations.SensorDB.SensorModelFields.ISOCode.ToString()]; var o = dr[DbOperations.SensorDB.SensorModelFields.ISOChannelName.ToString()]; if (!DBNull.Value.Equals(o)) { ISOChannelName = (string)o; } else { ISOChannelName = ""; } o = dr[DbOperations.SensorDB.SensorModelFields.UserCode.ToString()]; if (!DBNull.Value.Equals(o)) { UserCode = (string)o; } else { UserCode = ""; } o = dr[DbOperations.SensorDB.SensorModelFields.UserChannelName.ToString()]; if (!DBNull.Value.Equals(o)) { UserChannelName = (string)o; } else { UserChannelName = ""; } Calibration = new SensorCalibration((string)dr[DbOperations.SensorDB.SensorModelFields.CalibrationRecord.ToString()]); var options = new List(); var tokens = ((string)dr[DbOperations.SensorDB.SensorModelFields.SupportedExcitation.ToString()]).Split(new[] { System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None); foreach (var token in tokens) { if (Enum.TryParse(token, out ExcitationVoltageOptions.ExcitationVoltageOption option)) { options.Add(option); } } SupportedExcitation = options.ToArray(); } catch (Exception ex) { APILogger.Log("Failed to process fields: ", ex); } } } public class SensorModelCollection : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected bool SetProperty(ref T storage, T value, String propertyName = null) { if (Equals(storage, value)) return false; storage = value; OnPropertyChanged(propertyName); return true; } protected void OnPropertyChanged(string propertyName = null) { if (!HookedUp) { return; } PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private Dictionary> _sensorModels = new Dictionary>(); public void ReloadAll() { lock (_collection) { PopulateCollection(); } } private static void PopulateCollection() { if (null == _collection) { _collection = new SensorModelCollection(); } else { _collection._sensorModels.Clear(); } _collection.LoadAllSensorModels(); } protected SensorModelCollection() { } private static SensorModelCollection _collection = null; public static SensorModelCollection SensorModelList { get { lock (_lock) { if (null == _collection) { PopulateCollection(); } return _collection; } } } private static readonly object _lock = new object(); private volatile bool _Hookedup = true; public bool HookedUp { get => _Hookedup; set { _Hookedup = value; OnPropertyChanged("AllSensors"); } } public SensorModelCollection(string path) { LoadAllSensorModels(path); } public SensorModel[] SensorModels { get { lock (_lock) { var l = new List(); using (var sensorModelsEnumerator = _sensorModels.GetEnumerator()) { while (sensorModelsEnumerator.MoveNext()) { var currentValueEnumerator = sensorModelsEnumerator.Current.Value.GetEnumerator(); while (currentValueEnumerator.MoveNext()) { l.Add(currentValueEnumerator.Current.Value); } } } return l.ToArray(); } } } /// /// deletes all Sensor Models /// originally created so TDM imports could clear all tables except DAS tables /// public void DeleteAll() { _sensorModels.Clear(); try { using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = DbOperationsEnum.StoredProcedure.sp_SensorModelsDelete.ToString(); cmd.Parameters.Add(new SqlParameter("@Model", SqlDbType.NVarChar, 50) { Value = null }); cmd.Parameters.Add(new SqlParameter("@Manufacturer", SqlDbType.NVarChar, 50) { Value = null }); var errorNumberParam = new SqlParameter("@errorNumber", SqlDbType.Int) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(errorNumberParam); var errorMessageParam = new SqlParameter("@errorMessage", SqlDbType.NVarChar, 250) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(errorMessageParam); cmd.ExecuteNonQuery(); if (int.Parse(errorNumberParam.Value.ToString()) != 0) { //errorMessageParam.Value } cmd.ExecuteNonQuery(); } finally { cmd.Connection.Dispose(); } } } catch (Exception ex) { APILogger.Log("Failed to delete sensor models, ", ex); } LoadAllSensorModels(); } private const string FILE_NAME = "Model.SensorDB.xml"; protected void LoadAllSensorModels(string path) { string filename = System.IO.Path.Combine(path, FILE_NAME); if (!System.IO.File.Exists(filename)) { return; } var doc = new System.Xml.XmlDocument(); var xml = System.IO.File.ReadAllText(filename); doc.LoadXml(xml); var nodes = doc.GetElementsByTagName("SensorModels"); foreach (var node in nodes) { if (!(node is System.Xml.XmlElement element)) { continue; } foreach (var childNode in element.GetElementsByTagName("SensorModel")) { if (!(childNode is System.Xml.XmlElement elem)) { continue; } LoadSensor(elem); } } } protected void LoadAllSensorModels() { try { using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = DbOperationsEnum.StoredProcedure.sp_SensorModelsGet.ToString(); #region params cmd.Parameters.Add(new SqlParameter("@Model", SqlDbType.NVarChar, 50) { Value = null }); #endregion params using (var ds = DbOperations.Connection.QueryDataSet(cmd)) { if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { foreach (DataRow dr in ds.Tables[0].Rows) { try { var sm = new SensorModel(dr); if (!_sensorModels.ContainsKey(sm.Manufacturer)) { _sensorModels.Add(sm.Manufacturer, new Dictionary()); } if (!_sensorModels[sm.Manufacturer].ContainsKey(sm.Model)) { _sensorModels[sm.Manufacturer].Add(sm.Model, sm); } } catch (Exception ex) { APILogger.Log("Failed to process a row in the database: ", ex); } } } } } finally { cmd.Connection.Dispose(); } } } catch (Exception ex) { APILogger.Log("Failed to retrieve sensor models, ", ex); } } private void LoadSensor(System.Xml.XmlElement node) { try { var sm = new SensorModel(node); if (!_sensorModels.ContainsKey(sm.Manufacturer)) { _sensorModels.Add(sm.Manufacturer, new Dictionary()); } _sensorModels[sm.Manufacturer][sm.Model] = sm; } catch (Exception ex) { APILogger.Log("failed to get node from sensor model db, ", ex); } } public void Commit(SensorModel sm, string username) { Commit(sm, username, true); } public void Commit(SensorModel sm, string username, bool bNotify) { if (_sensorModels.ContainsKey(sm.Manufacturer)) { if (_sensorModels[sm.Manufacturer].ContainsKey(sm.Model)) { UpdateAll(username, sm); _sensorModels[sm.Manufacturer][sm.Model] = sm; return; } Insert(username, sm); _sensorModels[sm.Manufacturer].Add(sm.Model, sm); } else { Insert(username, sm); _sensorModels.Add(sm.Manufacturer, new Dictionary()); _sensorModels[sm.Manufacturer].Add(sm.Model, sm); } if (bNotify) { OnPropertyChanged("SensorModels"); } } public void UpdateList() { OnPropertyChanged("SensorModels"); } private void Insert(string username, SensorModel sm) { try { sm.LastModified = DateTime.Now; sm.LastUpdatedBy = username; using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = DbOperationsEnum.StoredProcedure.sp_SensorModelsInsert.ToString(); #region params cmd.Parameters.Add(new SqlParameter("@Model", SqlDbType.NVarChar, 50) { Value = sm.Model }); cmd.Parameters.Add( new SqlParameter("@Manufacturer", SqlDbType.NVarChar, 50) { Value = sm.Manufacturer }); cmd.Parameters.Add( new SqlParameter("@UserPartNumber", SqlDbType.NVarChar, 50) { Value = sm.UserPartNumber }); cmd.Parameters.Add(new SqlParameter("@Capacity", SqlDbType.Float) { Value = sm.Capacity }); cmd.Parameters.Add( new SqlParameter("@OffsetToleranceLow", SqlDbType.Float) { Value = sm.OffsetToleranceLow }); cmd.Parameters.Add( new SqlParameter("@OffsetToleranceHigh", SqlDbType.Float) { Value = sm.OffsetToleranceHigh }); cmd.Parameters.Add( new SqlParameter("@MeasurementUnit", SqlDbType.NVarChar, 50) { Value = sm.DisplayUnit }); cmd.Parameters.Add(new SqlParameter("@Bridge", SqlDbType.SmallInt) { Value = SensorsCollection.ConvertBridgeToInt(sm.Bridge) }); cmd.Parameters.Add(new SqlParameter("@Shunt", SqlDbType.SmallInt) { Value = sm.Shunt }); cmd.Parameters.Add( new SqlParameter("@BridgeResistance", SqlDbType.Float) { Value = sm.BridgeResistance }); cmd.Parameters.Add( new SqlParameter("@FilterClass", SqlDbType.NVarChar, 50) { Value = sm.Filter.ToString() }); cmd.Parameters.Add(new SqlParameter("@UniPolar", SqlDbType.Bit) { Value = sm.UniPolar }); cmd.Parameters.Add(new SqlParameter("@IgnoreRange", SqlDbType.Bit) { Value = sm.IgnoreRange }); cmd.Parameters.Add( new SqlParameter("@CouplingMode", SqlDbType.SmallInt) { Value = sm.CouplingMode }); cmd.Parameters.Add(new SqlParameter("@Version", SqlDbType.Int) { Value = sm.Version }); cmd.Parameters.Add(new SqlParameter("@RangeLow", SqlDbType.Float) { Value = sm.RangeLow }); cmd.Parameters.Add(new SqlParameter("@RangeAve", SqlDbType.Float) { Value = sm.RangeMedium }); cmd.Parameters.Add(new SqlParameter("@RangeHigh", SqlDbType.Float) { Value = sm.RangeHigh }); cmd.Parameters.Add( new SqlParameter("@LastModified", SqlDbType.DateTime) { Value = sm.LastModified }); cmd.Parameters.Add( new SqlParameter("@ModifiedBy", SqlDbType.NVarChar, 50) { Value = sm.LastUpdatedBy }); cmd.Parameters.Add(new SqlParameter("@LocalOnly", SqlDbType.Bit) { Value = sm.LocalOnly }); cmd.Parameters.Add( new SqlParameter("@NumberOfAxes", SqlDbType.SmallInt) { Value = sm.NumberOfAxes }); cmd.Parameters.Add(new SqlParameter("@CalInterval", SqlDbType.Int) { Value = sm.CalInterval }); cmd.Parameters.Add(new SqlParameter("@AxisNumber", SqlDbType.SmallInt) { Value = sm.AxisNumber }); cmd.Parameters.Add(new SqlParameter("@Polarity", SqlDbType.NVarChar, 50) { Value = sm.Polarity }); cmd.Parameters.Add(new SqlParameter("@Invert", SqlDbType.Bit) { Value = sm.Invert }); cmd.Parameters.Add(new SqlParameter("@CheckOffset", SqlDbType.Bit) { Value = sm.CheckOffset }); cmd.Parameters.Add( new SqlParameter("@CalibrationRecord", SqlDbType.NVarChar, 255) { Value = sm.Calibration.ToSerializedString() }); cmd.Parameters.Add(new SqlParameter("@ISOCode", SqlDbType.NVarChar, 20) { Value = sm.ISOCode }); cmd.Parameters.Add(new SqlParameter("@IsoChannelName", SqlDbType.NVarChar, 255) { Value = sm.ISOChannelName }); cmd.Parameters.Add(new SqlParameter("@UserCode", SqlDbType.NVarChar, 50) { Value = sm.UserCode }); cmd.Parameters.Add(new SqlParameter("@UserChannelName", SqlDbType.NVarChar, 255) { Value = sm.UserChannelName }); cmd.Parameters.Add(new SqlParameter("@SupportedExcitation", SqlDbType.NVarChar, 255) { Value = string.Join( System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator, sm.SupportedExcitation.Select(e => e.ToString()).ToArray()) }); cmd.Parameters.Add(//TODO: linear/nonlinear Offsets new SqlParameter("@InitialEU", SqlDbType.Float) { Value = sm.Calibration.InitialOffsets.Offsets[0].EU }); var newIdParam = new SqlParameter("@new_id", SqlDbType.Int) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(newIdParam); var errorNumberParam = new SqlParameter("@errorNumber", SqlDbType.Int) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(errorNumberParam); var errorMessageParam = new SqlParameter("@errorMessage", SqlDbType.NVarChar, 250) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(errorMessageParam); #endregion params cmd.ExecuteNonQuery(); if (int.Parse(errorNumberParam.Value.ToString()) != 0) { //errorMessageParam.Value } } finally { cmd.Connection.Dispose(); } } } catch (Exception ex) { APILogger.Log("failed to insert sensor model:", ex); } } private static void UpdateAll(string username, SensorModel sm) { sm.LastModified = DateTime.Now; sm.LastUpdatedBy = username; try { using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = DbOperationsEnum.StoredProcedure.sp_SensorModelsUpdate.ToString(); #region params cmd.Parameters.Add(new SqlParameter("@Model", SqlDbType.NVarChar, 50) { Value = sm.Model }); cmd.Parameters.Add( new SqlParameter("@Manufacturer", SqlDbType.NVarChar, 50) { Value = sm.Manufacturer }); cmd.Parameters.Add( new SqlParameter("@UserPartNumber", SqlDbType.NVarChar, 50) { Value = sm.UserPartNumber }); cmd.Parameters.Add(new SqlParameter("@Capacity", SqlDbType.Float) { Value = sm.Capacity }); cmd.Parameters.Add( new SqlParameter("@OffsetToleranceLow", SqlDbType.Float) { Value = sm.OffsetToleranceLow }); cmd.Parameters.Add( new SqlParameter("@OffsetToleranceHigh", SqlDbType.Float) { Value = sm.OffsetToleranceHigh }); cmd.Parameters.Add( new SqlParameter("@MeasurementUnit", SqlDbType.NVarChar, 50) { Value = sm.DisplayUnit }); cmd.Parameters.Add(new SqlParameter("@Bridge", SqlDbType.SmallInt) { Value = SensorsCollection.ConvertBridgeToInt(sm.Bridge) }); cmd.Parameters.Add(new SqlParameter("@Shunt", SqlDbType.SmallInt) { Value = sm.Shunt }); cmd.Parameters.Add( new SqlParameter("@BridgeResistance", SqlDbType.Float) { Value = sm.BridgeResistance }); cmd.Parameters.Add( new SqlParameter("@FilterClass", SqlDbType.NVarChar, 50) { Value = sm.Filter.ToString() }); cmd.Parameters.Add(new SqlParameter("@UniPolar", SqlDbType.Bit) { Value = sm.UniPolar }); cmd.Parameters.Add(new SqlParameter("@IgnoreRange", SqlDbType.Bit) { Value = sm.IgnoreRange }); cmd.Parameters.Add( new SqlParameter("@CouplingMode", SqlDbType.SmallInt) { Value = sm.CouplingMode }); cmd.Parameters.Add(new SqlParameter("@Version", SqlDbType.Int) { Value = sm.Version }); cmd.Parameters.Add(new SqlParameter("@RangeLow", SqlDbType.Float) { Value = sm.RangeLow }); cmd.Parameters.Add(new SqlParameter("@RangeAve", SqlDbType.Float) { Value = sm.RangeMedium }); cmd.Parameters.Add(new SqlParameter("@RangeHigh", SqlDbType.Float) { Value = sm.RangeHigh }); cmd.Parameters.Add( new SqlParameter("@LastModified", SqlDbType.DateTime) { Value = sm.LastModified }); cmd.Parameters.Add( new SqlParameter("@ModifiedBy", SqlDbType.NVarChar, 50) { Value = sm.LastUpdatedBy }); cmd.Parameters.Add(new SqlParameter("@LocalOnly", SqlDbType.Bit) { Value = sm.LocalOnly }); cmd.Parameters.Add( new SqlParameter("@NumberOfAxes", SqlDbType.SmallInt) { Value = sm.NumberOfAxes }); cmd.Parameters.Add(new SqlParameter("@CalInterval", SqlDbType.Int) { Value = sm.CalInterval }); cmd.Parameters.Add(new SqlParameter("@AxisNumber", SqlDbType.SmallInt) { Value = sm.AxisNumber }); cmd.Parameters.Add(new SqlParameter("@Polarity", SqlDbType.NVarChar, 50) { Value = sm.Polarity }); cmd.Parameters.Add(new SqlParameter("@Invert", SqlDbType.Bit) { Value = sm.Invert }); cmd.Parameters.Add(new SqlParameter("@CheckOffset", SqlDbType.Bit) { Value = sm.CheckOffset }); cmd.Parameters.Add( new SqlParameter("@CalibrationRecord", SqlDbType.NVarChar, 255) { Value = sm.Calibration.ToSerializedString() }); cmd.Parameters.Add(new SqlParameter("@ISOCode", SqlDbType.NVarChar, 20) { Value = sm.ISOCode }); cmd.Parameters.Add(new SqlParameter("@IsoChannelName", SqlDbType.NVarChar, 255) { Value = sm.ISOChannelName }); cmd.Parameters.Add(new SqlParameter("@UserCode", SqlDbType.NVarChar, 50) { Value = sm.UserCode }); cmd.Parameters.Add(new SqlParameter("@UserChannelName", SqlDbType.NVarChar, 255) { Value = sm.UserChannelName }); cmd.Parameters.Add(new SqlParameter("@SupportedExcitation", SqlDbType.NVarChar, 255) { Value = string.Join( System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator, sm.SupportedExcitation.Select(e => e.ToString()).ToArray()) }); cmd.Parameters.Add(//TODO: linear/nonlinear offsets new SqlParameter("@InitialEU", SqlDbType.Float) { Value = sm.Calibration.InitialOffsets.Offsets[0].EU }); var errorNumberParam = new SqlParameter("@errorNumber", SqlDbType.Int) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(errorNumberParam); var errorMessageParam = new SqlParameter("@errorMessage", SqlDbType.NVarChar, 250) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(errorMessageParam); #endregion params cmd.ExecuteNonQuery(); if (int.Parse(errorNumberParam.Value.ToString()) != 0) { //errorMessageParam.Value } } finally { cmd.Connection.Dispose(); } } } catch (Exception ex) { APILogger.Log("failed to insert sensor model:", ex); } } public void DeleteSensorModel(SensorModel sm) { if (!_sensorModels.ContainsKey(sm.Manufacturer)) { return; } if (!_sensorModels[sm.Manufacturer].ContainsKey(sm.Model)) { return; } using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = DbOperationsEnum.StoredProcedure.sp_SensorModelsDelete.ToString(); cmd.Parameters.Add(new SqlParameter("@Model", SqlDbType.NVarChar, 50) { Value = sm.Model }); cmd.Parameters.Add( new SqlParameter("@Manufacturer", SqlDbType.NVarChar, 50) { Value = sm.Manufacturer }); var errorNumberParam = new SqlParameter("@errorNumber", SqlDbType.Int) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(errorNumberParam); var errorMessageParam = new SqlParameter("@errorMessage", SqlDbType.NVarChar, 250) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(errorMessageParam); cmd.ExecuteNonQuery(); if (int.Parse(errorNumberParam.Value.ToString()) != 0) { //errorMessageParam.Value } } finally { cmd.Connection.Dispose(); } } _sensorModels[sm.Manufacturer].Remove(sm.Model); if (_sensorModels[sm.Manufacturer].Count < 1) { _sensorModels.Remove(sm.Manufacturer); } OnPropertyChanged("SensorModels"); } public void DeleteSensorModels(SensorModel[] sms) { foreach (var sm in sms) { DeleteSensorModel(sm); } } public SensorModel[] GetSensorModelsForManufacturer(string manufacturer) { if (!_sensorModels.ContainsKey(manufacturer)) { return new SensorModel[0]; } var models = new SensorModel[_sensorModels[manufacturer].Count]; _sensorModels[manufacturer].Values.CopyTo(models, 0); var list = new List(models.Length); list.AddRange(models); list.Sort(); return list.ToArray(); } public string[] GetUniqueManufacturers() { var names = new string[_sensorModels.Keys.Count]; _sensorModels.Keys.CopyTo(names, 0); var list = new List(names.Length); list.AddRange(names); list.Sort(); return list.ToArray(); } public List GetUniqueAssemblyNames() { var sensors = SensorsCollection.SensorsList.GetAllSensors(true); var assemblyNameList = sensors.Select(x => x.AssemblyName.Trim()).Distinct().OrderBy(a => a).ToList(); return assemblyNameList; } public int GetNumberOfModels() { var count = 0; using (var enumeratorSensorModels = _sensorModels.GetEnumerator()) { while (enumeratorSensorModels.MoveNext()) { count += enumeratorSensorModels.Current.Value.Count; } } return count; } public SensorModel GetSensorModel(string maker, string model) { if (null == maker) { return null; } if (!_sensorModels.ContainsKey(maker)) return null; return _sensorModels[maker].ContainsKey(model) ? _sensorModels[maker][model] : null; } } }