using DTS.Common.Classes.Sensors; using DTS.Common.DAS.Concepts; using DTS.Common.DataModel; using DTS.Common.Enums.Sensors; using DTS.Common.Import.Interfaces; using DTS.Common.SharedResource.Strings; using DTS.Common.Utilities.Logging; using DTS.SensorDB; using System; using System.Globalization; using System.Linq; namespace DTS.Common.Import.Parsers.CSV { [System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Acronym")] public class Version0CSVSensorParser : AbstractCSVParser { /// /// handles the Version 0 Channel name tag /// /// /// private static void HandleVersion0ChannelName(string val, ParseParameters pp) { pp.SensorData.Comment = val; if (string.IsNullOrWhiteSpace(pp.SensorData.ISOChannelName)) { pp.SensorData.ISOChannelName = val; } if (string.IsNullOrEmpty(pp.SensorData.UserChannelName)) { pp.SensorData.UserChannelName = val; } } public override int Version => 0; public override void ParseVersion(CSVImportTags.Tags field, string val, ParseParameters pp) { var sd = (SensorData)pp.SensorData; try { #region and another very long switch statement switch (field) { case CSVImportTags.Tags.Axis: break; case CSVImportTags.Tags.BRIDGE: //FB 41817 if bridge value is type don't override it, the bridge type will have a value and it will assign it later if (!string.IsNullOrWhiteSpace(val)) { pp.SensorData.Bridge = val.ToLower() == "full" ? SensorConstants.BridgeType.FullBridge : SensorConstants.BridgeType.HalfBridge; } break; case CSVImportTags.Tags.BridgeResistance: { if (!string.IsNullOrWhiteSpace(val)) { if (double.TryParse(val, NumberStyles.Any, pp.ImportCulture, out var d)) { pp.SensorData.BridgeResistance = d; } else { pp.Errors.Add(string.Format(StringResources.InvalidBridgeResistance, val)); } } } break; case CSVImportTags.Tags.BypassAAFilter: pp.SensorData.ByPassFilter = val.ToLower() == "yes"; break; case CSVImportTags.Tags.Category: { if (string.IsNullOrWhiteSpace(val)) { return; } if (int.TryParse(val, NumberStyles.Any, pp.ImportCulture, out var temp)) { pp.SensorData.SensorCategory = temp; } else { pp.Errors.Add(string.Format(StringResources.InvalidCategory, val)); } } break; case CSVImportTags.Tags.ChannelName: HandleVersion0ChannelName(val, pp); break; case CSVImportTags.Tags.CommentField: pp.SensorData.UserValue1 = val; break; case CSVImportTags.Tags.CustomerCode: pp.SensorData.UserValue2 = val; break; case CSVImportTags.Tags.DatabaseReferenceNumber: break; case CSVImportTags.Tags.DesiredRange: { if (string.IsNullOrWhiteSpace(val)) { return; } if (double.TryParse(val, NumberStyles.Any, pp.ImportCulture, out double d)) { pp.SensorData.RangeHigh = d; pp.SensorData.RangeMedium = d; pp.SensorData.RangeLow = d; } else { pp.Errors.Add(string.Format(StringResources.InvalidDesiredRange, val)); } } break; case CSVImportTags.Tags.Dimension: break; case CSVImportTags.Tags.Due: break; case CSVImportTags.Tags.DueCal: break; case CSVImportTags.Tags.EquivalentEUShuntResistor: break; case CSVImportTags.Tags.EU: { foreach (var r in pp.SensorCal.Records.Records) { r.EngineeringUnits = val;//FB16398: set units on all records, not just first } //removed dependency to unity framework //sc.Records.Records.ForEach(record => record.EngineeringUnits = val); //FB16398: set units on all records, not just first sd.DisplayUnit = val; } break; case CSVImportTags.Tags.Exc: { if (string.IsNullOrWhiteSpace(val)) { return; } if (double.TryParse(val, NumberStyles.Any, pp.ImportCulture, out var d)) { try { pp.SensorData.SupportedExcitation = new[] { Test.Module.Channel.Sensor.GetExcitationVoltageEnumFromMagnitude(d) }; } catch (Exception ex) { if (ex is NotSupportedException) { pp.Errors.Add(string.Format(StringResources.InvalidExcitation, val)); } } } else { pp.Errors.Add(string.Format(StringResources.InvalidExcitation, val)); } } break; case CSVImportTags.Tags.FilterClass: { if (string.IsNullOrWhiteSpace(val)) { return; } if (val.Contains(CFC)) { ParseFilterClassCFC(val, pp, sd); } else { ParseFilterClassInt(val, pp, sd); } } break; case CSVImportTags.Tags.FullScale: { if (string.IsNullOrWhiteSpace(val)) { return; } if (double.TryParse(val, NumberStyles.Any, pp.ImportCulture, out double d)) { pp.SensorData.Capacity = d; } else { pp.Errors.Add(string.Format(StringResources.InvalidFullScale, val)); } } break; case CSVImportTags.Tags.Group1: break; case CSVImportTags.Tags.Group2: break; case CSVImportTags.Tags.Group3: break; case CSVImportTags.Tags.Group4: break; case CSVImportTags.Tags.Group5: break; case CSVImportTags.Tags.InvertSignal: pp.SensorData.Invert = val.ToLower() == "yes"; break; case CSVImportTags.Tags.IRTRACCExponent: { if (!string.IsNullOrWhiteSpace(val)) { if (double.TryParse(val, NumberStyles.Any, pp.ImportCulture, out var d)) { if (d < 1) { pp.IrtraccExponent = d; } } else { pp.Errors.Add(string.Format(StringResources.InvalidIRTRACCExponent, val)); } } else { pp.IrtraccExponent = 1; } } break; case CSVImportTags.Tags.LaboratoryCode: pp.SensorData.UserValue3 = val; break; case CSVImportTags.Tags.LastCal: { if (string.IsNullOrWhiteSpace(val)) { return; } if (DateTime.TryParse(val, pp.ImportCulture, DateTimeStyles.AssumeLocal, out var dt)) { pp.SensorCal.CalibrationDate = dt; } else { pp.Errors.Add(string.Format(StringResources.InvalidLastCal, val)); } } break; case CSVImportTags.Tags.Location: break; case CSVImportTags.Tags.Manufacturer: pp.SensorData.Manufacturer = val; break; case CSVImportTags.Tags.Model: pp.SensorData.Model = val; break; case CSVImportTags.Tags.OffsetToleranceHigh: { if (string.IsNullOrWhiteSpace(val)) { return; } if (double.TryParse(val, NumberStyles.Any, pp.ImportCulture, out var d)) { pp.SensorData.OffsetToleranceHigh = d; } else { pp.Errors.Add(string.Format(StringResources.InvalidOffsetToleranceHigh, val)); } } break; case CSVImportTags.Tags.OffsetToleranceLow: { if (string.IsNullOrWhiteSpace(val)) { return; } if (double.TryParse(val, NumberStyles.Any, pp.ImportCulture, out var d)) { pp.SensorData.OffsetToleranceLow = d; } else { pp.Errors.Add(string.Format(StringResources.InvalidOffsetToleranceLow, val)); } } break; case CSVImportTags.Tags.OutputAtEXCFSmV: break; case CSVImportTags.Tags.PartialISOCode: sd.ISOCode = val; break; case CSVImportTags.Tags.Proportional: pp.SensorCal.IsProportional = val.ToLower() == "yes"; //Since this could get get set to False if the sensor is non-linear, save it in //case there is also a linear calibration for this sensor and set it to what is saved. pp.SavedIsProportional = pp.SensorCal.IsProportional; break; case CSVImportTags.Tags.Received: break; case CSVImportTags.Tags.RemoveOffset: pp.SensorCal.RemoveOffset = val.ToLower() == "yes"; //Since this could get get set to False if the sensor is non-linear, save it in //case there is also a linear calibration for this sensor and set it to what is saved. pp.SavedRemoveOffset = pp.SensorCal.RemoveOffset; break; case CSVImportTags.Tags.Sensitivity: { if (string.IsNullOrWhiteSpace(val)) { return; } if (double.TryParse(val, NumberStyles.Any, pp.ImportCulture, out var d)) { //13810 Sensor ID and sensitivity are degraded to scientific notation when editing if (val.ToLower().Contains("e")) { pp.Errors.Add(string.Format(StringResources.InvalidSensitivity, pp.SensorData.SerialNumber, val)); return; } pp.Sensitivity = d; //FB 41820 set sensitivity in sensor data pp.SensorData.Calibration.Records.Records[0].Sensitivity = d; } else { pp.Errors.Add(string.Format(StringResources.InvalidSensitivity, sd.SerialNumber, val)); } } break; case CSVImportTags.Tags.SensorID: //13810 Sensor ID and sensitivity are degraded to scientific notation when editing if (!string.IsNullOrWhiteSpace(val) && val.ToLower() != "none" && !val.ToLower().Contains("e+") && !val.ToLower().Contains("e-")) { pp.SensorData.EID = val; } break; case CSVImportTags.Tags.SensorSN: if (string.IsNullOrEmpty(val)) { val = string.Concat(Constants.ISO_CH_ONLY_PREFIX, Guid.NewGuid().ToString()); } if (pp.StripBackslash) { //14772 Sanitize sensor serials when performing TDC sensor import var splits = val.Split('\\'); val = splits.Last(); } pp.SensorData.SerialNumber = val; pp.SensorData.UUID = val; break; case CSVImportTags.Tags.SensorType: break; case CSVImportTags.Tags.ShuntResistorValue: break; case CSVImportTags.Tags.SoftwareZeroEquivalentEU: { if (!string.IsNullOrWhiteSpace(val)) { if (double.TryParse(val, NumberStyles.Any, pp.ImportCulture, out double d)) { pp.OriginalOffset = d; } else { pp.Errors.Add(string.Format(StringResources.InvalidZeroEquivalentEU, val)); } } } break; case CSVImportTags.Tags.SoftwareZeroReference: switch (val)// (Pre, Avg, 0mV) { case SensorDatabaseExport.ZM_STRING_DIAGNOSTICS: pp.ZeroType = ZeroMethodType.UsePreEventDiagnosticsZero; break; case SensorDatabaseExport.ZM_STRING_NONE: pp.ZeroType = ZeroMethodType.None; break; default: pp.ZeroType = ZeroMethodType.AverageOverTime; break; } break; case CSVImportTags.Tags.Tech: pp.SensorCal.Username = val; break; case CSVImportTags.Tags.Unknown: break; case CSVImportTags.Tags.UseShuntCal: sd.Shunt = val.ToLower() == "yes" ? ShuntMode.Emulation : ShuntMode.None; break; } #endregion and another very long switch statement } catch (Exception) { pp.Errors.Add(string.Format(StringResources.InvalidField, field, val)); } } private const string CFC = "CFC"; private static void ParseFilterClassCFC(string val, ParseParameters pp, SensorData sd) { try { var idx = val.IndexOf(CFC); if (0 > idx) { pp.Errors.Add(string.Format(StringResources.InvalidFilterClass, val)); return; } val = val.Substring(idx + CFC.Length); val = val.Trim(); } catch (Exception ex) { APILogger.Log(ex); } ParseFilterClassInt(val, pp, sd); } private static void ParseFilterClassInt(string val, ParseParameters pp, SensorData sd) { try { if (int.TryParse(val, NumberStyles.Any, pp.ImportCulture, out var numericFilterClassValue)) { sd.Filter = new FilterClass(FilterClass.GetFilterClassTypeFromNumericFC(numericFilterClassValue)); var fc = new FilterClass(FilterClass.GetFilterClassTypeFromNumericFC(numericFilterClassValue)); if (null != fc) { // http://manuscript.dts.local/f/cases/16440/CSV-Import-should-respect-IS // 16440 - CSV Import should respect ISO Code Filter Mapping setting if (pp.UseISOCodeFilterMapping) { sd.SetFilterAndFilterClassISO(fc, pp.UseZeroForUnfiltered, false); } else { sd.Filter = fc; } } } else { pp.Errors.Add(string.Format(StringResources.InvalidFilterClass, val)); } } catch (Exception ex) { APILogger.Log(ex); pp.Errors.Add(string.Format(StringResources.InvalidFilterClass, val)); } } } }