342 lines
16 KiB
C#
342 lines
16 KiB
C#
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<bool> 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<int, int> oldSensorDatabaseIdToNew = new Dictionary<int, int>();
|
|
_saveSensor.MapOldSensorDatabaseIdToNew(ref oldSensorDatabaseIdToNew);
|
|
_saveSensor.UpdateSensorsWithUpdatedSensitivityUnits();
|
|
SaveCsv(oldSensorDatabaseIdToNew);
|
|
_importObject.AssignOldSensorDatabaseIdToNew(oldSensorDatabaseIdToNew);
|
|
}
|
|
|
|
private void SaveCsv(Dictionary<int, int> oldSensorDatabaseIdToNew)
|
|
{
|
|
var calibrationLookup = new Dictionary<string, List<SensorCalibration>>();
|
|
foreach (var sc in _importObject.Calibrations().OrderBy(cal => cal.ModifyDate))
|
|
{
|
|
if (IsCancelled()) { return; }
|
|
if (!calibrationLookup.ContainsKey(sc.SerialNumber))
|
|
{
|
|
calibrationLookup[sc.SerialNumber] = new List<SensorCalibration>();
|
|
}
|
|
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<bool> 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<int, int> oldSensorDatabaseIdToNew = new Dictionary<int, int>();
|
|
_saveSensor.MapOldSensorDatabaseIdToNew(ref oldSensorDatabaseIdToNew);
|
|
MapOldSensorDatabaseIdToNewNonCsv(ref oldSensorDatabaseIdToNew);
|
|
_saveSensor.UpdateSensorsWithUpdatedSensitivityUnits();
|
|
SaveNonCsv();
|
|
_importObject.AssignOldSensorDatabaseIdToNew(oldSensorDatabaseIdToNew);
|
|
}
|
|
|
|
public void MapOldSensorDatabaseIdToNewNonCsv(ref Dictionary<int, int> 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<string, SensorData>();
|
|
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<bool> isCancelled = null) :
|
|
base(importObject, persistCalculator, importNotification, isCancelled)
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
/// <param name="group"></param>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
/// <param name="channel"></param>
|
|
/// <param name="defaultInitialOffset"></param>
|
|
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<int, int> 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<string>();
|
|
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()
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|