Files
2026-04-17 14:55:32 -04:00

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()
{
}
}
}