using System; using System.Collections.Generic; using System.Linq; using System.Text; using DTS.Common.Utilities.Logging; namespace DTS.SensorDB { public class MeasurementUnit { private string _mainDisplayUnit; public string MainDisplayUnit { get { return _mainDisplayUnit; } set { _mainDisplayUnit = value; } } private string[] _alternateDisplayUnits; public string[] AlternateDisplayUnits { get { return _alternateDisplayUnits; } set { _alternateDisplayUnits = value; } } private string _dimension = "00"; public string Dimension { get { return _dimension; } set { _dimension = value; } } public MeasurementUnit(string mainUnit, string[] alternateUnits, MeasurementUnit.UnitConversion[] conversions, string dimension) { MainDisplayUnit = mainUnit; AlternateDisplayUnits = alternateUnits; UnitConversions = conversions; Dimension = dimension; } public MeasurementUnit(System.Xml.XmlElement node) { foreach (var childnode in node.ChildNodes) { System.Xml.XmlElement elem = childnode as System.Xml.XmlElement; if (null == elem) { continue; } try { switch (elem.Name) { case "MainDisplayUnit": MainDisplayUnit = elem.InnerText; break; case "AlternateDisplayUnits": { var nodes = elem.GetElementsByTagName("String"); List aunits = new List(); foreach (var node2 in nodes) { System.Xml.XmlElement element = node2 as System.Xml.XmlElement; if (null == element) { continue; } try { aunits.Add(element.InnerText); } catch (System.Exception) { } } AlternateDisplayUnits = aunits.ToArray(); } break; case "Dimension": { Dimension = elem.InnerText; } break; case "UnitConversions": { var nodes = elem.GetElementsByTagName("UnitConversion"); foreach (var node2 in nodes) { System.Xml.XmlElement element = node2 as System.Xml.XmlElement; if (null == element) { continue; } try { _unitConversions.Add(new UnitConversion(element)); } catch (System.Exception) { } } } break; default: System.Diagnostics.Trace.WriteLine("didn't handle " + elem.Name); break; } } catch (System.Exception ex) { APILogger.Log("Failed to parse xml", ex, elem.Name, elem.Value); } } } public bool UnitMatches(string unit) { unit = unit.Trim().ToLower(); if (MainDisplayUnit.ToLower() == unit) { return true; } foreach (string aunit in AlternateDisplayUnits) { if (aunit.ToLower() == unit) { return true; } } return false; } public double GetScalerConversion(string newUnit) { return 1D; //6194 disable display units for the short term //if (UnitMatches(newUnit)) { return 1D; } //foreach (var uc in UnitConversions) //{ // if (uc.UnitMatches(newUnit)) { return uc.Scaler; } //} //throw new InvalidCastException(string.Format("No conversion available from {0} to {1}", newUnit, MainDisplayUnit)); } public double GetScalerConversionFrom(string oldUnit) { return 1D; //6194 disable display units for the short term //if (UnitMatches(oldUnit)) { return 1D; } //foreach (var uc in UnitConversions) //{ // if (uc.UnitMatches(oldUnit)) { return 1D / uc.Scaler; } //} //throw new InvalidCastException(string.Format("No conversion available from {0} to {1}", oldUnit, MainDisplayUnit)); } private List _unitConversions = new List(); public UnitConversion[] UnitConversions { get { return _unitConversions.ToArray(); } set { if (null == value) { return; } _unitConversions = new List(value); } } public class UnitConversion { private string _unit; public string Unit { get { return _unit; } set { _unit = value; } } private double _scaler; public double Scaler { get { return _scaler; } set { _scaler = value; } } public bool UnitMatches(string unit) { return (Unit.ToLower() == unit.Trim().ToLower()); } public void WriteToXML(System.Xml.XmlWriter writer) { writer.WriteStartElement("UnitConversion"); DTS.DASLib.Service.XMLHelper.PutString(writer, "Unit", Unit); DTS.DASLib.Service.XMLHelper.PutDouble(writer, "Scaler", Scaler); writer.WriteEndElement(); } public UnitConversion(string unit, double scaler) { Unit = unit; Scaler = scaler; } public UnitConversion(System.Xml.XmlElement node) { foreach (var childnode in node.ChildNodes) { System.Xml.XmlElement elem = childnode as System.Xml.XmlElement; if (null == elem) { continue; } try { switch (elem.Name) { case "Unit": Unit = elem.InnerText; break; case "Scaler": Scaler = double.Parse(elem.InnerText, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture); break; default: System.Diagnostics.Trace.WriteLine("didn't handle " + elem.Name); break; } } catch (System.Exception ex) { APILogger.Log("Failed to parse xml", ex, elem.Name, elem.Value); } } } } public void WriteToXML(System.Xml.XmlWriter writer) { writer.WriteStartElement("MeasurementUnit"); DTS.DASLib.Service.XMLHelper.PutString(writer, "MainDisplayUnit", MainDisplayUnit); DTS.DASLib.Service.XMLHelper.PutString(writer, "Dimension", Dimension); writer.WriteStartElement("AlternateDisplayUnits"); foreach (var unit in AlternateDisplayUnits) { writer.WriteStartElement("String"); writer.WriteValue(unit); writer.WriteEndElement(); } writer.WriteEndElement(); //DTS.DASLib.Service.XMLHelper.PutString(writer, "AlternateDisplayUnits", string.Join("×", AlternateDisplayUnits)); writer.WriteStartElement("UnitConversions"); foreach (var uc in UnitConversions) { uc.WriteToXML(writer); } writer.WriteEndElement(); writer.WriteEndElement(); } public override string ToString() { return MainDisplayUnit; } } public class MeasurementUnitList { private static MeasurementUnitList _instance; private static object MyLock = new object(); private Dictionary _units = new Dictionary(); private MeasurementUnit[] GetAllUnits() { return _units.Values.ToArray(); } public static MeasurementUnit[] GetAllMeasurementUnits() { lock (MyLock) { if (null == _instance) { _instance = new MeasurementUnitList(); } return _instance.GetAllUnits(); } } public static MeasurementUnit GetMeasurementUnit(string key) { lock (MyLock) { return new MeasurementUnit(key, null, null, null); } } private MeasurementUnitList() { LoadAllMeasurementUnits(); } public void SaveToXML() { StringBuilder sb = new StringBuilder(); System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings(); settings.OmitXmlDeclaration = false; settings.Indent = true; using (System.Xml.XmlWriter xmlWriter = System.Xml.XmlTextWriter.Create(sb, settings)) { xmlWriter.WriteStartDocument(true); xmlWriter.WriteStartElement("MeasurementUnits"); var e1 = _units.GetEnumerator(); while (e1.MoveNext()) { e1.Current.Value.WriteToXML(xmlWriter); } xmlWriter.WriteEndElement(); xmlWriter.WriteEndDocument(); xmlWriter.Flush(); } System.IO.File.WriteAllText(FILE_NAME, sb.ToString()); } private void CreateDefaultMeasurementUnitsFile() { MeasurementUnit mu = new MeasurementUnit("g", new string[] { "g" }, new MeasurementUnit.UnitConversion[] { new MeasurementUnit.UnitConversion("m/sec^2", 9.80665D), new MeasurementUnit.UnitConversion("ft/s^2", 32.17405D)}, "AC"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("m/sec^2", new string[] { "m/sec^2", "m/s^2", "m/sec2", "m/s2" }, new MeasurementUnit.UnitConversion[] { new MeasurementUnit.UnitConversion("g", .101971621), new MeasurementUnit.UnitConversion("ft/s^2", 3.28084D), new MeasurementUnit.UnitConversion("cm/s^2", 100D)}, "AC"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("deg", new string[] { "deg", "degree", "degrees", "°" }, new MeasurementUnit.UnitConversion[0], "AN"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("Nm", new string[] { "Nm", "N -m", "N-m" }, new MeasurementUnit.UnitConversion[0], "DC"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("mm", new string[] { "mm", "M-m", "M -m" }, new MeasurementUnit.UnitConversion[0], "DC"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("deg/sec", new string[] { "deg/sec", "degrees/sec", "d/sec", "deg/s" }, new MeasurementUnit.UnitConversion[0], "AA"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("kN", new string[] { "kn", "K-n", "k -n", "kilonewton" }, new MeasurementUnit.UnitConversion[]{ new MeasurementUnit.UnitConversion("N", 1000) }, "FO"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("N", new string[] { "n", "newton" }, new MeasurementUnit.UnitConversion[]{ new MeasurementUnit.UnitConversion("kN", .001D) }, "FO"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("ft/s^2", new string[] { "ft/s2", "ft/s^2", "ft/sec^2" }, new MeasurementUnit.UnitConversion[] { new MeasurementUnit.UnitConversion("cm/s^2", 30.48D), new MeasurementUnit.UnitConversion("m/sec^2", .3048D)}, "AC"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("cm/s^2", new string[] { "cm/s^2", "cm/s2", "cm/sec^2" }, new MeasurementUnit.UnitConversion[]{ new MeasurementUnit.UnitConversion("ft/s^2", .032808D), new MeasurementUnit.UnitConversion("m/sec^2", .01D) }, "AC"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("Ampere", new string[] { "Amp", "Amper", "Amps" }, new MeasurementUnit.UnitConversion[] { new MeasurementUnit.UnitConversion("mAmp", 1000D) }, "CU"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("mAmp", new string[] { "mAmp", "m Amp", "milliampere", "milliamp" }, new MeasurementUnit.UnitConversion[]{ new MeasurementUnit.UnitConversion("Ampere", .001D)}, "CU"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("A", new string[] { "Amp", "Ampere" }, new MeasurementUnit.UnitConversion[] { new MeasurementUnit.UnitConversion("mAmp", 1000)}, "CU"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("Hz", new string[] { "hertz", "cycle/sec", "cyc/s" }, new MeasurementUnit.UnitConversion[] { new MeasurementUnit.UnitConversion("kHz", .001D)}, "FR"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("kHz", new string[] { "kHertz", "kilohertz" }, new MeasurementUnit.UnitConversion[] { new MeasurementUnit.UnitConversion("Hz", 1000D)}, "FR"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("m", new string[] { "m", "Meter" }, new MeasurementUnit.UnitConversion[] { new MeasurementUnit.UnitConversion("mm", 100D)}, "DC"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("V", new string[] { "volt", "VO" }, new MeasurementUnit.UnitConversion[] { new MeasurementUnit.UnitConversion("mV", 100D)}, "VO"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("mV", new string[] { "mv", "millivolt", "mVolt" }, new MeasurementUnit.UnitConversion[]{ new MeasurementUnit.UnitConversion("V", .001D)}, "VO"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("με", new string[] { "microstrain", "με", "micro strain" }, new MeasurementUnit.UnitConversion[0], "??"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("Pa", new string[] { "PA", "Pascal", "kg/m^2" }, new MeasurementUnit.UnitConversion[]{ new MeasurementUnit.UnitConversion("kPa", 1000D), new MeasurementUnit.UnitConversion("hPA", 100), new MeasurementUnit.UnitConversion("MPa", 1000000D)} , "??"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } mu = new MeasurementUnit("kPa", new string[] { "KPA", "kilopascal", "KiloPascal" }, new MeasurementUnit.UnitConversion[]{ new MeasurementUnit.UnitConversion("Pa", 1D/1000D)}, "??"); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } SaveToXML(); } public static bool ContainsMeasurementUnit(string unit) { lock (MyLock) { if (null == _instance) { _instance = new MeasurementUnitList(); } var units = from u in _instance.GetAllUnits() where u.UnitMatches(unit) select u; if (units.Count() > 0) { return true; } else { return false; } } } private void LoadAllMeasurementUnits() { if (!System.IO.File.Exists(FILE_NAME)) { CreateDefaultMeasurementUnitsFile(); } else { System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); string xml = System.IO.File.ReadAllText(FILE_NAME); doc.LoadXml(xml); var nodes = doc.GetElementsByTagName("MeasurementUnits"); foreach (var node in nodes) { System.Xml.XmlElement element = node as System.Xml.XmlElement; if (null == element) { continue; } foreach (var childNode in element.GetElementsByTagName("MeasurementUnit")) { System.Xml.XmlElement elem = childNode as System.Xml.XmlElement; if (null == elem) { continue; } LoadMeasurementUnit(elem); } } CreateDefaultMeasurementUnitsFile(); } } private const string FILE_NAME = "MeasurementUnits.xml"; private void LoadMeasurementUnit(System.Xml.XmlElement node) { try { MeasurementUnit mu = new MeasurementUnit(node); if (!_units.ContainsKey(mu.MainDisplayUnit)) { _units.Add(mu.MainDisplayUnit, mu); } else { _units[mu.MainDisplayUnit] = mu; } } catch (System.Exception ex) { APILogger.Log("failed to get node from measurement unit db, ", ex); } } } }