using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; using System.IO; using DTS.Common.Classes.Sensors; using DTS.DASLib.Service; using System.ComponentModel; using DTS.Common.Enums; using DTS.Common.Enums.Sensors; namespace DTS.SensorDB { #region Support classes and enums public enum ShuntMode { None, Emulation, Internal, External } public enum BridgeLeg { First, Second, Third, Fourth } public class LowHigh : 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) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public double Low { get; set; } public double High { get; set; } #region Tags internal const string LowHighTag = "LowHigh"; internal const string LowTag = "Low"; internal const string HighTag = "High"; #endregion private readonly string TableName; internal LowHigh(XElement elem, string prefix, string tblName, string id) { TableName = tblName; XElement inner = null; try { inner = elem.Element(mkTag(prefix)); } catch (ArgumentNullException) { if (!string.IsNullOrEmpty(id)) throw new Exception(string.Format("{0}: Can't find tag {1} for entry {2}", TableName, prefix + "-" + LowHighTag, id)); else throw new Exception(string.Format("{0}: Can't find tag {1} in file", TableName, prefix + "-" + LowHighTag)); } Low = double.Parse(inner.Attribute(LowTag).Value, System.Globalization.CultureInfo.InvariantCulture); High = double.Parse(inner.Attribute(HighTag).Value, System.Globalization.CultureInfo.InvariantCulture); } public LowHigh(double _low, double _high) { Low = _low; High = _high; } internal XElement ToXElement(string prefix) { var element = new XElement(mkTag(prefix)); element.SetAttributeValue(LowTag, Low); element.SetAttributeValue(HighTag, High); return element; } internal void Update(XElement elem, string prefix) { var element = elem.Element(mkTag(prefix)); element.SetAttributeValue(LowTag, Low); element.SetAttributeValue(HighTag, High); } static internal string mkTag(string prefix) { return prefix + "-" + LowHighTag; } public string ToSerializeString() { return string.Format("{0},{1}", Low.ToString(System.Globalization.CultureInfo.InvariantCulture), High.ToString(System.Globalization.CultureInfo.InvariantCulture)); } public LowHigh(string value) { string[] values = value.Split(new char[] { ',' }); if (values.Length < 2) { throw new InvalidDataException("invalid low-high: " + value); } Low = double.Parse(values[0], System.Globalization.CultureInfo.InvariantCulture); High = double.Parse(values[1], System.Globalization.CultureInfo.InvariantCulture); } } #endregion public class SensorDBTables { private const string CalibrationTag = "Calibration"; private const string CalibrationDateTag = "Date"; public SensorCalibration GetLatestCalibrationBySerialNumberSafe(string sensorSerNo) { var cals = from cal in Calibrations.Elements(SensorDBTables.CalibrationTag) where ((string)cal.Element(SensorDBTables.SerialNumberTag)).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) orderby (DateTime)cal.Element(SensorDBTables.CalibrationDateTag) descending select new SensorCalibration(cal); if (null == cals || cals.Count() == 0) { return null; } return cals.First(); } public OutputTOMDigitalChannel[] GetTomsByDescription(string description) { var toms = from sensor in DigitalOutputChannels where sensor.DigitalChannelDescription == description select sensor; return toms.ToArray(); } protected System.Globalization.CultureInfo InvariantCulture = new System.Globalization.CultureInfo(""); public class EntryNotFoundException : System.Exception { public EntryNotFoundException(string msg) : base(msg) { } } #region Filenames internal const string ModelTableFilename = "Model.SensorDB.xml"; public const string DataTableFilename = "Data.SensorDB.xml"; public const string SensorTag = "Sensor"; public const string SerialNumberTag = "SerialNumber"; public const string IDTag = "ID"; internal const string CalibrationTableFilename = "Calibration.SensorDB.xml"; internal const string SquibTableFilename = "Data.SquibDB.xml"; internal const string DigitalOutputTableFilename = "Data.DigitalOut.xml"; #endregion #region Our data storage [Serializable()] public class DigitalChannelList { public List DigitalChannels { get; set; } public DigitalChannelList(OutputTOMDigitalChannel[] channels) { DigitalChannels = new List(channels); } public DigitalChannelList() { DigitalChannels = new List(); } } [Serializable()] public class SquibChannelList { public List SquibChannels { get; set; } public SquibChannelList(OutputSquibChannel[] channels) { SquibChannels = new List(channels); } public SquibChannelList() { SquibChannels = new List(); } } private List _squibChannels = new List(); public OutputSquibChannel[] SquibChannels { get { return _squibChannels.ToArray(); } set { _squibChannels.Clear(); _squibChannels.AddRange(value); } } private List _digitalChannels = new List(); public OutputTOMDigitalChannel[] DigitalOutputChannels { get { return _digitalChannels.ToArray(); } set { _digitalChannels.Clear(); _digitalChannels.AddRange(value); } } protected XElement Models { get; set; } protected XElement Sensors { get; set; } public XElement GetSensorsElement() { return Sensors; } public SensorData[] GetSensorsBySerialNumber(string sensorSerNo) { var sensors = from sensor in Sensors.Elements(SensorTag) where SensorData.IsValid(sensor) && ((string)sensor.Element(SerialNumberTag)).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) orderby (string)sensor.Element(SerialNumberTag) select new SensorData(sensor); return sensors.ToArray(); } protected XElement Calibrations { get; set; } protected bool ModelsDirty { get; set; } protected bool SensorsDirty { get; set; } protected bool CalibrationsDirty { get; set; } /// /// Event generated whenever the tables are modified. /// public event EventHandler OnSensorDBModified; #endregion public string CurrentFolder { get; set; } public SensorDBTables() { SetAllClean(); } protected void SetAllClean() { ModelsDirty = false; SensorsDirty = false; CalibrationsDirty = false; } protected void TriggerSensorDBModified() { OnSensorDBModified?.Invoke(this, null); } /// /// this function is designed to allow the Load function below to /// load XML files without throwing exceptions when the files don't exist, /// but create if Empty is true /// 6/8/2010 - dtm /// /// /// /// /// private XElement LoadFile(string fileLocation, bool createIfEmpty, string defaultElement) { if (System.IO.File.Exists(fileLocation)) { return XElement.Load(fileLocation); } else if (createIfEmpty) { return new XElement(defaultElement); } throw new System.IO.FileNotFoundException(fileLocation); } private double _defaultAveZeroStart = SensorConstants.DefaultZeroMethodStart; // FB12764: Default in SensorConstants public double DefaultAveZeroStart { get { return _defaultAveZeroStart; } set { _defaultAveZeroStart = value; } } private double _defaultAveZeroStop = SensorConstants.DefaultZeroMethodEnd; // FB12764: Default in SensorConstants public double DefaultAveZeroStop { get { return _defaultAveZeroStop; } set { _defaultAveZeroStop = value; } } public void Load(string folder, bool createIfEmpty, string sifFolder, double defaultPrepareAveZeroStart, double defaultPrepareAveZeroStop) { Load(folder, createIfEmpty, sifFolder, defaultPrepareAveZeroStart, defaultPrepareAveZeroStop, DataTableFilename); } public void Load(string folder, bool createIfEmpty, string sifFolder, double defaultPrepareAveZeroStart, double defaultPrepareAveZeroStop, string datatableFileName) { _defaultAveZeroStart = defaultPrepareAveZeroStart; _defaultAveZeroStop = defaultPrepareAveZeroStop; CurrentFolder = folder; //APILogger.Log(SensorModelCollection.GetSensorModels().GetNumberOfModels(), " sensor models loaded"); try { Sensors = LoadFile(string.Format("{0}\\{1}", folder, datatableFileName), createIfEmpty, SensorData.TOP_LEVEL_TAG); } catch (System.Exception ex) { if (!createIfEmpty) { throw ex; } Sensors = new XElement(SensorData.TOP_LEVEL_TAG); } try { Calibrations = LoadFile(string.Format("{0}\\{1}", folder, CalibrationTableFilename), createIfEmpty, SensorCalibration.TOP_LEVEL_TAG); } catch (System.Exception ex) { if (!createIfEmpty) { throw ex; } Calibrations = new XElement(SensorCalibration.TOP_LEVEL_TAG); } try { _digitalChannels.Clear(); string file = Path.Combine(folder, DigitalOutputTableFilename); if (File.Exists(file)) { using (FileStream fs = new FileStream(file, FileMode.Open)) { System.Xml.XmlReaderSettings settings = new System.Xml.XmlReaderSettings(); settings.ConformanceLevel = System.Xml.ConformanceLevel.Fragment; settings.IgnoreWhitespace = true; settings.IgnoreComments = true; System.Xml.XmlReader reader = System.Xml.XmlReader.Create(fs, settings); reader.Read(); reader.ReadStartElement("DigitalChannelList"); reader.ReadStartElement("DigitalChannels"); while (reader.NodeType == System.Xml.XmlNodeType.Element) { OutputTOMDigitalChannel osc = new OutputTOMDigitalChannel(reader); _digitalChannels.Add(osc); } reader.ReadEndElement(); reader.ReadEndElement(); } } } catch (System.Exception) { _digitalChannels.Clear(); } try { _squibChannels.Clear(); string file = Path.Combine(folder, SquibTableFilename); if (File.Exists(file)) { using (FileStream fs = new FileStream(file, FileMode.Open)) { System.Xml.XmlReaderSettings settings = new System.Xml.XmlReaderSettings(); settings.ConformanceLevel = System.Xml.ConformanceLevel.Fragment; settings.IgnoreWhitespace = true; settings.IgnoreComments = true; System.Xml.XmlReader reader = System.Xml.XmlReader.Create(fs, settings); reader.Read(); reader.ReadStartElement("SquibChannelList"); reader.ReadStartElement("SquibChannels"); while (reader.NodeType == System.Xml.XmlNodeType.Element) { OutputSquibChannel osc = new OutputSquibChannel(reader); _squibChannels.Add(osc); } reader.ReadEndElement(); reader.ReadEndElement(); } } } catch (Exception) { //_squibChannels.Clear(); } SetAllClean(); TriggerSensorDBModified(); } private const string INVERT_DATA_TAG = "---- Invert Data - 0=no invert, 1=yes invert ----"; private const string ZERO_REFERENCE_TAG = "---- Zero Reference - 0=use 30 msec avg, 1=use prezero, 2=equals zero mV ----"; private const string CHANNEL_DESCRIPTION_TAG = "---- Channel Description ----"; private const string SERIAL_NUMBER_TAG = "---- Serial Number ----"; private const string OFFSET_LOW_TOLERANCE_TAG = "---- Offset Low Tol (mV) ----"; private const string OFFSET_HIGH_TOLERANCE_TAG = "---- Offset High Tol (mV) ----"; private const string CAL_MODE_TAG = "---- Cal Mode - I=Voltage Insertion, S=Shunt ----"; private const string CAL_STEP_TAG = "---- Cal Step - shunt resistor (Ohms) ----"; private const string SHUNT_VALUE_TAG = "---- Shunt Value - corresponding value of shunt resistor in Eng Units ----"; private const string PROPORTIONAL_TO_EXCITATION_TAG = "---- Proportional to Excitation ----"; private const string SENSITIVITY_TAG = "---- Sensitivity (mV/V/eng unit) ----"; private const string GAIN_TAG = "---- Gain - must be a valid gain from list ----"; private const string EXCITATION_TAG = "---- Excitation Voltage must be a valid voltage from list ----"; private const string ENG_UNIT_TAG = "---- Eng Unit ----"; private const string SOFTWARE_FILTER_TAG = "---- Software Filter, -3dB point (Hz) ----"; private const string DESIRED_MAX_RANGE_TAG = "---- Desired Max Range in Eng Units ----"; private const string CALIBRATION_DATE_TAG = "---- Calibration Date M_D_Y ----"; private const string REMOVE_NATURAL_OFFSET_TAG = "---- Remove Natural Sensor Offset? ----"; private const string INITIAL_EU_VALUE_TAG = "---- Initial EU Value ----"; private const string SENSOR_ID_TYPE_TAG = "---- Sensor ID Type ----"; private const string SENSOR_ID_NUMBER_TAG = "---- Sensor ID No ----"; private const string ISO_CODE_TAG = "---- ISO Code ----"; private const string EMPTY_ISO_CODE = "0000000000000000"; private const string EMPTY_SENSORID_TAG = "NONE"; private const string SENSOR_CATEGORY_TAG = "---- Sensor Category (Use 0 for most sensors) ----"; private const string SOFTWARE_VERSION_TAG = "Software Version: "; public static void ProcessSif(string file, ref SensorData sd, ref SensorCalibration cal, double defaultAveWindowStart, double defaultAveWindowStop) { if (!File.Exists(file)) { throw new FileNotFoundException(file); } using (StreamReader sr = new StreamReader(file, Encoding.Default)) { sd = CreateDefaultSensor(0D, 0D); sd.CheckOffset = true; string line1 = sr.ReadLine(); string line2 = sr.ReadLine(); double sensitivity = 0D; DateTime calibrationDate = DateTime.MinValue; while (null != line1 && null != line2) { switch (line1) { case CHANNEL_DESCRIPTION_TAG: sd.Comment = line2; break; case SERIAL_NUMBER_TAG: sd.SerialNumber = line2; break; case OFFSET_LOW_TOLERANCE_TAG: sd.OffsetToleranceLow = Convert.ToDouble(line2); break; case OFFSET_HIGH_TOLERANCE_TAG: sd.OffsetToleranceHigh = Convert.ToDouble(line2); break; case CAL_MODE_TAG: switch (line2[0]) { case 'S'://this appears to just tell us Shunt or not, not what type? //sd.Shunt = ShuntMode.Internal; sd.Shunt = ShuntMode.Emulation; break; case 'I'://voltage insertion - apparently this is what you get //if you click no shunt or have bridge resistance of 0? sd.Shunt = ShuntMode.None; break; default: throw new InvalidDataException("bad format cal mode position 0 " + line2); } switch (line2[1]) { case 'D': sd.Bridge = SensorConstants.BridgeType.FullBridge; break; case 'S': sd.Bridge = SensorConstants.BridgeType.HalfBridge; break; default: throw new InvalidDataException("bad format cal mode position 1 " + line2); } switch (line2[2]) { case 'F': sd.ByPassFilter = false; break; case 'B': sd.ByPassFilter = true; break; default: throw new InvalidDataException("bad format cal mode position 2" + line2); } break; case CAL_STEP_TAG: { double value = Convert.ToDouble(line2); if (value == 0D) { if (sd.Shunt != ShuntMode.None) { } sd.ExternalShuntResistance = value; } else if (value == -1D) { if (sd.Shunt != ShuntMode.None) { } sd.InternalShuntResistance = value; } else { if (sd.Shunt != ShuntMode.None) { } sd.InternalShuntResistance = value; } } break; case SHUNT_VALUE_TAG: sd.BridgeResistance = Convert.ToDouble(line2); break; case PROPORTIONAL_TO_EXCITATION_TAG: cal.IsProportional = line2 == "Y"; break; case SENSITIVITY_TAG: { string[] tokens = line2.Split(','); sensitivity = Convert.ToDouble(tokens[0]); if (tokens.Length > 1) { cal.Records.Records[0].Poly.LinearizationExponent = Convert.ToDouble(tokens[1]); } } break; case GAIN_TAG: //not stored at all? break; case EXCITATION_TAG: switch (line2) { case "5.0": sd.SupportedExcitation = new ExcitationVoltageOptions.ExcitationVoltageOption[] { ExcitationVoltageOptions.ExcitationVoltageOption.Volt5 }; cal.Records.Records[0].Excitation = ExcitationVoltageOptions.ExcitationVoltageOption.Volt5; break; case "10.0": sd.SupportedExcitation = new ExcitationVoltageOptions.ExcitationVoltageOption[] { ExcitationVoltageOptions.ExcitationVoltageOption.Volt10 }; cal.Records.Records[0].Excitation = ExcitationVoltageOptions.ExcitationVoltageOption.Volt10; break; case "0": sd.SupportedExcitation = new ExcitationVoltageOptions.ExcitationVoltageOption[] { ExcitationVoltageOptions.ExcitationVoltageOption.Undefined }; cal.Records.Records[0].Excitation = ExcitationVoltageOptions.ExcitationVoltageOption.Undefined; break; case "2.5": sd.SupportedExcitation = new ExcitationVoltageOptions.ExcitationVoltageOption[] { ExcitationVoltageOptions.ExcitationVoltageOption.Volt2_5 }; cal.Records.Records[0].Excitation = ExcitationVoltageOptions.ExcitationVoltageOption.Volt2_5; break; case "2.0": sd.SupportedExcitation = new ExcitationVoltageOptions.ExcitationVoltageOption[] { ExcitationVoltageOptions.ExcitationVoltageOption.Volt2 }; cal.Records.Records[0].Excitation = ExcitationVoltageOptions.ExcitationVoltageOption.Volt2; break; case "3.0": sd.SupportedExcitation = new ExcitationVoltageOptions.ExcitationVoltageOption[] { ExcitationVoltageOptions.ExcitationVoltageOption.Volt3 }; cal.Records.Records[0].Excitation = ExcitationVoltageOptions.ExcitationVoltageOption.Volt3; break; } break; case ENG_UNIT_TAG: sd.DisplayUnit = line2; break; case SOFTWARE_FILTER_TAG: sd.Filter = new FilterClass(Convert.ToDouble(line2)); break; case INVERT_DATA_TAG: switch (line2) { case "1": sd.Invert = true; break; case "0": sd.Invert = false; break; default: throw new InvalidDataException(INVERT_DATA_TAG + " " + line2); } break; case ZERO_REFERENCE_TAG: switch (line2) { case "0": //sd.OriginalZeroMethod = ZeroMethodType.AverageOverTime; cal.ZeroMethods = new ZeroMethods(new ZeroMethod(ZeroMethodType.AverageOverTime, defaultAveWindowStart, defaultAveWindowStop)); break; case "1": //sd.OriginalZeroMethod = ZeroMethodType.UsePreEventDiagnosticsZero; cal.ZeroMethods = new ZeroMethods(new ZeroMethod(ZeroMethodType.UsePreEventDiagnosticsZero, defaultAveWindowStart, defaultAveWindowStop)); break; case "2": //sd.OriginalZeroMethod = ZeroMethodType.None; cal.ZeroMethods = new ZeroMethods(new ZeroMethod(ZeroMethodType.None, defaultAveWindowStart, defaultAveWindowStop)); //sd.Zero = new ZeroMethod( ZeroMethodType.UseZeroMv, _defaultAveZeroStart, _defaultAveZeroStop); break; default: throw new InvalidDataException(ZERO_REFERENCE_TAG + " " + line2); } break; case DESIRED_MAX_RANGE_TAG: sd.Capacity = Convert.ToDouble(line2); break; case CALIBRATION_DATE_TAG: { string[] tokens = line2.Split('_'); if (tokens.Length == 3) { cal.CalibrationDate = new DateTime(Convert.ToInt32(tokens[2]), Convert.ToInt32(tokens[0]), Convert.ToInt32(tokens[1])); cal.ModifyDate = DateTime.Now; } } break; case REMOVE_NATURAL_OFFSET_TAG: cal.RemoveOffset = line2 == "Y"; break; case INITIAL_EU_VALUE_TAG: cal.InitialOffsets = new InitialOffsets(new InitialOffset(Convert.ToDouble(line2))); //sd.InitialEU = Convert.ToDouble(line2); break; case SENSOR_ID_TYPE_TAG: //always DALLAS break; case SENSOR_ID_NUMBER_TAG: sd.EID = line2; if (line2 == EMPTY_SENSORID_TAG) { sd.EID = ""; } break; case ISO_CODE_TAG: sd.ISOCode = line2; if (line2 == EMPTY_ISO_CODE) { sd.ISOCode = ""; } break; case SENSOR_CATEGORY_TAG: sd.SensorCategory = Convert.ToInt32(line2); break; default: if (line1.Contains(SOFTWARE_VERSION_TAG)) { //ignored for now } else { throw new InvalidDataException("bad sif data: " + line1 + "-" + line2); } break; } line1 = sr.ReadLine(); line2 = sr.ReadLine(); } sr.Close(); } } private void CreateDirectoryIfMissing(DirectoryInfo di) { if (!di.Parent.Exists) { CreateDirectoryIfMissing(di.Parent); } if (!di.Exists) { di.Create(); } } #region Model functions /*public void Add(SensorModel newModel) { ModelsDirty = true; SensorModelCollection.GetSensorModels().AddSensorModel(newModel); } */ /*public void Delete(SensorModel model) { if(model == null) { // "SensorDBTables.Delete(SensorModel): model is null" throw new ArgumentException(Strings.SensorDBTables_Delete_SensorModel_Err1); } if(string.IsNullOrEmpty(model.Model)) { // "SensorDBTables.Delete(SensorModel): model.Model is null" throw new ArgumentException(Strings.SensorDBTables_Delete_SensorModel_Err2); } ModelsDirty = true; SensorModelCollection.GetSensorModels().DeleteSensorModel(model); } */ /// /// Update the data for this sensor model. If it doesn't exist, we'll add it /// /// The new sensor model data /*public void Update(SensorModel model) { SensorModelCollection.GetSensorModels().UpdateSensorModel(model); ModelsDirty = true; }*/ /* public SensorModel[] GetModelsByManufacturer(string manufacturer) { return SensorModelCollection.GetSensorModels().GetSensorModelsForManufacturer(manufacturer); } */ /* public string[] GetUniqueManufacturers() { return SensorModelCollection.GetSensorModels().GetUniqueManufacturers(); } */ #endregion #region Data functions public static SensorData CreateDefaultSensor(double defaultAveStart, double defaultAveEnd) { SensorData sensor = new SensorData(); sensor.Bridge = SensorConstants.BridgeType.FullBridge; sensor.BridgeLegMode = BridgeLeg.First; sensor.BridgeResistance = 100; sensor.Capacity = 0; sensor.CheckOffset = false; sensor.Comment = ""; sensor.Created = DateTime.Now; sensor.ExternalShuntResistance = 0; sensor.Filter = new FilterClass(FilterClassType.CFC1000); sensor.EID = ""; //sensor.InitialEU = 0; sensor.InternalShuntResistance = 0; sensor.Invert = false; sensor.ISOCode = ""; sensor.DisplayUnit = ""; sensor.Model = ""; sensor.OffsetToleranceLow = SensorConstants.DefaultBridgeOffsetMVTolLow; sensor.OffsetToleranceHigh = SensorConstants.DefaultBridgeOffsetMVTolHigh; //sensor.OffsetTolerance = new LowHigh(-100, 100); sensor.SerialNumber = ""; sensor.Shunt = ShuntMode.None; sensor.CalSignal = false; sensor.Status = SensorStatus.Available; sensor.TimesUsed = 0; sensor.UserSerialNumber = ""; sensor.DiagnosticsMode = false; sensor.UserValue1 = ""; sensor.UserValue2 = ""; sensor.UserValue3 = ""; sensor.CouplingMode = SensorConstants.CouplingModes.DC; sensor.CheckCalibrationSignal = false; return sensor; } public SensorData[] GetAllSensors() { if (null == Sensors) { return new SensorData[0]; } var sensors = from sensor in Sensors.Elements(SensorData.SENSOR_TAG) where SensorData.IsValid(sensor) //orderby (string)sensor.Element(SensorData.SensorXMLFields.SerialNumber.ToString()) select new SensorData(sensor); List list = new List(sensors.ToArray()); list.Sort(); return list.ToArray(); } #endregion #region Calibration functions /* public void Add(SensorCalibration newCal) { if(newCal == null) { // "SensorDBTables.Add(SensorCalibration): newCal is null" throw new ArgumentException(Strings.SensorDBTables_Add_SensorCalibration_Err1); } if(string.IsNullOrEmpty(newCal.SerialNumber)) { // "SensorDBTables.Add(SensorCalibration): newCal.SerialNumber is null" throw new ArgumentException(Strings.SensorDBTables_Add_SensorCalibration_Err2); } // make sure the sensor serial number exist var sensors = GetRawSensorsBySerialNumber(newCal.SerialNumber); if(sensors == null || sensors.Count() == 0) { // "SensorDBTables.Add(SensorCalibration): newCal.SerialNumber({0}) doesn't exist" throw new ArgumentException(string.Format(Strings.SensorDBTables_Add_SensorCalibration_Err3, newCal.SerialNumber)); } // looks good, add it Calibrations.Add(newCal.ToXElement()); CalibrationsDirty = true; }*/ /* public void Delete(String serialNumber) { if (null == serialNumber) { throw new ArgumentException(Strings.SensorDBTables_Delete_SensorCalibration_Err2); } XElement [] xes = GetRawCalibrationsBySerialNumber(serialNumber); if (null != xes && xes.Length > 0) { foreach (XElement xe in xes) { xe.Remove(); } } CalibrationsDirty = true; } */ /* public void Delete(SensorCalibration calib) { if(calib == null) { // "SensorDBTables.Delete(SensorCalibration): calib is null" throw new ArgumentException(Strings.SensorDBTables_Delete_SensorCalibration_Err1); } if(string.IsNullOrEmpty(calib.SerialNumber)) { // "SensorDBTables.Delete(SensorCalibration): calib.SerialNumber is null" throw new ArgumentException(Strings.SensorDBTables_Delete_SensorCalibration_Err2); } var foundCals = GetRawCalibrationsBySerialNumberAndDate(calib.SerialNumber, calib.CalibrationDate); // first check if we found something if(foundCals == null || foundCals.Count() == 0) { // no, consider it deleted return; } // OK, delete this one foreach(var xe in foundCals) { xe.Remove(); } CalibrationsDirty = true; } */ /* /// /// Update the data for this sensor. If it doesn't exist, we'll add it /// /// The new sensor calibration data public void Update(SensorCalibration calib) { if(calib == null) { // "SensorDBTables.Update(SensorCalibration): calib is null" throw new ArgumentException(Strings.SensorDBTables_Update_SensorCalibration_Err1); } if(string.IsNullOrEmpty(calib.SerialNumber)) { // "SensorDBTables.Update(SensorCalibration): calib.SerialNumber is null" throw new ArgumentException(Strings.SensorDBTables_Update_SensorCalibration_Err2); } var foundCals = GetRawCalibrationsBySerialNumberAndDate(calib.SerialNumber, calib.CalibrationDate); // first check if we found something if(foundCals == null || foundCals.Count() == 0) { // no, we'll add it Add(calib); return; } // if we got more than 1 it's trouble if(foundCals.Count() > 1) { // SensorDBTables.Update(SensorCalibration): Calibrations table is corrupt, there's more than one entry with same SerialNumber and date throw new System.Exception(Strings.SensorDBTables_Update_SensorCalibration_Err3); } // OK, update this one foreach(var xe in foundCals) { // replace all except serial number and date (our keys) xe.SetElementValue(SensorCalibration.DocumentIDTag, calib.DocumentID); xe.SetElementValue(SensorCalibration.ExcitationTag, calib.Excitation.ToString()); xe.SetElementValue(SensorCalibration.MeasurementUnitTag, calib.MeasurementUnit); xe.SetElementValue(SensorCalibration.SensitivityTag, calib.Sensitivity); xe.SetElementValue(SensorCalibration.UsernameTag, calib.Username); xe.SetElementValue(SensorCalibration.ZmoTag, calib.Zmo); xe.SetElementValue(SensorCalibration.PolyTag, calib.Poly.ToSerializeString()); } CalibrationsDirty = true; } */ /* protected XElement[] GetRawCalibrationsBySerialNumber(string sensorSerNo) { var cals = from cal in Calibrations.Elements(SensorCalibration.CalibrationTag) where ((string)cal.Element(SensorCalibration.SerialNumberTag)).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) select cal; return cals.ToArray(); } */ /* protected IEnumerable GetRawCalibrationsBySerialNumberAndDate(string sensorSerNo, DateTime ts) { var cals = from cal in Calibrations.Elements(SensorCalibration.CalibrationTag) where ((string)cal.Element(SensorCalibration.SerialNumberTag)).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) && (DateTime)cal.Element(SensorCalibration.CalibrationDateTag) == ts select cal; return cals; } */ public SensorCalibration[] GetAllCalibrations() { var cals = from cal in Calibrations.Elements(SensorCalibration.CALIBRATION_TAG) select new SensorCalibration(cal); return cals.ToArray(); } /* public SensorCalibration[] GetCalibrationsBySerialNumber(string sensorSerNo) { var cals = from cal in Calibrations.Elements(SensorCalibration.CalibrationTag) where ((string)cal.Element(SensorCalibration.XMLFields.SerialNumber.ToString())).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) orderby (DateTime)cal.Element(SensorCalibration.XMLFields.Date.ToString()) select new SensorCalibration(cal); return cals.ToArray(); } public SensorCalibration GetLatestCalibrationBySerialNumberSafe(string sensorSerNo) { var cals = from cal in Calibrations.Elements(SensorCalibration.CalibrationTag) where ((string)cal.Element(SensorCalibration.XMLFields.SerialNumber.ToString())).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) orderby (DateTime)cal.Element(SensorCalibration.XMLFields.Date.ToString()) descending select new SensorCalibration(cal); if (null == cals || cals.Count() == 0) { return null; } return cals.First(); } public SensorCalibration GetLatestCalibrationBySerialNumber(string sensorSerNo) { var cals = from cal in Calibrations.Elements(SensorCalibration.CalibrationTag) where ((string)cal.Element(SensorCalibration.XMLFields.SerialNumber.ToString())).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) orderby (DateTime)cal.Element(SensorCalibration.XMLFields.Date.ToString()) descending select new SensorCalibration(cal); if (null == cals || cals.Count() == 0) { throw new EntryNotFoundException("no calibrations for " + sensorSerNo); } return cals.First(); } */ /* public double GetLatestSensitivityBySerialNumber(string sensorSerNo) { var cals = from cal in Calibrations.Elements(SensorCalibration.CalibrationTag) where ((string)cal.Element(SensorCalibration.SerialNumberTag)).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) orderby (DateTime)cal.Element(SensorCalibration.CalibrationDateTag) descending select double.Parse((string)cal.Element(SensorCalibration.SensitivityTag), InvariantCulture); if (cals == null || cals.Count() == 0) { throw new EntryNotFoundException(string.Format(Strings.SensorDBTables_GetLatestSensitivityBySerialNumber_Err1, sensorSerNo)); } return cals.First(); } */ /* public double? GetLatestSensitivityBySerialNumberSafe(string sensorSerNo) { var cals = from cal in Calibrations.Elements(SensorCalibration.CalibrationTag) where ((string)cal.Element(SensorCalibration.SerialNumberTag)).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) orderby (DateTime)cal.Element(SensorCalibration.CalibrationDateTag) descending select double.Parse((string)cal.Element(SensorCalibration.SensitivityTag), InvariantCulture); if (cals == null || cals.Count() == 0) { return null; } return cals.First(); } */ /* public string GetLatestPolyBySerialNumberSafe(string sensorSerNo) { try { var cals = from cal in Calibrations.Elements(SensorCalibration.CalibrationTag) where ((string)cal.Element(SensorCalibration.SerialNumberTag)).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) orderby (DateTime)cal.Element(SensorCalibration.CalibrationDateTag) descending select cal.Element(SensorCalibration.PolyTag); if (cals == null || cals.Count() == 0) { return null; } return (string)(cals.First()); } catch (System.Exception) { return null; } } */ /* public SensorCalibration GetCalibrationBySerialNumberAndDate(string sensorSerNo, DateTime ts) { var cals = from cal in Calibrations.Elements(SensorCalibration.CalibrationTag) where ((string)cal.Element(SensorCalibration.SerialNumberTag)).Equals(sensorSerNo, StringComparison.OrdinalIgnoreCase) && (DateTime)cal.Element(SensorCalibration.CalibrationDateTag) == ts select new SensorCalibration(cal); // make sure we only got one if(cals != null && cals.Count() > 1) { // "SensorDBTables.GetCalibrationBySerialNumberAndDate: Duplicate entries for {0} and {1}" throw new System.Exception(string.Format(Strings.SensorDBTables_GetCalibrationBySerialNumberAndDate_Err1, sensorSerNo, ts.ToString("o"))); } if(cals.Count() == 0) return null; return cals.ToArray()[0]; } */ #endregion } }