init
This commit is contained in:
813
DataPRO/SensorDB/SensorCalibration.cs
Normal file
813
DataPRO/SensorDB/SensorCalibration.cs
Normal file
@@ -0,0 +1,813 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using System.Data;
|
||||
using System.ComponentModel;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Storage;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using LinearizationFormula = DTS.Common.Classes.Sensors.LinearizationFormula;
|
||||
|
||||
namespace DTS.SensorDB
|
||||
{
|
||||
public class SensorCalibration : SensorCalDbRecord, IComparable<SensorCalibration>, ISensorCalibration
|
||||
{
|
||||
|
||||
public long CalVersion { get; set; } = long.MinValue;
|
||||
|
||||
public string EngineeringUnits
|
||||
{
|
||||
get => Records.Records[0].EngineeringUnits;
|
||||
}
|
||||
|
||||
internal const string TOP_LEVEL_TAG = "Calibrations";
|
||||
internal const string CALIBRATION_TAG = "Calibration";
|
||||
|
||||
public enum XMLFields
|
||||
{
|
||||
Version,
|
||||
SerialNumber,
|
||||
Date,
|
||||
Sensitivity,
|
||||
Username,
|
||||
DocumentID,
|
||||
MeasurementUnit,
|
||||
Excitation,
|
||||
Zmo,
|
||||
Poly
|
||||
}
|
||||
public bool SimpleEquals(SensorCalibration sc)
|
||||
{
|
||||
if (null == sc) { return false; }
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case Fields.CalibrationDate: if (sc.CalibrationDate.Date != CalibrationDate.Date) { return false; } break;
|
||||
case Fields.CalibrationRecords: if (!sc.Records.Records[0].IsEqual(Records.Records[0], this)) { return false; } break;
|
||||
case Fields.IRTraccCalculationType: if (sc.IRTraccCalculationType != IRTraccCalculationType) { return false; } break;
|
||||
case Fields.IsProportional: if (sc.IsProportional != IsProportional) { return false; } break;
|
||||
case Fields.InitialOffsets: if (!sc.InitialOffsets.Equals(InitialOffsets)) { return false; } break; // FB5429
|
||||
case Fields.LocalOnly: if (sc.LocalOnly != LocalOnly) { return false; } break;
|
||||
case Fields.NonLinear: if (sc.NonLinear != NonLinear) { return false; } break;
|
||||
case Fields.RemoveOffset: if (sc.RemoveOffset != RemoveOffset) { return false; } break;
|
||||
case Fields.SerialNumber: if (sc.SerialNumber != SerialNumber) { return false; } break;
|
||||
case Fields.ModifyDate: break;
|
||||
case Fields.Username: break;
|
||||
case Fields.SensitivityInspection: break;
|
||||
case Fields.ZeroMethods: if (!sc.ZeroMethods.Equals(ZeroMethods)) { return false; } break;
|
||||
case Fields.CertificationDocuments: /*if (!sc.CertificationDocuments.SequenceEqual(CertificationDocuments)) { return false; }*/
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("SensorCalibration::Equals Unknown field " + field.ToString());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is SensorCalibration sc)
|
||||
{
|
||||
var fields = Enum.GetValues(typeof(Fields)).Cast<Fields>().ToArray();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case Fields.CalibrationDate: if (sc.CalibrationDate.Date != CalibrationDate.Date) { return false; } break;
|
||||
case Fields.CalibrationRecords: if (!sc.Records.IsEqual(Records, this)) { return false; } break;
|
||||
case Fields.IRTraccCalculationType: if (sc.IRTraccCalculationType != IRTraccCalculationType) { return false; } break;
|
||||
case Fields.IsProportional: if (sc.IsProportional != IsProportional) { return false; } break;
|
||||
case Fields.InitialOffsets: if (!sc.InitialOffsets.Equals(InitialOffsets)) { return false; } break; // FB5429
|
||||
case Fields.LocalOnly: if (sc.LocalOnly != LocalOnly) { return false; } break;
|
||||
case Fields.ModifyDate: if (sc.ModifyDate != ModifyDate) { return false; } break;
|
||||
case Fields.NonLinear: if (sc.NonLinear != NonLinear) { return false; } break;
|
||||
case Fields.RemoveOffset: if (sc.RemoveOffset != RemoveOffset) { return false; } break;
|
||||
case Fields.SerialNumber: if (sc.SerialNumber != SerialNumber) { return false; } break;
|
||||
case Fields.Username: break;
|
||||
case Fields.SensitivityInspection: break;
|
||||
case Fields.ZeroMethods: if (!sc.ZeroMethods.Equals(ZeroMethods)) { return false; } break;
|
||||
case Fields.CertificationDocuments:
|
||||
if (!sc.CertificationDocuments.SequenceEqual(CertificationDocuments)) { return false; }
|
||||
break;
|
||||
case Fields.UsageCount: break; //Don't consider Usage Count when comparing, so it gets set to 0
|
||||
default:
|
||||
throw new NotSupportedException("SensorCalibration::Equals Unknown field " + field);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return base.Equals(obj);
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public string UUID { get; set; } = "";
|
||||
|
||||
public string LinearAddedValues
|
||||
{
|
||||
get
|
||||
{
|
||||
if (LinearAdded)
|
||||
{
|
||||
var records = new CalibrationRecords(Records);
|
||||
var methods = new ZeroMethods(ZeroMethods);
|
||||
var offsets = new InitialOffsets(InitialOffsets);
|
||||
|
||||
records.Records = records.Records.Where(record => record != records.Records[0]).ToArray();
|
||||
methods.Methods = new ZeroMethod[] { methods.Methods[1] };
|
||||
return records.ToSerializedString(this) + SensorConstants.LinearValuesSeparator + methods.ToSerializedString() + SensorConstants.LinearValuesSeparator + offsets.ToSerializedString();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
public double LinearAddedSensitivity
|
||||
{
|
||||
get
|
||||
{
|
||||
if (LinearAdded)
|
||||
{
|
||||
var records = new CalibrationRecords(Records);
|
||||
|
||||
records.Records = records.Records.Where(record => record != records.Records[0]).ToArray();
|
||||
return records.Records[0].Sensitivity;
|
||||
}
|
||||
return 0D;
|
||||
}
|
||||
}
|
||||
public ICalibrationRecord[] LinearAddedRecords
|
||||
{
|
||||
get
|
||||
{
|
||||
var records = new CalibrationRecords(Records);
|
||||
|
||||
if (LinearAdded)
|
||||
{
|
||||
records.Records = records.Records.Where(record => record != records.Records[0]).ToArray();
|
||||
return records.Records;
|
||||
}
|
||||
return records.Records;
|
||||
}
|
||||
}
|
||||
public ZeroMethodType LinearAddedZeroMethodType
|
||||
{
|
||||
get
|
||||
{
|
||||
var methods = new ZeroMethods(ZeroMethods);
|
||||
var zeroMethods = new ZeroMethod[] { methods.Methods[1] };
|
||||
return zeroMethods[0].Method;
|
||||
}
|
||||
}
|
||||
public double LinearAddedZeroMethodEnd
|
||||
{
|
||||
get
|
||||
{
|
||||
var methods = new ZeroMethods(ZeroMethods);
|
||||
var zeroMethods = new ZeroMethod[] { methods.Methods[1] };
|
||||
return zeroMethods[0].End;
|
||||
}
|
||||
}
|
||||
public double LinearAddedZeroMethodStart
|
||||
{
|
||||
get
|
||||
{
|
||||
var methods = new ZeroMethods(ZeroMethods);
|
||||
var zeroMethods = new ZeroMethod[] { methods.Methods[1] };
|
||||
return zeroMethods[0].Start;
|
||||
}
|
||||
}
|
||||
|
||||
public double GetPolynomialEU(double inputmV, double excitation)
|
||||
{
|
||||
return Records.Records[0].Poly.GetLinearizedValue(inputmV, excitation);
|
||||
}
|
||||
/// <summary>
|
||||
/// inserts a sensor calibration into the db
|
||||
/// </summary>
|
||||
/// <param name="bChangeModifyDate"></param>
|
||||
/// <param name="sensor"></param>
|
||||
/// <param name="bSetLatestCalibrationId">whether to set the given sensor's latest calibration
|
||||
/// id to the calibration when committing</param>
|
||||
internal void Insert(bool bChangeModifyDate, SensorData sensor, bool bSetLatestCalibrationId = false)
|
||||
{
|
||||
if (bChangeModifyDate)
|
||||
{
|
||||
ModifyDate = DateTime.Now;
|
||||
}
|
||||
_ = DbOperations.SensorCalibrationsInsert(this, sensor.GetSensorType(), bSetLatestCalibrationId);
|
||||
}
|
||||
|
||||
public void CopyValues(ISensorCalibration icopy)
|
||||
{
|
||||
var copy = (SensorCalibration)icopy;
|
||||
CalibrationDate = copy.CalibrationDate;
|
||||
Records = new CalibrationRecords(copy.Records);
|
||||
IsProportional = copy.IsProportional;
|
||||
LocalOnly = copy.LocalOnly;
|
||||
ModifyDate = copy.ModifyDate;
|
||||
NonLinear = copy.NonLinear;
|
||||
RemoveOffset = copy.RemoveOffset;
|
||||
SerialNumber = copy.SerialNumber;
|
||||
Username = copy.Username;
|
||||
ZeroMethods = new ZeroMethods(copy.ZeroMethods);
|
||||
InitialOffsets = new InitialOffsets(copy.InitialOffsets);
|
||||
CertificationDocuments = new string[copy.CertificationDocuments.Length];
|
||||
CalibrationNote = copy.CalibrationNote;
|
||||
UsageCount = copy.UsageCount;
|
||||
copy.CertificationDocuments.CopyTo(CertificationDocuments, 0);
|
||||
|
||||
OnPropertyChanged(ALL_FIELDS);
|
||||
}
|
||||
|
||||
public const string ALL_FIELDS = "AllFields";
|
||||
|
||||
public static SensorCalibration GetLatestCalibrationBySerialNumber(SensorData sd)
|
||||
{
|
||||
return SensorCalibrationList.GetLatestCalibrationBySerialNumber(sd);
|
||||
}
|
||||
|
||||
public static SensorCalibration NewDigitalSC(string units)
|
||||
{
|
||||
var sc = new SensorCalibration
|
||||
{
|
||||
RemoveOffset = false,
|
||||
CalibrationDate = DateTime.Now.Date,
|
||||
IsProportional = false,
|
||||
LocalOnly = false,
|
||||
NonLinear = false
|
||||
};
|
||||
sc.Records.Records[0].Sensitivity = 1;
|
||||
sc.Records.Records[0].EngineeringUnits = units;
|
||||
sc.Records.Records[0].Excitation = ExcitationVoltageOptions.ExcitationVoltageOption.Volt5;
|
||||
sc.ZeroMethods = new ZeroMethods(new[] { new ZeroMethod(ZeroMethodType.None, 0, 0) });
|
||||
return sc;
|
||||
}
|
||||
|
||||
public static SensorCalibration NewEmbeddedSC(string units)
|
||||
{
|
||||
//TODO: REMOVE THIS HACK
|
||||
//and put in proper variables / gets from device
|
||||
var sc = new SensorCalibration
|
||||
{
|
||||
RemoveOffset = true,
|
||||
CalibrationDate = DateTime.Now.Date,
|
||||
IsProportional = false,
|
||||
LocalOnly = false,
|
||||
NonLinear = false
|
||||
};
|
||||
sc.Records.Records[0].Sensitivity = 1;
|
||||
sc.Records.Records[0].EngineeringUnits = units;
|
||||
sc.Records.Records[0].Excitation = ExcitationVoltageOptions.ExcitationVoltageOption.Volt5;
|
||||
sc.ZeroMethods = new ZeroMethods(new[] { new ZeroMethod(ZeroMethodType.None, 0, 0) });
|
||||
return sc;
|
||||
}
|
||||
public static SensorCalibration GetLatestCalibrationBySerialNumberAndExcitation(SensorData sd, ExcitationVoltageOptions.ExcitationVoltageOption exc)
|
||||
{
|
||||
return SensorCalibrationList.GetLatestCalibrationBySerialNumberAndExcitation(sd, exc);
|
||||
}
|
||||
|
||||
public static SensorCalibration GetLatestCalibrationsBySerialNumberAndCalDate(string ser, DateTime calDate)
|
||||
{
|
||||
return SensorCalibrationList.GetLatestCalibrationsBySerialNumberAndCalDate(ser, calDate);
|
||||
}
|
||||
public static SensorCalibration GetLatestCalibrationsBySerialNumberCalDateAndModifyDate(string ser, DateTime calDate, DateTime modifyDate)
|
||||
{
|
||||
return SensorCalibrationList.GetLatestCalibrationsBySerialNumberCalDateAndModifyDate(ser, calDate, modifyDate);
|
||||
}
|
||||
|
||||
public static SensorCalibration[] GetCalibrationsBySerialNumber(SensorData sd)
|
||||
{
|
||||
return SensorCalibrationList.GetCalibrationsBySerialNumber(sd);
|
||||
}
|
||||
|
||||
#region Data Fields
|
||||
|
||||
private string _documentId = "";
|
||||
public string DocumentID
|
||||
{
|
||||
get => _documentId;
|
||||
set => SetProperty(ref _documentId, value, "DocumentID");
|
||||
}
|
||||
|
||||
public NonLinearStyles IRTraccCalculationType
|
||||
{
|
||||
get => Records.Records[0].Poly.NonLinearStyle;
|
||||
set => Records.Records[0].Poly.NonLinearStyle = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//private ZeroMethods _zeroMethods;
|
||||
public new ZeroMethods ZeroMethods
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == base.ZeroMethods || !base.ZeroMethods.Methods.Any())
|
||||
{
|
||||
// FB12764: Defaults in SensorConstants
|
||||
base.ZeroMethods = new ZeroMethods() { Methods = new ZeroMethod[] { new ZeroMethod(SensorConstants.DefaultZeroMethodType, SensorConstants.DefaultZeroMethodStart, SensorConstants.DefaultZeroMethodEnd) } };
|
||||
}
|
||||
try
|
||||
{
|
||||
if (NonLinear)
|
||||
{
|
||||
switch (Records.Records[0].Poly.NonLinearStyle)
|
||||
{
|
||||
case NonLinearStyles.IRTraccAverageOverTime: base.ZeroMethods.Methods[0].Method = ZeroMethodType.AverageOverTime; break;
|
||||
case NonLinearStyles.IRTraccDiagnosticsZero: base.ZeroMethods.Methods[0].Method = ZeroMethodType.UsePreEventDiagnosticsZero; break;
|
||||
case NonLinearStyles.IRTraccZeroMMmV: base.ZeroMethods.Methods[0].Method = ZeroMethodType.None; break;
|
||||
case NonLinearStyles.IRTraccCalFactor: base.ZeroMethods.Methods[0].Method = ZeroMethodType.None; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
return base.ZeroMethods;
|
||||
}
|
||||
set => base.ZeroMethods = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected const int CURRENT_VERSION = 1;
|
||||
|
||||
public SensorCalibration()
|
||||
{
|
||||
if (!NonLinear || LinearAdded) return;
|
||||
Records.Records[0].Sensitivity = 1D;
|
||||
//FB 29728 Don't set it to false, user can make the selection
|
||||
// IsProportional = false;
|
||||
RemoveOffset = false;
|
||||
}
|
||||
public enum Fields
|
||||
{
|
||||
CalibrationDate,
|
||||
CalibrationRecords,
|
||||
IsProportional,
|
||||
LocalOnly,
|
||||
ModifyDate,
|
||||
NonLinear,
|
||||
RemoveOffset,
|
||||
SerialNumber,
|
||||
Username,
|
||||
ZeroMethods,
|
||||
InitialOffsets,
|
||||
CertificationDocuments,
|
||||
IRTraccCalculationType,
|
||||
SensitivityInspection,
|
||||
UsageCount
|
||||
}
|
||||
private void CommonInit()
|
||||
{
|
||||
if (!NonLinear || LinearAdded) return;
|
||||
Records.Records[0].Sensitivity = 1D;
|
||||
//FB 29728 Don't set it to false, user can make the selection
|
||||
// IsProportional = false;
|
||||
RemoveOffset = false;
|
||||
}
|
||||
public SensorCalibration(string s)
|
||||
{
|
||||
FromSerializedString(s);
|
||||
CommonInit();
|
||||
}
|
||||
public SensorCalibration(ISensorCalDbRecord record) : base(record)
|
||||
{
|
||||
CommonInit();
|
||||
}
|
||||
|
||||
public SensorCalibration(IDataReader dr, int actualDbVersion) : base(dr, actualDbVersion)
|
||||
{
|
||||
CommonInit();
|
||||
}
|
||||
public SensorCalibration(DataRow dr)
|
||||
{
|
||||
try
|
||||
{
|
||||
CalibrationDate = Convert.ToDateTime(dr[DbOperations.SensorDB.SensorCalibrationFields.CalibrationDate.ToString()]);
|
||||
CalibrationId = Convert.ToInt32(dr[DbOperations.SensorDB.SensorCalibrationFields.SensorCalibrationId.ToString()]);
|
||||
LocalOnly = Convert.ToBoolean(dr[DbOperations.SensorDB.SensorCalibrationFields.LocalOnly.ToString()]);
|
||||
SerialNumber = (string)dr[DbOperations.SensorDB.SensorCalibrationFields.SerialNumber.ToString()];
|
||||
Username = (string)dr[DbOperations.SensorDB.SensorCalibrationFields.Username.ToString()];
|
||||
Records = new CalibrationRecords((string)dr[DbOperations.SensorDB.SensorCalibrationFields.CalibrationRecords.ToString()]);
|
||||
NonLinear = Convert.ToBoolean(dr[DbOperations.SensorDB.SensorCalibrationFields.NonLinear.ToString()]);
|
||||
IsProportional = Convert.ToBoolean(dr[DbOperations.SensorDB.SensorCalibrationFields.IsProportional.ToString()]);
|
||||
ModifyDate = Convert.ToDateTime(dr[DbOperations.SensorDB.SensorCalibrationFields.ModifyDate.ToString()]);
|
||||
CertificationDocuments = ((string)dr[DbOperations.SensorDB.SensorCalibrationFields.CertificationDocuments.ToString()]).Split(new[] { CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None).ToArray();
|
||||
RemoveOffset = Convert.ToBoolean(dr[DbOperations.SensorDB.SensorCalibrationFields.RemoveOffset.ToString()]);
|
||||
ZeroMethods = new ZeroMethods((string)dr[DbOperations.SensorDB.SensorCalibrationFields.ZeroMethod.ToString()]);
|
||||
InitialOffsets = new InitialOffsets((string)dr[DbOperations.SensorDB.SensorCalibrationFields.InitialOffset.ToString()]);
|
||||
|
||||
//this is downright silly, but because the linearization formula marks itself valid when it deserializes with data in it, we go and correct it here.
|
||||
Records.Records[0].Poly.MarkValid(NonLinear);
|
||||
|
||||
if (!NonLinear || LinearAdded) return;
|
||||
Records.Records[0].Sensitivity = 1D;
|
||||
IsProportional = false;
|
||||
RemoveOffset = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Failed to process Sensor Calibration record", ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// serializes to a string
|
||||
/// primarily used by sensor models, which only have one calibration entry
|
||||
/// sensors on the other hand have many and serialize to rows in a db table
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ToSerializedString()
|
||||
{
|
||||
var fields = Enum.GetValues(typeof(DbOperations.SensorDB.SensorCalibrationFields)).Cast<DbOperations.SensorDB.SensorCalibrationFields>().ToArray();
|
||||
|
||||
if (CalibrationDate.Year < 1960) { CalibrationDate = DateTime.Now.Date; }
|
||||
var substrings = new List<string>();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationDate: substrings.Add(CalibrationDate.Date.ToFileTimeUtc().ToString(System.Globalization.CultureInfo.InvariantCulture)); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationRecords: substrings.Add(Records.ToSerializedString(this)); break;
|
||||
//case DbOperations.SensorDB.SensorCalibrationFields.IRTraccCalculationType: substrings.Add(IRTraccCalculationType.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.IsProportional: substrings.Add(IsProportional.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.LocalOnly: substrings.Add(LocalOnly.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.ModifyDate: substrings.Add(DateTime.Now.ToFileTimeUtc().ToString(System.Globalization.CultureInfo.InvariantCulture)); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.NonLinear: substrings.Add(NonLinear.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.RemoveOffset: substrings.Add(RemoveOffset.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SerialNumber: substrings.Add(SerialNumber); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.Username: substrings.Add(Username); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.ZeroMethod: substrings.Add(ZeroMethods.ToSerializedString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.InitialOffset: substrings.Add(InitialOffsets.ToSerializedString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CertificationDocuments:
|
||||
{
|
||||
List<string> docs = new List<string>();
|
||||
foreach (var d in CertificationDocuments) { docs.Add(d); }
|
||||
substrings.Add(string.Join(System.Globalization.CultureInfo.InvariantCulture.TextInfo.ListSeparator, docs.ToArray()));
|
||||
}
|
||||
break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SensorCalibrationId: substrings.Add(CalibrationId?.ToString() ?? INVALID_CALIBRATION_ID.ToString()); break; //FB16002: follow the import/export pattern for strings as in XML
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.UsageCount: substrings.Add(UsageCount.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SensitivityInspection:
|
||||
try
|
||||
{
|
||||
substrings.Add(((int)SensitivityInspection).ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.LogException(ex);
|
||||
}
|
||||
break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationNote: substrings.Add(CalibrationNote); break;
|
||||
default: throw new NotSupportedException("SensorCalibration::ToSerializedString unknown field: " + field.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (var i = 0; i < substrings.Count; i++)
|
||||
{
|
||||
substrings[i] = substrings[i]?.Replace(CultureInfo.InvariantCulture.TextInfo.ListSeparator, SEPARATOR_REPLACEMENT);
|
||||
}
|
||||
return string.Join(CultureInfo.InvariantCulture.TextInfo.ListSeparator, substrings.ToArray());
|
||||
}
|
||||
public void FromSerializedString(string s)
|
||||
{
|
||||
var fields = Enum.GetValues(typeof(DbOperations.SensorDB.SensorCalibrationFields)).Cast<DbOperations.SensorDB.SensorCalibrationFields>().ToArray();
|
||||
var tokens = s.Split(new[] { CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None);
|
||||
|
||||
for (var i = 0; i < tokens.Length && i < fields.Length; i++)
|
||||
{
|
||||
var field = fields[i];
|
||||
var token = tokens[i].Replace(SEPARATOR_REPLACEMENT, CultureInfo.InvariantCulture.TextInfo.ListSeparator);
|
||||
switch (field)
|
||||
{
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationDate: CalibrationDate = DateTime.FromFileTimeUtc(Convert.ToInt64(token)); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SensorCalibrationId:
|
||||
//FB16002: follow the import/export pattern for strings as in XML
|
||||
if (int.TryParse(token, NumberStyles.Any, CultureInfo.InvariantCulture, out int iTemp))
|
||||
{
|
||||
if (iTemp == INVALID_CALIBRATION_ID) { CalibrationId = null; }
|
||||
else
|
||||
{
|
||||
CalibrationId = iTemp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CalibrationId = null;
|
||||
}
|
||||
break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationRecords: Records = new CalibrationRecords(token); break;
|
||||
//case DbOperations.SensorDB.SensorCalibrationFields.IRTraccCalculationType: IRTraccCalculationType = (SensorModel.IRTraccFormats)Enum.Parse(typeof(SensorModel.IRTraccFormats), token);break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.IsProportional: IsProportional = Convert.ToBoolean(token); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.LocalOnly: LocalOnly = Convert.ToBoolean(token); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.ModifyDate: ModifyDate = DateTime.FromFileTimeUtc(Convert.ToInt64(token)); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.NonLinear: NonLinear = Convert.ToBoolean(token); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.RemoveOffset: RemoveOffset = Convert.ToBoolean(token); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SerialNumber: SerialNumber = token; break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.Username: Username = token; break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.ZeroMethod: ZeroMethods = new ZeroMethods(token); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.InitialOffset: InitialOffsets = new InitialOffsets(token); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CertificationDocuments: CertificationDocuments = token.Split(new[] { CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.UsageCount: UsageCount = Convert.ToInt32(token); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SensitivityInspection:
|
||||
try
|
||||
{
|
||||
SensitivityInspection = (SensitivityInspectionType)Convert.ToInt32(token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.LogException(ex);
|
||||
}
|
||||
break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationNote: CalibrationNote = token; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public const string SEPARATOR_REPLACEMENT = "__SC__";
|
||||
public SensorCalibration(ISensorCalibration iSensorCalibration)
|
||||
{
|
||||
var sc = (SensorCalibration)iSensorCalibration;
|
||||
_serialNumber = sc.SerialNumber;
|
||||
_userName = sc.Username;
|
||||
_calibrationDate = sc.CalibrationDate;
|
||||
ModifyDate = sc.ModifyDate;
|
||||
NonLinear = sc.NonLinear;
|
||||
IsProportional = sc.IsProportional;
|
||||
Records = new CalibrationRecords(sc.Records);
|
||||
RemoveOffset = sc.RemoveOffset;
|
||||
ZeroMethods = new ZeroMethods(sc.ZeroMethods);
|
||||
InitialOffsets = new InitialOffsets(sc.InitialOffsets);
|
||||
CertificationDocuments = sc.CertificationDocuments;
|
||||
CalibrationId = sc.CalibrationId;
|
||||
//43152
|
||||
SensitivityInspection = sc.SensitivityInspection;
|
||||
//43141 added note property
|
||||
CalibrationNote = sc.CalibrationNote;
|
||||
UsageCount = sc.UsageCount;
|
||||
}
|
||||
|
||||
internal SensorCalibration(XElement elem)
|
||||
{
|
||||
var tableName = SensorDBTables.CalibrationTableFilename;
|
||||
int ver;
|
||||
try
|
||||
{
|
||||
ver = (int)elem.Element(XMLFields.Version.ToString());
|
||||
}
|
||||
catch (ArgumentNullException)
|
||||
{
|
||||
throw new Exception("SensorData: Can't find version tag in DB file");
|
||||
}
|
||||
if (ver != CURRENT_VERSION)
|
||||
{
|
||||
throw new Exception(string.Format(Strings.SensorData_Ctor_Err1, CURRENT_VERSION, ver));
|
||||
}
|
||||
|
||||
SensorDBBase.GetValue(elem, XMLFields.SerialNumber.ToString(), out _serialNumber, null, tableName);
|
||||
SensorDBBase.GetValue(elem, XMLFields.Date.ToString(), out _calibrationDate, SerialNumber, tableName);
|
||||
SensorDBBase.GetValue(elem, XMLFields.Sensitivity.ToString(), out double sensitivity, SerialNumber, tableName);
|
||||
Records.Records[0].Sensitivity = sensitivity;
|
||||
|
||||
var poly = "";
|
||||
try { SensorDBBase.GetValueSafe(elem, XMLFields.Poly.ToString(), out poly, SerialNumber, tableName); }
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
Records.Records[0].Poly = new LinearizationFormula();
|
||||
if (!string.IsNullOrWhiteSpace(poly))
|
||||
{
|
||||
Records.Records[0].Poly.FromSerializeString(poly);
|
||||
NonLinear = true;
|
||||
}
|
||||
SensorDBBase.GetValue(elem, XMLFields.MeasurementUnit.ToString(), out string mu, SerialNumber, tableName);
|
||||
Array.ForEach(Records.Records, record => record.EngineeringUnits = mu); //FB16398: set units on all records, not just first
|
||||
SensorDBBase.GetValue(elem, XMLFields.Username.ToString(), out _userName, SerialNumber, tableName);
|
||||
SensorDBBase.GetValueSafe(elem, XMLFields.DocumentID.ToString(), out _documentId, SerialNumber, tableName);
|
||||
if (null == _documentId) { _documentId = string.Empty; }
|
||||
if (!NonLinear) return;
|
||||
Records.Records[0].Sensitivity = 1D;
|
||||
IsProportional = false;
|
||||
}
|
||||
|
||||
public int CompareTo(SensorCalibration other)
|
||||
{
|
||||
if (null == other) { return 1; }
|
||||
if (Equals(this, other)) { return 0; }
|
||||
if (CalibrationDate.Date != other.CalibrationDate.Date)
|
||||
return other.CalibrationDate.CompareTo(CalibrationDate);
|
||||
var modifyCompare = other.ModifyDate.CompareTo(ModifyDate);
|
||||
return 0 == modifyCompare ? other.CalVersion.CompareTo(CalVersion) : modifyCompare;
|
||||
}
|
||||
|
||||
private string BuildLinearDisplayString(ICalibrationRecord[] records, ExcitationVoltageOptions.ExcitationVoltageOption excitation, string linearFormat, bool iepe = false)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var dSensitivity = 0D;
|
||||
if (ExcitationVoltageOptions.ExcitationVoltageOption.Undefined == excitation
|
||||
|| !IsProportional)
|
||||
{
|
||||
dSensitivity = records[0].Sensitivity;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var r in records)
|
||||
{
|
||||
if (r.Excitation != excitation) continue;
|
||||
dSensitivity = r.Sensitivity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var sensUnits = string.Empty;
|
||||
switch (records[0].SensitivityUnits)
|
||||
{
|
||||
case SensorConstants.SensUnits.mV: sensUnits = " mV"; break;
|
||||
case SensorConstants.SensUnits.mVperEU: sensUnits = " mV/EU"; break;
|
||||
case SensorConstants.SensUnits.mVperV: sensUnits = " mV/V"; break;
|
||||
case SensorConstants.SensUnits.mVperVperEU: sensUnits = " mV/V/EU"; break;
|
||||
}
|
||||
|
||||
if (iepe)
|
||||
{
|
||||
sensUnits = " mV/EU";
|
||||
}
|
||||
sb.Append(string.Concat(dSensitivity.ToString(linearFormat), sensUnits));
|
||||
if (IsProportional)
|
||||
{
|
||||
if (ExcitationVoltageOptions.ExcitationVoltageOption.Undefined != excitation)
|
||||
{
|
||||
var excitationString = string.Empty;
|
||||
switch (excitation)
|
||||
{
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt1: excitationString = "1V"; break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt10: excitationString = "10V"; break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt2: excitationString = "2V"; break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt2_5: excitationString = "2.5V"; break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt3: excitationString = "3V"; break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt5: excitationString = "5V"; break;
|
||||
}
|
||||
sb.Append($" ({excitationString})");
|
||||
}
|
||||
}
|
||||
|
||||
if (records[0].AtCapacity)
|
||||
{
|
||||
sb.Append($" @({records[0].CapacityOutputIsBasedOn}EU)");
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public string ToDisplayString(ExcitationVoltageOptions.ExcitationVoltageOption excitation,
|
||||
string linearFormat,
|
||||
string nonlinearFormat,
|
||||
bool iepe)
|
||||
{
|
||||
if (NonLinear && !iepe)
|
||||
{
|
||||
return Records.Records[0].Poly.ToDisplayString(nonlinearFormat);
|
||||
}
|
||||
return BuildLinearDisplayString(Records.Records, excitation, linearFormat, iepe);
|
||||
}
|
||||
|
||||
public string ToLinearDisplayString(ExcitationVoltageOptions.ExcitationVoltageOption excitation, string linearFormat, bool iepe)
|
||||
{
|
||||
if (NonLinear && !iepe)
|
||||
{
|
||||
if (LinearAdded)
|
||||
{
|
||||
//build linear string from remaining records after the poly record.
|
||||
return BuildLinearDisplayString(Records.Records.Where(record => record != Records.Records[0]).ToArray(), excitation, linearFormat);
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
return ToDisplayString(excitation, linearFormat, null, iepe);
|
||||
}
|
||||
|
||||
public string ToNonLinearDisplayString(string nonlinearFormat, bool iepe)
|
||||
{
|
||||
if (!NonLinear) return string.Empty;
|
||||
return ToDisplayString(ExcitationVoltageOptions.ExcitationVoltageOption.Undefined, null, nonlinearFormat, iepe);
|
||||
}
|
||||
public void ReadXML(System.Xml.XmlElement root)
|
||||
{
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (node is System.Xml.XmlElement) { ProcessXmlElement(node as System.Xml.XmlElement); }
|
||||
}
|
||||
}
|
||||
private void ProcessXmlElement(System.Xml.XmlElement node)
|
||||
{
|
||||
if (!Enum.TryParse(node.Name, out DbOperations.SensorDB.SensorCalibrationFields field)) return;
|
||||
switch (field)
|
||||
{
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationDate: CalibrationDate = DateTime.Parse(node.InnerText, CultureInfo.InvariantCulture); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationRecords: Records = new CalibrationRecords(node.InnerText); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CertificationDocuments: CertificationDocuments = new string[0]; break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.IsProportional: IsProportional = Convert.ToBoolean(node.InnerText); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.LocalOnly: LocalOnly = Convert.ToBoolean(node.InnerText); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.ModifyDate: ModifyDate = DateTime.Parse(node.InnerText, CultureInfo.InvariantCulture); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.NonLinear: NonLinear = Convert.ToBoolean(node.InnerText); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.RemoveOffset: RemoveOffset = Convert.ToBoolean(node.InnerText); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SerialNumber: SerialNumber = node.InnerText; break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.Username: Username = node.InnerText; break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.ZeroMethod: ZeroMethods = new ZeroMethods(node.InnerText); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.InitialOffset: InitialOffsets = new InitialOffsets(node.InnerText); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SensorCalibrationId:
|
||||
if (int.TryParse(node.InnerText, NumberStyles.Any, CultureInfo.InvariantCulture, out int iTemp))
|
||||
{
|
||||
if (iTemp == INVALID_CALIBRATION_ID) { CalibrationId = null; }
|
||||
else
|
||||
{
|
||||
CalibrationId = iTemp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
APILogger.Log($"possible error in sensor calibration id: {node.InnerText}");
|
||||
CalibrationId = null;
|
||||
}
|
||||
break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.UsageCount: UsageCount = Convert.ToInt32(node.InnerText, CultureInfo.InvariantCulture); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationNote: CalibrationNote = node.InnerText; break;
|
||||
//FB 43267
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SensitivityInspection:
|
||||
try
|
||||
{
|
||||
SensitivityInspection = (SensitivityInspectionType)Convert.ToInt32(node.InnerText, CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.LogException(ex);
|
||||
}
|
||||
|
||||
break;
|
||||
default: throw new NotSupportedException("SensorCalibration::ProcessXMLElement unsupported tag: " + field);
|
||||
}
|
||||
}
|
||||
|
||||
private const int INVALID_CALIBRATION_ID = -1;
|
||||
public void WriteXML(ref System.Xml.XmlWriter writer)
|
||||
{
|
||||
writer.WriteStartElement("SensorCalibration");
|
||||
|
||||
var fields = Enum.GetValues(typeof(DbOperations.SensorDB.SensorCalibrationFields)).Cast<DbOperations.SensorDB.SensorCalibrationFields>().ToArray();
|
||||
|
||||
foreach (var f in fields)
|
||||
{
|
||||
writer.WriteStartElement(f.ToString());
|
||||
switch (f)
|
||||
{
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationDate: writer.WriteString(CalibrationDate.ToString(CultureInfo.InvariantCulture)); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationRecords: writer.WriteString(Records.ToSerializedString(this)); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CertificationDocuments: writer.WriteString(""); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.IsProportional: writer.WriteString(IsProportional.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.LocalOnly: writer.WriteString(LocalOnly.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.ModifyDate: writer.WriteString(ModifyDate.ToString(CultureInfo.InvariantCulture)); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.NonLinear: writer.WriteString(NonLinear.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.RemoveOffset: writer.WriteString(RemoveOffset.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SerialNumber: writer.WriteString(SerialNumber); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.Username: writer.WriteString(Username); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.ZeroMethod: writer.WriteString(ZeroMethods.ToSerializedString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.InitialOffset: writer.WriteString(InitialOffsets.ToSerializedString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SensorCalibrationId:
|
||||
if (null != CalibrationId)
|
||||
{
|
||||
writer.WriteString(((int)CalibrationId).ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteString(INVALID_CALIBRATION_ID.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.UsageCount: writer.WriteString(UsageCount.ToString()); break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.SensitivityInspection:
|
||||
try
|
||||
{
|
||||
writer.WriteString(((int)SensitivityInspection).ToString());
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
APILogger.LogException(ex);
|
||||
}
|
||||
break;
|
||||
case DbOperations.SensorDB.SensorCalibrationFields.CalibrationNote: writer.WriteString(CalibrationNote.ToString()); break;
|
||||
default: throw new NotSupportedException("SensorCalibration::WriteXML unsupported field: " + f);
|
||||
}
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
public bool IsCompatibleWithIEPE()
|
||||
{
|
||||
if (IsProportional) { return false; }
|
||||
return !NonLinear;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user