using DTS.Common.Classes.Groups; using DTS.Common.Enums.Sensors; using DTS.Common.Import.Enums; using DTS.Common.Interface.Channels; using DTS.Common.SharedResource.Strings; using DTS.Common.Storage; using DTS.SensorDB; using DTS.Slice.Users; using System; using System.Collections.Generic; using System.Linq; namespace DTS.Common.Import.Persist { public class SaveCsvSourceSensor : SaveVariantBase { public bool ImportFirstUseDate { get; set; } = false; public bool ImportNewSensorsOnly { get; set; } public User CurrentUser { get; set; } private readonly SaveSensor _saveSensor; public SaveCsvSourceSensor(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func isCancelled = null) : base(importObject, persistCalculator, importNotification, isCancelled) { _saveSensor = new SaveSensor(importObject, persistCalculator, importNotification, isCancelled); } public override void Save() { _importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingSensors, PossibleStatus = PossibleStatus.Importing }); Dictionary oldSensorDatabaseIdToNew = new Dictionary(); _saveSensor.MapOldSensorDatabaseIdToNew(ref oldSensorDatabaseIdToNew); _saveSensor.UpdateSensorsWithUpdatedSensitivityUnits(); SaveCsv(oldSensorDatabaseIdToNew); _importObject.AssignOldSensorDatabaseIdToNew(oldSensorDatabaseIdToNew); } private void SaveCsv(Dictionary oldSensorDatabaseIdToNew) { var calibrationLookup = new Dictionary>(); foreach (var sc in _importObject.Calibrations().OrderBy(cal => cal.ModifyDate)) { if (IsCancelled()) { return; } if (!calibrationLookup.ContainsKey(sc.SerialNumber)) { calibrationLookup[sc.SerialNumber] = new List(); } calibrationLookup[sc.SerialNumber].Add(sc); _persistCalculator.AddDone(); _importNotification.SetProgress(_persistCalculator.ProgressValue); } //FB 35530 Clean cache SensorCalibrationList.ClearCachedCalibrations(); //Merge your sensor cals var sm = new SensorMerge(CurrentUser, _importObject.Sensors().ToList(), calibrationLookup, oldSensorDatabaseIdToNew); sm.PerformWork(); } } public class SaveNonCsvSourceSensor : SaveVariantBase { public bool ImportFirstUseDate { get; set; } = false; public bool ImportNewSensorsOnly { get; set; } public User CurrentUser { get; set; } private readonly SaveSensor _saveSensor; public SaveNonCsvSourceSensor(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func isCancelled = null) : base(importObject, persistCalculator, importNotification, isCancelled) { _saveSensor = new SaveSensor(importObject, persistCalculator, importNotification, isCancelled); } public override void Save() { _importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingSensors, PossibleStatus = PossibleStatus.Importing }); Dictionary oldSensorDatabaseIdToNew = new Dictionary(); _saveSensor.MapOldSensorDatabaseIdToNew(ref oldSensorDatabaseIdToNew); MapOldSensorDatabaseIdToNewNonCsv(ref oldSensorDatabaseIdToNew); _saveSensor.UpdateSensorsWithUpdatedSensitivityUnits(); SaveNonCsv(); _importObject.AssignOldSensorDatabaseIdToNew(oldSensorDatabaseIdToNew); } public void MapOldSensorDatabaseIdToNewNonCsv(ref Dictionary oldSensorDatabaseIdToNew) { foreach (var s in _importObject.Sensors()) { if (IsCancelled()) { return; } var oldId = s.DatabaseId; SensorsCollection.SensorsList.Commit(CurrentUser.UserName, s, false); if (s.DatabaseId != oldId) { oldSensorDatabaseIdToNew[oldId] = s.DatabaseId; } _persistCalculator.AddDone(); _importNotification.SetProgress(_persistCalculator.ProgressValue); } } private void SaveNonCsv() { var sensorLookup = new Dictionary(); foreach (var s in _importObject.Sensors()) { sensorLookup[s.SerialNumber] = s; } foreach (var sc in _importObject.Calibrations().OrderBy(cal => cal.ModifyDate)) { if (IsCancelled()) { return; } SensorData sensor = null; if (sensorLookup.ContainsKey(sc.SerialNumber)) { sensor = sensorLookup[sc.SerialNumber]; } if (null == sensor || sensor.IsDigitalInput() || sensor.IsDigitalOutput() || sensor.IsSquib() || sensor.IsUart() || sensor.IsStreamInput() || sensor.IsStreamOutput() || sensor.IsCan()) { //these do not store calibrations, don't try. } else if (!ImportNewSensorsOnly) { var updateCalId = false; if (sc.CalibrationId == sensor.LatestCalibrationId && null != sensor.LatestCalibrationId) { updateCalId = true; } //12488 Import Test Setup adds new sensor calibration entries every time. //check for existing calibration, if present, don't import. var existing = SensorCalibrationList.GetLatestCalibrationsBySerialNumberCalDateAndModifyDate( sc.SerialNumber, sc.CalibrationDate, sc.ModifyDate); if (null == existing) { SensorCalibrationList.Commit(sc, false, sensor, updateCalId); if (updateCalId) { sensor.LatestCalibrationId = sc.CalibrationId; } } else { //make sure the cals match //note that if we are here we have the same serial number and calibration date //however the modify date may not be exact, but should be within 1 second //to avoid failing the .Equals we need to adjust the modify date to match sc.ModifyDate = existing.ModifyDate; //now the same thing happens with Certification documents (ie [0] versus [1] = {""} if (0 == sc.CertificationDocuments.Length && existing.CertificationDocuments.Length == 1 && string.IsNullOrWhiteSpace(existing.CertificationDocuments[0])) { sc.CertificationDocuments = existing.CertificationDocuments; } if (!existing.Equals(sc)) { SensorCalibrationList.Commit(sc, false, sensor, updateCalId); if (updateCalId) { sensor.LatestCalibrationId = sc.CalibrationId; } } } } _persistCalculator.AddDone(); _importNotification.SetProgress(_persistCalculator.ProgressValue); } } } public class SaveSensor : SaveVariantBase { public bool ImportFirstUseDate { get; set; } = false; public bool ImportNewSensorsOnly { get; set; } public User CurrentUser { get; set; } public SaveSensor(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func isCancelled = null) : base(importObject, persistCalculator, importNotification, isCancelled) { } /// /// 15262 Absolute zero sensors in test setup change to ave over time after import. /// this fixes any missing zero method parameter on the channel. /// if a channel is imported from an older xml, then the zero method parameter will not be defined, /// however we don't want to let it use the default parameter (Avg over time), so we check the sensor on the /// channel to see if there is a more appropriate one /// /// public static void FixMissingZeroMethodParameter(IGroupChannel channel, IChannelSetting defaultZeroMethod, IChannelSetting defaultZeroStart, IChannelSetting defaultZeroEnd) { if (!(channel is GroupChannel groupChannel)) { return; } if (channel.SensorId > 0) { var sensor = SensorsCollection.SensorsList.GetSensorById(channel.SensorId, false); if (null == sensor) { return; } //sensor doesn't exist, forget about it //only analog support zeromethod, skip others if (sensor.IsDigitalInput() || sensor.IsDigitalOutput() || sensor.IsSquib()) { return; } var sc = sensor.GetLatestCalibration(); if (null == sc) { //ZeroMethod is stored in SC, so if there's no sc, we can't set the ZeroMethod ... return; } groupChannel.FixZeroMethodIfNeeded(defaultZeroMethod, defaultZeroStart, defaultZeroEnd, sc); } } /// /// Adds an appropriate initial offset setting if one is not present on old import by using the /// sensor calibration /// 15236 Initial offset parameter not set after test setup import /// /// /// public static void FixMissingInitialOffset(IGroupChannel channel, IChannelSetting defaultInitialOffset) { if (!(channel is GroupChannel groupChannel)) { return; } if (channel.SensorId > 0) { var sensor = SensorsCollection.SensorsList.GetSensorById(channel.SensorId, false); if (null == sensor) { return; } //sensor doesn't exist, forget about it //only analog support zeromethod, skip others if (sensor.IsDigitalInput() || sensor.IsDigitalOutput() || sensor.IsSquib()) { return; } var sc = sensor.GetLatestCalibration(); if (null == sc) { //ZeroMethod is stored in SC, so if there's no sc, we can't set the ZeroMethod ... return; } groupChannel.FixInitialOffsetIfNeeded(defaultInitialOffset, sc); } } public void MapOldSensorDatabaseIdToNew(ref Dictionary oldSensorDatabaseIdToNew) { foreach (var s in _importObject.Sensors()) { if (IsCancelled()) { return; } if (!ImportFirstUseDate) { s.LatestCalibrationId = null; s.FirstUseDate = null; } var oldId = s.DatabaseId; if (s.IsTestSpecificDigitalOutput) { var TSD_TestSpecificSensorId = SensorsCollection.SensorsList.GetSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_DIGITAL_OUT_SERIAL); oldSensorDatabaseIdToNew[oldId] = TSD_TestSpecificSensorId.DatabaseId; continue; } if (s.IsTestSpecificSquib) { var TSQ_TestSpecificSensorId = SensorsCollection.SensorsList.GetSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_SQUIB_SERIAL); oldSensorDatabaseIdToNew[oldId] = TSQ_TestSpecificSensorId.DatabaseId; continue; } if (s.IsTestSpecificDigitalIn) { var TSI_TestSpecificSensorId = SensorsCollection.SensorsList.GetSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_DIGITAL_IN_SERIAL); oldSensorDatabaseIdToNew[oldId] = TSI_TestSpecificSensorId.DatabaseId; continue; } if (s.IsTestSpecificUart) { var TSU_TestSpecificSensorId = SensorsCollection.SensorsList.GetSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_UART_SERIAL); oldSensorDatabaseIdToNew[oldId] = TSU_TestSpecificSensorId.DatabaseId; continue; } if (s.IsTestSpecificStreamOutput) { var TSS_TestSpecificSensorId = SensorsCollection.SensorsList.GetSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_STREAM_OUT_SERIAL); oldSensorDatabaseIdToNew[oldId] = TSS_TestSpecificSensorId.DatabaseId; continue; } if (s.IsTestSpecificStreamInput) { var TSS_TestSpecificSensorId = SensorsCollection.SensorsList.GetSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_STREAM_IN_SERIAL); oldSensorDatabaseIdToNew[oldId] = TSS_TestSpecificSensorId.DatabaseId; } //if (s.IsTestSpecificCan) //{ // var TSF_TestSpecificSensorId = SensorsCollection.SensorsList.GetSensorBySerialNumber(SensorConstants.TEST_SPECIFIC_CAN_SERIAL); // oldSensorDatabaseIdToNew[oldId] = TSf_TestSpecificSensorId.DatabaseId; // continue; //} } } public void UpdateSensorsWithUpdatedSensitivityUnits() { //18259 DataPRO XML and CSV imports let you import inconsistent SensitvityUnits _importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingCalibrations, PossibleStatus = PossibleStatus.Importing }); var sensorsWithUpdatedSensitivityUnits = new List(); foreach (var sc in _importObject.Calibrations()) { if (!sc.IsProportional && sc.Records.Records[0].SensitivityUnits == SensorConstants.SensUnits.mVperVperEU) { sc.Records.Records[0].SensitivityUnits = SensorConstants.SensUnits.mVperEU; if (!sensorsWithUpdatedSensitivityUnits.Contains(sc.SerialNumber)) { sensorsWithUpdatedSensitivityUnits.Add(sc.SerialNumber); } } } if (sensorsWithUpdatedSensitivityUnits.Any()) { _importObject.AddError(new ImportError { Message = $"{StringResources.SensorsUpdatedSensitivityUnits} {string.Join(", ", sensorsWithUpdatedSensitivityUnits.ToArray())}", Severity = ImportSeverityError.Warning, ContinueImportOnError = true }); } } public override void Save() { } } }