984 lines
45 KiB
C#
984 lines
45 KiB
C#
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<T>(ref T storage, T value, String propertyName = null)
|
|
{
|
|
if (Equals(storage, value)) return false;
|
|
|
|
storage = value;
|
|
OnPropertyChanged(propertyName);
|
|
return true;
|
|
}
|
|
protected void OnPropertyChanged(string propertyName = null)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
public 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<OutputTOMDigitalChannel> DigitalChannels { get; set; }
|
|
|
|
public DigitalChannelList(OutputTOMDigitalChannel[] channels)
|
|
{
|
|
DigitalChannels = new List<OutputTOMDigitalChannel>(channels);
|
|
}
|
|
public DigitalChannelList() { DigitalChannels = new List<OutputTOMDigitalChannel>(); }
|
|
}
|
|
[Serializable()]
|
|
public class SquibChannelList
|
|
{
|
|
public List<OutputSquibChannel> SquibChannels { get; set; }
|
|
|
|
public SquibChannelList(OutputSquibChannel[] channels)
|
|
{
|
|
SquibChannels = new List<OutputSquibChannel>(channels);
|
|
}
|
|
public SquibChannelList() { SquibChannels = new List<OutputSquibChannel>(); }
|
|
}
|
|
private List<OutputSquibChannel> _squibChannels = new List<OutputSquibChannel>();
|
|
public OutputSquibChannel[] SquibChannels
|
|
{
|
|
get { return _squibChannels.ToArray(); }
|
|
set { _squibChannels.Clear(); _squibChannels.AddRange(value); }
|
|
}
|
|
|
|
private List<OutputTOMDigitalChannel> _digitalChannels = new List<OutputTOMDigitalChannel>();
|
|
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; }
|
|
|
|
/// <summary>
|
|
/// Event generated whenever the tables are modified.
|
|
/// </summary>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
/// <param name="fileLocation"></param>
|
|
/// <param name="createIfEmpty"></param>
|
|
/// <param name="defaultElement"></param>
|
|
/// <returns></returns>
|
|
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);
|
|
}
|
|
*/
|
|
/// <summary>
|
|
/// Update the data for this sensor model. If it doesn't exist, we'll add it
|
|
/// </summary>
|
|
/// <param name="sensor">The new sensor model data</param>
|
|
/*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<SensorData> list = new List<SensorData>(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;
|
|
}
|
|
*/
|
|
/*
|
|
/// <summary>
|
|
/// Update the data for this sensor. If it doesn't exist, we'll add it
|
|
/// </summary>
|
|
/// <param name="sensor">The new sensor calibration data</param>
|
|
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<XElement> 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
|
|
}
|
|
}
|