init
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DataPROWin7.DataModel.Classes.Hardware;
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.SensorDB;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveTestSetup : SaveVariantBase
|
||||
{
|
||||
private readonly SaveCustomChannels _saveCustomChannels;
|
||||
private readonly SaveHardware _saveHardware;
|
||||
private readonly SaveGroups _saveGroups;
|
||||
public User CurrentUser { get; set; }
|
||||
//FB 38039 Get/ Set setup name used in run test
|
||||
public string TestSetupName { get; set; }
|
||||
public SaveTestSetup(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification,
|
||||
SaveCustomChannels saveCustomChannels, SaveHardware saveHardware, SaveGroups saveGroups,
|
||||
Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
_saveCustomChannels = saveCustomChannels;
|
||||
_saveHardware = saveHardware;
|
||||
_saveGroups = saveGroups;
|
||||
}
|
||||
//FB 38039 Default used for run test
|
||||
private void ConfigureDefaultRunTestTestSetup(TestTemplate TestSetup)
|
||||
{
|
||||
TestSetup.DoROIDownload = true;
|
||||
|
||||
TestSetup.ViewROIDownload = true;
|
||||
|
||||
TestSetup.DownloadAll = true;
|
||||
|
||||
TestSetup.ViewDownloadAll = true;
|
||||
|
||||
TestSetup.RequireUserConfirmationOnErrors = true;
|
||||
//FB 43757 disable upload since eqx for GM does not use upload any more
|
||||
TestSetup.UploadData = false;
|
||||
|
||||
TestSetup.ViewDiagnostics = true;
|
||||
|
||||
TestSetup.VerifyChannels = true;
|
||||
|
||||
TestSetup.ViewExport = true;
|
||||
|
||||
TestSetup.DefaultNumberRealtimeGraphs = 1;
|
||||
|
||||
TestSetup.ExportFormats = DTS.Common.Enums.SupportedExportFormatBitFlags.rdfadc;
|
||||
|
||||
TestSetup.AllowMissingSensors = false;
|
||||
|
||||
TestSetup.StrictDiagnostics = true;
|
||||
|
||||
TestSetup.AutomaticProgression = true;
|
||||
|
||||
TestSetup.DoAutoArm = false;
|
||||
|
||||
TestSetup.DoEnableRepeat = false;
|
||||
|
||||
TestSetup.DoStreaming = false;
|
||||
|
||||
TestSetup.AllowSensorIdToBlankChannel = false;
|
||||
TestSetup.AllowMissingSensors = false;
|
||||
TestSetup.SuppressMissingSensorsWarning = false;
|
||||
TestSetup.CheckListRequirePass = true;
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
var testSetups = _importObject.TestSetups();
|
||||
|
||||
if (_importObject.TestSetupImportFileFormat == ImportFileFormat.SingleTestSetup && !string.IsNullOrEmpty(TestSetupName))
|
||||
{
|
||||
//FB 38039 this test is used for run test
|
||||
var testSetup = testSetups.FirstOrDefault();
|
||||
if (testSetup == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
testSetup.Name = TestSetupName;
|
||||
testSetup.TestId = TestSetupName;
|
||||
ConfigureDefaultRunTestTestSetup(testSetup);
|
||||
}
|
||||
|
||||
Dictionary<string, string> oldIdToNewIdLookup = new Dictionary<string, string>();
|
||||
|
||||
SaveTestSetupHelper.UpdateLevelTriggers(ref oldIdToNewIdLookup, _saveCustomChannels, testSetups);
|
||||
|
||||
SaveTestSetupHelper.DeleteExistingTestSetups(testSetups, CurrentUser.UserName);
|
||||
|
||||
Dictionary<string, DASHardware> hardwareLookup = SaveTestSetupHelper.PopulateHarwareLookup();
|
||||
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingTestSetups, PossibleStatus = PossibleStatus.Importing });
|
||||
|
||||
foreach (var t in testSetups)
|
||||
{
|
||||
SaveTestSetupHelper.FixDasAff(hardwareLookup, t);
|
||||
//keep track of test id prior to commit, so that we can correct das.TestId
|
||||
//if we need to
|
||||
var idPriorToCommit = t.Id;
|
||||
t.Id = 0;
|
||||
|
||||
var allSensorsInDb = SensorsCollection.SensorsList.GetAllSensors(true);
|
||||
|
||||
foreach (var channels in t.ChannelsForGroup)
|
||||
{
|
||||
foreach (var ch in channels.Value)
|
||||
{
|
||||
if (_importObject.OldSensorDatabaseIdsToNew().ContainsKey(ch.SensorId))
|
||||
{
|
||||
ch.SensorId = _importObject.OldSensorDatabaseIdToNew(ch.SensorId);
|
||||
var match = allSensorsInDb?.FirstOrDefault(s => s.DatabaseId == ch.SensorId);
|
||||
if (null != match)
|
||||
{
|
||||
ch.SetSensorData(match, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (_saveHardware.OldDASIdToNewDASId.ContainsKey(ch.DASId))
|
||||
{
|
||||
ch.DASId = _saveHardware.OldDASIdToNewDASId[ch.DASId];
|
||||
}
|
||||
//15262 Absolute zero sensors in test setup change to ave over time after import.
|
||||
//zero method may be undefined on older imports
|
||||
//make sure we set the zero method before embedded group is committed ...
|
||||
SaveSensor.FixMissingZeroMethodParameter(ch, _saveGroups.DefaultZeroMethod, _saveGroups.DefaultZeroStart, _saveGroups.DefaultZeroEnd);
|
||||
SaveSensor.FixMissingInitialOffset(ch, _saveGroups.DefaultInitialOffset);
|
||||
}
|
||||
}
|
||||
|
||||
var hardwareIncluded = t.AddedHardware.ToList();
|
||||
var hardwareRemoved = t.RemovedHardware.ToList();
|
||||
|
||||
var listToProcess = new List<Tuple<int, int>>();
|
||||
foreach (var e in _saveHardware.OldDASIdToNewDASId)
|
||||
{
|
||||
listToProcess.Add(new Tuple<int, int>(e.Key, e.Value));
|
||||
}
|
||||
//arrange the to process by the largest new id
|
||||
listToProcess.Sort((a, b) =>
|
||||
{
|
||||
if (a == b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return b.Item2.CompareTo(a.Item2);
|
||||
});
|
||||
|
||||
foreach (var tuple in listToProcess)
|
||||
{
|
||||
if (tuple.Item1 == tuple.Item2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (hardwareIncluded.Contains(tuple.Item2))
|
||||
{
|
||||
throw new Exception("Panic, new id already in list");
|
||||
}
|
||||
|
||||
if (hardwareRemoved.Contains(tuple.Item2))
|
||||
{
|
||||
throw new Exception("Panic, new id already in list");
|
||||
}
|
||||
|
||||
if (hardwareIncluded.Contains(tuple.Item1))
|
||||
{
|
||||
hardwareIncluded.Remove(tuple.Item1);
|
||||
hardwareIncluded.Add(tuple.Item2);
|
||||
}
|
||||
|
||||
if (hardwareRemoved.Contains(tuple.Item1))
|
||||
{
|
||||
hardwareRemoved.Remove(tuple.Item1);
|
||||
hardwareRemoved.Add(tuple.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
SaveTestSetupHelper.AddHardwareFromEmbeddedGroups(t, _saveGroups, hardwareRemoved, hardwareIncluded);
|
||||
|
||||
t.ReplaceCalculatedChannel(oldIdToNewIdLookup);
|
||||
if (IsCancelled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (t.TestSetupUniqueId == null)
|
||||
{
|
||||
t.TestSetupUniqueId = Guid.NewGuid().ToString();
|
||||
}
|
||||
TestTemplateList.TestTemplatesList.Commit(t, false);
|
||||
if (idPriorToCommit > 0 && _saveHardware.TestIdToHardware.ContainsKey(idPriorToCommit))
|
||||
{
|
||||
foreach (var enumH in _saveHardware.TestIdToHardware[idPriorToCommit])
|
||||
{
|
||||
enumH.TestId = t.Id;
|
||||
enumH.Update();
|
||||
}
|
||||
}
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
|
||||
oldIdToNewIdLookup.Clear();
|
||||
|
||||
if (_importObject.Errors().Any())
|
||||
{
|
||||
//report errors
|
||||
}
|
||||
//FB 36879 Still parsing it should report as Working status
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.None, PossibleStatus = PossibleStatus.Working });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.SensorDB;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public interface ICalibrationImport
|
||||
{
|
||||
SensorCalibration AddLinearCalRecordIfNeeded(SensorCalibration sc, bool savedIsProportional, bool savedRemoveOffset);
|
||||
SensorCalibration AddLinearZeroMethodIfNeeded(SensorCalibration sc, ZeroMethodType zeroMethodType, double zeroMethodStart, double zeroMethodEnd);
|
||||
SensorCalibration CheckForExcitationCalibration(SensorCalibration sc, double sensitivity, ExcitationVoltageOptions.ExcitationVoltageOption excitation, string EU);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
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())
|
||||
{
|
||||
//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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseMMECustomFilterClasses : XMLParseBase
|
||||
{
|
||||
public XMLParseMMECustomFilterClasses(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AddCustomFilterClasses(ParseMMECustomFilterClasses(_root));
|
||||
}
|
||||
|
||||
private IEnumerable<ISO.MMEFilterClasses> ParseMMECustomFilterClasses(XmlElement root)
|
||||
{
|
||||
List<ISO.MMEFilterClasses> list = new List<ISO.MMEFilterClasses>();
|
||||
|
||||
foreach (var child in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return list; }
|
||||
if (child is XmlElement)
|
||||
{
|
||||
list.Add(ISO.MMEFilterClasses.ReadXML(child as XmlElement));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,457 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Classes.Groups.ChannelSettings;
|
||||
using DTS.Common.Classes.Groups;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Channels;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.SensorDB;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Utils;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
|
||||
public class XMLPre20ParseTestSetups : XMLParseBase
|
||||
{
|
||||
private readonly IsoViewMode _isoViewMode;
|
||||
private readonly XMLParseTestSetups _xmlParseTestSetups;
|
||||
public XMLPre20ParseTestSetups(XmlElement root, double importedVersion, IsoViewMode isoViewMode, XMLParseTestSetups xmlParseTestSetups, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_isoViewMode = isoViewMode;
|
||||
_xmlParseTestSetups = xmlParseTestSetups;
|
||||
}
|
||||
|
||||
private XmlElement MigratePre20TestTemplate(IEnumerable<TestTemplate> testTemplates, ImportObject importObject)
|
||||
{
|
||||
|
||||
_writer.WriteStartElement(TopLevelFields.TestSetups.ToString());
|
||||
foreach (var t in testTemplates)
|
||||
{
|
||||
//Migrate HardwareOverrides to HardwareIncludes and HardwareRemoves
|
||||
|
||||
//Since we're migrating an earlier version of a Test Setup export which does not have
|
||||
//a <DASList> within the <TestSetup>, change this Test Setup's <DASList><SamplesPerSecond>
|
||||
//from the Test Setup default to this Test Setup's aggregate sample rate
|
||||
//Also, initialize all DAS in the DASClockMasterList to false.
|
||||
var testSetupDAS = importObject.Hardware();
|
||||
foreach (var das in testSetupDAS)
|
||||
{
|
||||
t.DASSampleRateList[das.SerialNumber] = t.SamplesPerSecondAggregate;
|
||||
t.DASAAFRateList[das.SerialNumber] = TestTemplate.GetAAFForHardware(das, (int)t.SamplesPerSecondAggregate);
|
||||
t.DASClockMasterList[das.SerialNumber] = false;
|
||||
t.DASPTPDomainIDList[das.SerialNumber] = 0;
|
||||
}
|
||||
|
||||
//Migrate Groups
|
||||
var count = -1;
|
||||
var oldToNewChannelIds = new Dictionary<string, int>();
|
||||
|
||||
foreach (var testObject in t.TestObjectsAndAddedGroupsList)
|
||||
{
|
||||
//FB14086: Don't import channel-less groups
|
||||
if (!t.SensorLookup.ContainsKey(testObject.SerialNumber)) continue;
|
||||
IGroup newGroup = GroupHelper.CreateEmptyGroup();
|
||||
|
||||
|
||||
newGroup.StaticGroupId = GroupHelper.GetGroupId(testObject, _groupIdMapping, importObject.Groups()?.ToList());
|
||||
|
||||
newGroup.Name = testObject.SerialNumber;
|
||||
newGroup.DisplayName = testObject.DisplaySerialNumber == TestTemplate.NON_ISO_INTERNAL_GROUP_NAME
|
||||
? StringResources.TestChannels
|
||||
: testObject.DisplaySerialNumber;
|
||||
newGroup.DisplayOrder = testObject.DisplayOrder;
|
||||
newGroup.Position = testObject.Position.Position;
|
||||
newGroup.TestObject = testObject.TestObjectType;
|
||||
|
||||
//13203 DataPRO failed on XML test setup import
|
||||
//13558 Imported test setup missing included hardware.
|
||||
//Get the embedded Group's hardware
|
||||
var hardwareStringList = new List<string>();
|
||||
foreach (var serialNumber in testObject.Hardware.Select(s => s.SerialNumber))
|
||||
{
|
||||
if (!hardwareStringList.Contains(serialNumber))
|
||||
{
|
||||
hardwareStringList.Add(serialNumber);
|
||||
}
|
||||
}
|
||||
newGroup.IncludedHardwareStringList = hardwareStringList.ToArray();
|
||||
|
||||
t.Groups.Add(newGroup);
|
||||
|
||||
var groupChannelsList = new List<IGroupChannel>();
|
||||
foreach (var groupName in t.SensorLookup.Keys)
|
||||
{
|
||||
if (groupName == newGroup.Name)
|
||||
{
|
||||
var channels = t.SensorLookup[groupName];
|
||||
foreach (var channelName in channels.Keys)
|
||||
{
|
||||
var sensors = channels[channelName];
|
||||
foreach (var sensorName in sensors.Keys) //Really only 1
|
||||
{
|
||||
var groupChannel = new GroupChannel(true, newGroup.DisplayName, newGroup, new IChannelSetting[0]);
|
||||
groupChannel.IsoChannelName = channelName.StartsWith("TSD_")
|
||||
? StringResources.SensorTableControl_DigitalOutputSetting
|
||||
: channelName;
|
||||
var isoCode = sensors[sensorName].ISOCode;
|
||||
isoCode = isoCode.Remove(12, 2).Insert(12, sensors[sensorName].PhysicalDimension);
|
||||
isoCode = isoCode.Remove(14, 1).Insert(14, sensors[sensorName].Direction);
|
||||
groupChannel.IsoCode = isoCode;
|
||||
groupChannel.UserChannelName = channelName.StartsWith("TSD_")
|
||||
? StringResources.SensorTableControl_DigitalOutputSetting
|
||||
: channelName;
|
||||
groupChannel.UserCode = string.Empty;
|
||||
groupChannel.IsDisabled = false;
|
||||
|
||||
//Migrate the Settings string from the XML (0=2400,1=A, etc.)
|
||||
var settings = new List<IChannelSetting>();
|
||||
|
||||
|
||||
switch (sensors[sensorName].Bridge)
|
||||
{
|
||||
case SensorConstants.BridgeType.IEPE:
|
||||
case SensorConstants.BridgeType.QuarterBridge:
|
||||
case SensorConstants.BridgeType.HalfBridge:
|
||||
case SensorConstants.BridgeType.FullBridge:
|
||||
case SensorConstants.BridgeType.HalfBridge_SigPlus:
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.Range + 1, ChannelSettingBase.RANGE, "2400")
|
||||
{ DoubleValue = sensors[sensorName].Capacity });
|
||||
//FB 15574 use filter class instead of cfc
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.FilterClass + 1, ChannelSettingBase.FilterClass, "None,0")
|
||||
{ Value = FilterClass.GetFilterClassSettingFromFilterClass(sensors[sensorName].FilterClass) });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.Polarity + 1, ChannelSettingBase.POLARITY, "+")
|
||||
{ Value = sensors[sensorName].Invert ? "-" : "+" });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.Position + 1, ChannelSettingBase.POSITION, "?")
|
||||
{ Value = sensors[sensorName].Position });
|
||||
|
||||
//18861 When migrating from pre-2.0 add these settings
|
||||
ZeroMethod zeroMethod = sensors[sensorName].Calibration.ZeroMethods.Methods.LastOrDefault();
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.ZeroMethod + 1, ChannelSettingBase.ZEROMETHOD, "AverageOverTime")
|
||||
{ Value = zeroMethod.Method.ToString() });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.ZeroMethodStart + 1, ChannelSettingBase.ZEROMETHODSTART, "-0.05")
|
||||
{ DoubleValue = zeroMethod.Start });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.ZeroMethodEnd + 1, ChannelSettingBase.ZEROMETHODEND, "-0.02")
|
||||
{ DoubleValue = zeroMethod.End });
|
||||
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.UserValue1 + 1, ChannelSettingBase.USERVALUE1, "")
|
||||
{ Value = sensors[sensorName].UserValue1 });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.UserValue2 + 1, ChannelSettingBase.USERVALUE2, "")
|
||||
{ Value = sensors[sensorName].UserValue2 });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.UserValue3 + 1, ChannelSettingBase.USERVALUE3, "")
|
||||
{ Value = sensors[sensorName].UserValue3 });
|
||||
|
||||
InitialOffset initialOffset = sensors[sensorName].Calibration.InitialOffsets.Offsets.LastOrDefault();
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.InitialOffset + 1, ChannelSettingBase.INITIAL_OFFSET, "None,0,0")
|
||||
{ Value = $"{initialOffset.Form},{initialOffset.EU},{initialOffset.MV}" });
|
||||
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.ACCouplingEnabled + 1, ChannelSettingBase.ACCouplingEnabled, "0")
|
||||
{
|
||||
Value = "FALSE"
|
||||
});
|
||||
break;
|
||||
|
||||
case SensorConstants.BridgeType.DigitalInput:
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.DefaultValue + 1, ChannelSettingBase.DEFAULT_VALUE, "0")
|
||||
{ DoubleValue = sensors[sensorName].ScaleMultiplier.DefaultValue });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.ActiveValue + 1, ChannelSettingBase.ACTIVE_VALUE, "1")
|
||||
{ DoubleValue = sensors[sensorName].ScaleMultiplier.ActiveValue });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.DIMode + 1, ChannelSettingBase.DIMODE, "8")
|
||||
{ IntValue = (int)sensors[sensorName].InputMode });
|
||||
break;
|
||||
|
||||
case SensorConstants.BridgeType.SQUIB:
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.SQMode + 1, ChannelSettingBase.SQMODE, "1")
|
||||
{ IntValue = (int)sensors[sensorName].SquibFireMode });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.SquibDelay + 1, ChannelSettingBase.SQUIB_DELAY, "0")
|
||||
{ DoubleValue = sensors[sensorName].SquibFireDelayMS });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.SquibDuration + 1, ChannelSettingBase.SQUIB_DURATION, "100")
|
||||
{ DoubleValue = sensors[sensorName].SquibFireDurationMS });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.SquibLimitDuration + 1, ChannelSettingBase.SQUIB_LIMIT_DURATION, "1")
|
||||
{ BoolValue = sensors[sensorName].LimitSquibFireDuration });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.SquibCurrent + 1, ChannelSettingBase.SQUIB_CURRENT, "1.5")
|
||||
{ DoubleValue = sensors[sensorName].SquibOutputCurrent });
|
||||
break;
|
||||
|
||||
case SensorConstants.BridgeType.TOMDigital:
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.OutputMode + 1, ChannelSettingBase.OUTPUT_MODE, "1")
|
||||
{ IntValue = (int)sensors[sensorName].DigitalOutputMode });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.DigitalOutLimitDuration + 1, ChannelSettingBase.DIGITALOUT_LIMIT_DURATION, "1")
|
||||
{ BoolValue = sensors[sensorName].DigitalOutputLimitDuration });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.DigitalOutDuration + 1, ChannelSettingBase.DIGITALOUT_DURATION, "100")
|
||||
{ DoubleValue = sensors[sensorName].DigitalOutputDurationMS });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.DigitalOutDelay + 1, ChannelSettingBase.DIGITALOUT_DELAY, "0")
|
||||
{ DoubleValue = sensors[sensorName].DigitalOutputDelayMS });
|
||||
break;
|
||||
|
||||
case SensorConstants.BridgeType.UART:
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.UartBaudRate + 1, ChannelSettingBase.BAUD_RATE, "57600")
|
||||
{ IntValue = (int)sensors[sensorName].UartBaudRate });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.UartDataBits + 1, ChannelSettingBase.DATA_BITS, "8")
|
||||
{ IntValue = (int)sensors[sensorName].UartDataBits });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.UartStopBits + 1, ChannelSettingBase.STOP_BITS, "None")
|
||||
{ Value = sensors[sensorName].UartStopBits.ToString() });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.UartParity + 1, ChannelSettingBase.PARITY, "None")
|
||||
{ Value = sensors[sensorName].UartParity.ToString() });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.UartFlowControl + 1, ChannelSettingBase.FLOW_CONTROL, "None")
|
||||
{ Value = sensors[sensorName].UartFlowControl.ToString() });
|
||||
settings.Add(new ChannelSettingBase((int)SensorConstants.SensorSettings.UartDataFormat + 1, ChannelSettingBase.DATA_FORMAT, "Binary")
|
||||
{ Value = sensors[sensorName].UartDataFormat.ToString() });
|
||||
break;
|
||||
}
|
||||
|
||||
groupChannel.ChannelSettings = settings.ToArray();
|
||||
|
||||
foreach (var sensor in importObject.Sensors())
|
||||
{
|
||||
if (sensor.SerialNumber == sensors[sensorName].SerialNumber)
|
||||
{
|
||||
groupChannel.SetSensorData(sensors[sensorName], null);
|
||||
groupChannel.SensorId = sensor.DatabaseId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach (var hardware in importObject.Hardware())
|
||||
{
|
||||
foreach (var group in importObject.Groups())
|
||||
{
|
||||
foreach (var channel in group.GetISOTestObject().AllChannels)
|
||||
{
|
||||
var hardwareUnderscoreSplit = channel.HardwareId.Split('_');
|
||||
|
||||
if (hardwareUnderscoreSplit[0] == hardware.SerialNumber &&
|
||||
group.SerialNumber == groupChannel.Group.Name &&
|
||||
sensorName == channel.SensorSerialNumber)
|
||||
{
|
||||
groupChannel.DASId = hardware.DASId;
|
||||
var hardwareXSplit = channel.HardwareId.Split('x');
|
||||
groupChannel.DASChannelIndex = Convert.ToInt32(hardwareXSplit[1]) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var g in importObject.Groups())
|
||||
{
|
||||
if (g.SerialNumber == groupName)
|
||||
{
|
||||
foreach (var ch in g.GetISOTestObject().AllChannels)
|
||||
{
|
||||
if (ch.Name == channelName)
|
||||
{
|
||||
groupChannel.Id = count;
|
||||
var channelParts = ch.GetId().Split('_');
|
||||
groupChannel.GroupChannelOrder = Convert.ToInt32(channelParts[channelParts.Length - 1]);
|
||||
oldToNewChannelIds[ch.GetId()] = count;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
groupChannelsList.Add(groupChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
t.ChannelsForGroup[newGroup] = groupChannelsList.ToArray();
|
||||
}
|
||||
|
||||
//Migrate Graphs
|
||||
foreach (var testGraph in t.TestGraphs)
|
||||
{
|
||||
foreach (var testGraphChannel in testGraph.Channels)
|
||||
{
|
||||
foreach (var group in t.Groups)
|
||||
{
|
||||
foreach (var channel in t.ChannelsForGroup[group])
|
||||
{
|
||||
if (channel.GetChannelName(_isoViewMode) == testGraphChannel.Name)
|
||||
{
|
||||
testGraph.AddChannel(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Migrate CalculatedChannels
|
||||
foreach (var calculatedChannel in t.CalculatedChannels)
|
||||
{
|
||||
var groupChannelsList = new List<IGroupChannel>();
|
||||
foreach (var calculatedChannelInputChannel in calculatedChannel.TestObjectChannels)
|
||||
{
|
||||
foreach (var group in t.Groups)
|
||||
{
|
||||
foreach (var channel in t.ChannelsForGroup[group])
|
||||
{
|
||||
//15242 Sensors swapped on calculated channel when importing test setup.
|
||||
//use name of the channel to match between test channels and calculated input channel ...
|
||||
if (channel.GetChannelName(_isoViewMode) == calculatedChannelInputChannel.NameOfTheChannel)
|
||||
{
|
||||
groupChannelsList.Add(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
calculatedChannel.SetChannels(groupChannelsList.ToArray());
|
||||
}
|
||||
|
||||
//Migrate LevelTriggers
|
||||
foreach (var levelTrigger in t.LevelTriggerChannels.Select(l => l.Value))
|
||||
{
|
||||
foreach (var group in t.Groups)
|
||||
{
|
||||
foreach (var channel in t.ChannelsForGroup[group])
|
||||
{
|
||||
if ((channel.SensorData != null) && (channel.SensorData.SerialNumber == levelTrigger.SensorSerialNumber))
|
||||
{
|
||||
levelTrigger.GroupChannelId = channel.Id.ToString(CultureInfo.InvariantCulture);
|
||||
levelTrigger.GroupChannel = channel;
|
||||
channel.HardwareId = levelTrigger.HardwareChannelId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//first go through all groups, add any hardware from any groups in the test setup
|
||||
var addedHardwareList = new List<int>();
|
||||
var removedHardwareList = new List<int>();
|
||||
foreach (var group in t.Groups)
|
||||
{
|
||||
foreach (var h in group.IncludedHardwareStringList)
|
||||
{
|
||||
var matches = from hw in importObject.Hardware() where hw.SerialNumber == h select hw;
|
||||
if (matches.Any())
|
||||
{
|
||||
foreach (var match in matches)
|
||||
{
|
||||
if (!addedHardwareList.Contains(match.DASId))
|
||||
{
|
||||
addedHardwareList.Add(match.DASId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//finally add any hardware add/remove specific instructions
|
||||
foreach (var hardwareOverride in t.HardwareOverrides.Select(p => p.Value))
|
||||
{
|
||||
var dasId = 0;
|
||||
var dasParts = hardwareOverride.HardwareId.Split('_');
|
||||
foreach (var hardware in importObject.Hardware())
|
||||
{
|
||||
if (hardware.SerialNumber == dasParts[0])
|
||||
{
|
||||
dasId = hardware.DASId;
|
||||
if (hardwareOverride.Action == HardwareInclusionInstruction.Actions.Add)
|
||||
{
|
||||
addedHardwareList.Add(dasId);
|
||||
}
|
||||
else if (hardwareOverride.Action == HardwareInclusionInstruction.Actions.Remove)
|
||||
{
|
||||
if (addedHardwareList.Contains(dasId))
|
||||
{
|
||||
addedHardwareList.Remove(dasId);
|
||||
}
|
||||
|
||||
removedHardwareList.Add(dasId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
t.AddedHardware = addedHardwareList.ToArray();
|
||||
t.RemovedHardware = removedHardwareList.ToArray();
|
||||
t.HardwareOverrides.Clear();
|
||||
|
||||
_writer.Flush();
|
||||
t.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
}
|
||||
private IEnumerable<TestTemplate> ParsePre20TestTemplate(ImportObject importObject)
|
||||
{
|
||||
List<TestTemplate> testTemplates = new List<TestTemplate>();
|
||||
|
||||
var testobjectLookup = new Dictionary<string, TestObject>();
|
||||
|
||||
foreach (var to in importObject.Groups())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
testobjectLookup[to.SerialNumber] = to;
|
||||
}
|
||||
|
||||
var customerDetailsLookup = new Dictionary<string, ISO.CustomerDetails>();
|
||||
foreach (var c in importObject.CustomerDetails())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
customerDetailsLookup[c.Name] = c;
|
||||
}
|
||||
|
||||
var testEngineerDetailsLookup = new Dictionary<string, ISO.TestEngineerDetails>();
|
||||
foreach (var t in importObject.TestEngineerDetails())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
testEngineerDetailsLookup[t.Name] = t;
|
||||
}
|
||||
|
||||
var labDetailsLookup = new Dictionary<string, ISO.LabratoryDetails>();
|
||||
foreach (var l in importObject.LabDetails())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
labDetailsLookup[l.Name] = l;
|
||||
}
|
||||
|
||||
var sensorLookup = new Dictionary<string, SensorData>();
|
||||
foreach (var s in importObject.Sensors())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
sensorLookup[s.SerialNumber] = s;
|
||||
}
|
||||
|
||||
foreach (var node in _root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
var d = new TestTemplate();
|
||||
d.ReadXMLPre20(node as XmlElement, testobjectLookup, labDetailsLookup, customerDetailsLookup, testEngineerDetailsLookup, sensorLookup, importObject.Hardware()?.ToList());
|
||||
testTemplates.Add(d);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return testTemplates;
|
||||
}
|
||||
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
var testTemplates = ParsePre20TestTemplate(importObject);
|
||||
if (!testTemplates.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
XmlElement newRoot = MigratePre20TestTemplate(testTemplates, importObject);
|
||||
if (newRoot == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
importObject.AddTestSetups(_xmlParseTestSetups.ParseTestTemplate(importObject, newRoot));
|
||||
//FB 38039,40758 Identify test setup type
|
||||
importObject.TestSetupImportFileFormat = importObject.GetImportFileFormat();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseCustomerDetails : XMLParseBase
|
||||
{
|
||||
public XMLParseCustomerDetails(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingCustomerDetails });
|
||||
var customerDetails = ParseCustomerDetails(_root);
|
||||
var newRoot = ConvertCustomerDetails(customerDetails);
|
||||
customerDetails = ParseCustomerDetails(newRoot);
|
||||
importObject.AddCustomerDetailsList(customerDetails);
|
||||
}
|
||||
|
||||
private XmlElement ConvertCustomerDetails(IEnumerable<ISO.CustomerDetails> customerDetails)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.CustomerDetails.ToString());
|
||||
foreach (var c in customerDetails)
|
||||
{
|
||||
_writer.Flush();
|
||||
c.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
}
|
||||
private List<ISO.CustomerDetails> ParseCustomerDetails(XmlElement root)
|
||||
{
|
||||
List<ISO.CustomerDetails> customerDetails = new List<ISO.CustomerDetails>();
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return customerDetails; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
customerDetails.Add(ISO.CustomerDetails.ReadXML(node as XmlElement));
|
||||
}
|
||||
}
|
||||
return customerDetails;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Import.XML;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public static class XmlParserFactory
|
||||
{
|
||||
public static List<IUIItems> UIItems { get; set; }
|
||||
private static Func<bool> _isCancelled;
|
||||
public static IImportNotification ImportNotification { get; set; }
|
||||
private static List<IParseVariant> LessThan20XMLVersion(XmlElement node, double importVersion)
|
||||
{
|
||||
List<IParseVariant> parseVariants = new List<IParseVariant>();
|
||||
//FB 36879 prevent exception if there is no node to process
|
||||
if (node == null || node.ChildNodes == null)
|
||||
{
|
||||
return parseVariants;
|
||||
}
|
||||
foreach (var childNode in node.ChildNodes)
|
||||
{
|
||||
if (childNode is XmlElement)
|
||||
{
|
||||
var root = childNode as XmlElement;
|
||||
var name = root.Name;
|
||||
if (Enum.TryParse(name, out TopLevelFields field))
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case TopLevelFields.CustomChannels:
|
||||
var xmlCustomChannels = new XMLParseMMECustomChannels(root, importVersion, _isCancelled);
|
||||
parseVariants.Add(xmlCustomChannels);
|
||||
break;
|
||||
case TopLevelFields.CustomMainLocs:
|
||||
var xmlCustomMainLocs = new XMLParseMMECustomMainLocations(root, importVersion, _isCancelled);
|
||||
parseVariants.Add(xmlCustomMainLocs);
|
||||
break;
|
||||
case TopLevelFields.DASList:
|
||||
var xmlParseDasList = new XMLParseDASList(root, importVersion, _isCancelled);
|
||||
parseVariants.Add(new XMLPre20ParseDASList(root, importVersion, xmlParseDasList, _isCancelled));
|
||||
break;
|
||||
case TopLevelFields.Sensors:
|
||||
var xmlParseSensors = new XMLParseSensors(root, importVersion, _isCancelled);
|
||||
xmlParseSensors.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(new XMLPre20ParseSensors(root, importVersion, xmlParseSensors, _isCancelled));
|
||||
break;
|
||||
case TopLevelFields.Calibrations:
|
||||
var xmlParseCalibrations = new XMLParseCalibrations(root, importVersion, _isCancelled);
|
||||
xmlParseCalibrations.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(new XMLPre20ParseCalibrations(root, importVersion, xmlParseCalibrations, _isCancelled));
|
||||
break;
|
||||
case TopLevelFields.GroupTemplates:
|
||||
var xmlParseGroupTemplates = new XMLParseGroupTemplates(root, importVersion, null, _isCancelled);
|
||||
parseVariants.Add(new XMLPre20ParseGroupTemplates(root, importVersion, xmlParseGroupTemplates, _isCancelled));
|
||||
break;
|
||||
case TopLevelFields.Groups:
|
||||
var xmlParseGroups = new XMLParseGroups(root, importVersion);
|
||||
xmlParseGroups.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(new XMLPre20ParseGroups(root, importVersion, null, xmlParseGroups, _isCancelled));
|
||||
break;
|
||||
case TopLevelFields.TestSetups:
|
||||
var xmlParseTestSetups = new XMLParseTestSetups(root, importVersion, _isCancelled);
|
||||
xmlParseTestSetups.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(new XMLPre20ParseTestSetups(root, importVersion, DTS.Common.Enums.IsoViewMode.ISOOnly, xmlParseTestSetups, _isCancelled));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return parseVariants;
|
||||
}
|
||||
|
||||
|
||||
private static List<IParseVariant> GreaterOrEqual20XMLVersion(XmlElement node, double importVersion, bool skipNormalizing)
|
||||
{
|
||||
List<IParseVariant> parseVariants = new List<IParseVariant>();
|
||||
foreach (var childNode in node.ChildNodes)
|
||||
{
|
||||
if (childNode is XmlElement)
|
||||
{
|
||||
var root = childNode as XmlElement;
|
||||
var name = root.Name;
|
||||
if (Enum.TryParse(name, out TopLevelFields field))
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
|
||||
case TopLevelFields.LabDetails:
|
||||
var xmlParseLab = new XMLParseLabDetails(root, importVersion, _isCancelled);
|
||||
xmlParseLab.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(xmlParseLab);
|
||||
break;
|
||||
case TopLevelFields.CustomerDetails:
|
||||
var xmlParseCustomer = new XMLParseCustomerDetails(root, importVersion, _isCancelled);
|
||||
xmlParseCustomer.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(xmlParseCustomer);
|
||||
break;
|
||||
case TopLevelFields.TestEngineerDetails:
|
||||
var xmlParseTestEngineer = new XMLParseTestEngineerDetails(root, importVersion, _isCancelled);
|
||||
xmlParseTestEngineer.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(xmlParseTestEngineer);
|
||||
break;
|
||||
case TopLevelFields.DASList:
|
||||
var xmlParseDasList = new XMLParseDASList(root, importVersion, _isCancelled, skipNormalizing);
|
||||
xmlParseDasList.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(xmlParseDasList);
|
||||
break;
|
||||
case TopLevelFields.Sensors:
|
||||
var xmlParseSensors = new XMLParseSensors(root, importVersion, _isCancelled, skipNormalizing);
|
||||
xmlParseSensors.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(xmlParseSensors);
|
||||
break;
|
||||
case TopLevelFields.Calibrations:
|
||||
var xmlParseCalibrations = new XMLParseCalibrations(root, importVersion, _isCancelled);
|
||||
xmlParseCalibrations.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(xmlParseCalibrations);
|
||||
break;
|
||||
case TopLevelFields.GroupTemplates:
|
||||
var xmlParseGroupTemplates = new XMLParseGroupTemplates(root, importVersion, null, _isCancelled);
|
||||
parseVariants.Add(xmlParseGroupTemplates);
|
||||
break;
|
||||
case TopLevelFields.Groups:
|
||||
var xmlParseGroups = new XMLParseGroups(root, importVersion, _isCancelled);
|
||||
xmlParseGroups.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(xmlParseGroups);
|
||||
break;
|
||||
case TopLevelFields.TestSetups:
|
||||
var xmlParseTestSetups = new XMLParseTestSetups(root, importVersion, _isCancelled, skipNormalizing);
|
||||
xmlParseTestSetups.ImportNotification = ImportNotification;
|
||||
parseVariants.Add(xmlParseTestSetups);
|
||||
break;
|
||||
case TopLevelFields.Users:
|
||||
var xmlParseUsers = new XMLParseUsers(root, importVersion, UIItems, _isCancelled);
|
||||
parseVariants.Add(xmlParseUsers);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return parseVariants;
|
||||
}
|
||||
|
||||
public static IEnumerable<IParseVariant> CreateXMLParsers(string fileName, IImportNotification importNotification, Func<bool> isCanceled, bool skipNormalizing)
|
||||
{
|
||||
double importVersion = -1;
|
||||
_isCancelled = isCanceled;
|
||||
ImportNotification = importNotification;
|
||||
var node = FileUtils.GetImportXmlNode(fileName, null, out importVersion);
|
||||
|
||||
if (importVersion < FileUtils.DataPRO20XmlVersion)
|
||||
{
|
||||
return LessThan20XMLVersion(node, importVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GreaterOrEqual20XMLVersion(node, importVersion, skipNormalizing);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Classes.TestSetups;
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.SensorDB;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
|
||||
public class XMLParseTestSetups : XMLParseBase
|
||||
{
|
||||
public XMLParseTestSetups(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_channelIdMapping.Clear();
|
||||
}
|
||||
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingTestSetups });
|
||||
var testTemplates = ParseTestTemplate(importObject, _root);
|
||||
var newRoot = ConvertTestTemplates(testTemplates, importObject);
|
||||
testTemplates = ParseTestTemplate(importObject, newRoot);
|
||||
importObject.TestSetupImportFileFormat = ImportObject.GetImportFileFormat(testTemplates.Count());
|
||||
importObject.AddTestSetups(testTemplates);
|
||||
}
|
||||
private XmlElement ConvertTestTemplates(IEnumerable<TestTemplate> testTemplates, ImportObject importObject)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.TestSetups.ToString());
|
||||
foreach (var t in testTemplates)
|
||||
{
|
||||
var groupCount = -1;
|
||||
foreach (var group in t.Groups)
|
||||
{
|
||||
group.Id = groupCount;
|
||||
|
||||
if (group.StaticGroupId != null)
|
||||
{
|
||||
if (_groupIdMapping.ContainsKey(group.StaticGroupId.ToString()))
|
||||
{
|
||||
group.StaticGroupId = _groupIdMapping[group.StaticGroupId.ToString()];
|
||||
}
|
||||
else
|
||||
{
|
||||
//This can occur if an old (buggy) Test Setup export includes an embedded
|
||||
//Group which was created from a static Group which was later deleted.
|
||||
group.StaticGroupId = null;
|
||||
}
|
||||
}
|
||||
|
||||
groupCount--;
|
||||
}
|
||||
var channelCount = -1;
|
||||
foreach (var group in t.ChannelsForGroup)
|
||||
{
|
||||
foreach (var channel in group.Value)
|
||||
{
|
||||
if (_dasIdMapping.ContainsKey(channel.DASId))
|
||||
{
|
||||
channel.DASId = _dasIdMapping[channel.DASId];
|
||||
}
|
||||
if (_sensorIdMapping.ContainsKey(channel.SensorId))
|
||||
{
|
||||
var match = importObject.Sensors().FirstOrDefault(s => s.DatabaseId == _sensorIdMapping[channel.SensorId]);
|
||||
//setting the sensor just so IsUart, etc is populated
|
||||
if (null != match) { channel.SetSensorData(match, null, false); }
|
||||
channel.SensorId = _sensorIdMapping[channel.SensorId];
|
||||
}
|
||||
else
|
||||
{
|
||||
//FB 14308 - Don't fail Test Setup import if it was
|
||||
//exported when out-of-date due to a deleted sensor.
|
||||
channel.SensorId = 0;
|
||||
}
|
||||
_channelIdMapping[channel.Id] = channelCount;
|
||||
channel.Id = channelCount;
|
||||
channelCount--;
|
||||
}
|
||||
}
|
||||
|
||||
var addedHardwareList = new List<int>();
|
||||
foreach (var dasId in t.AddedHardware)
|
||||
{
|
||||
addedHardwareList.Add(_dasIdMapping[dasId]);
|
||||
}
|
||||
t.AddedHardware = addedHardwareList.ToArray();
|
||||
|
||||
var removedHardwareList = new List<int>();
|
||||
foreach (var dasId in t.RemovedHardware)
|
||||
{
|
||||
if (_dasIdMapping.ContainsKey(dasId))
|
||||
{
|
||||
removedHardwareList.Add(_dasIdMapping[dasId]);
|
||||
}
|
||||
}
|
||||
t.RemovedHardware = removedHardwareList.ToArray();
|
||||
|
||||
_writer.Flush();
|
||||
t.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
}
|
||||
|
||||
public IEnumerable<TestTemplate> ParseTestTemplate(ImportObject importObject, XmlElement root)
|
||||
{
|
||||
List<TestTemplate> testTemplates = new List<TestTemplate>();
|
||||
var testobjectLookup = new Dictionary<string, TestObject>();
|
||||
var groupLookup = new Dictionary<string, IGroup>();
|
||||
|
||||
foreach (var to in importObject.Groups())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
testobjectLookup[to.SerialNumber] = to;
|
||||
}
|
||||
|
||||
//Static Groups
|
||||
foreach (var g in importObject.StaticGroups())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
groupLookup[g.Name] = g;
|
||||
}
|
||||
|
||||
var customerDetailsLookup = new Dictionary<string, ISO.CustomerDetails>();
|
||||
foreach (var c in importObject.CustomerDetails())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
customerDetailsLookup[c.Name] = c;
|
||||
}
|
||||
|
||||
var testEngineerDetailsLookup = new Dictionary<string, ISO.TestEngineerDetails>();
|
||||
foreach (var t in importObject.TestEngineerDetails())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
testEngineerDetailsLookup[t.Name] = t;
|
||||
}
|
||||
|
||||
var labDetailsLookup = new Dictionary<string, ISO.LabratoryDetails>();
|
||||
foreach (var l in importObject.LabDetails())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
labDetailsLookup[l.Name] = l;
|
||||
}
|
||||
|
||||
var sensorLookup = new Dictionary<string, SensorData>();
|
||||
foreach (var s in importObject.Sensors())
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
sensorLookup[s.SerialNumber] = s;
|
||||
}
|
||||
|
||||
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return testTemplates; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
//18868 Pass the list of DAS from this import, instead of getting all of the DAS in the database.
|
||||
var simpleImportedHardwareList = new List<SimpleHardware>();
|
||||
foreach (var h in importObject.Hardware())
|
||||
{
|
||||
simpleImportedHardwareList.Add(new SimpleHardware(h.SerialNumber, h.ParentDAS, -1, Convert.ToInt32(h.DASTypeEnum)));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var d = new TestTemplate(null, true, simpleImportedHardwareList.ToArray());
|
||||
d.ReadXML(node as XmlElement, testobjectLookup, groupLookup, labDetailsLookup, customerDetailsLookup, testEngineerDetailsLookup, sensorLookup, importObject.Hardware()?.ToList(),
|
||||
importObject.Calibrations()?.ToList());
|
||||
d.SetGroupsListOrder(); //If any were just imported and have a DisplayOrder of -1, fix them up
|
||||
testTemplates.Add(d);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//FB 36879 If can't read the xml report the error
|
||||
importObject.AddError(new ImportError
|
||||
{
|
||||
Message = ex.Message,
|
||||
Severity = ImportSeverityError.Warning,
|
||||
ContinueImportOnError = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return testTemplates;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using DTS.Common.Classes;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using Microsoft.VisualBasic.FileIO;
|
||||
using System;
|
||||
|
||||
namespace DTS.Common.Import.Parsers.CSV
|
||||
{
|
||||
public class Version5CSVTestParser : IParseCSVTest
|
||||
{
|
||||
public int Version => 5;
|
||||
public void ParseVersion(TextFieldParser parser, TestSetupImportData tsid)
|
||||
{
|
||||
var foundHeader = false;
|
||||
string[] tokens = null;
|
||||
while (!foundHeader && !parser.EndOfData)
|
||||
{
|
||||
tokens = parser.ReadFields();
|
||||
if (null == tokens) { return; }
|
||||
if (0 == tokens.Length || string.IsNullOrEmpty(tokens[0])) { continue; }
|
||||
var field = CSVImportTags.GetTagForString(tokens[0]);
|
||||
var version = CSVImportTags.GetVersionForTag(field);
|
||||
if (version != 5) { return; } //no version 5 tokens in here ...
|
||||
foundHeader = true;
|
||||
}
|
||||
|
||||
var tokens2 = parser.ReadFields();
|
||||
for (var i = 0; null != tokens2 && i < tokens.Length && i < tokens2.Length; i++)
|
||||
{
|
||||
var field = CSVImportTags.GetTagForString(tokens[i]);
|
||||
var val = tokens2[i];
|
||||
switch (field)
|
||||
{
|
||||
case CSVImportTags.Tags.ClockMasterInputType:
|
||||
{
|
||||
if (Enum.TryParse(val, out InputClockSource source))
|
||||
{
|
||||
tsid.ClockMasterInput = source;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.ClockMasterOutputType:
|
||||
{
|
||||
if (Enum.TryParse(val, out OutputClockSource source))
|
||||
{
|
||||
tsid.ClockMasterOutput = source;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.ManageClocksOutsideDPMaster:
|
||||
{
|
||||
if (bool.TryParse(val, out var bTemp))
|
||||
{
|
||||
tsid.ManageClocksOutsideOfDataPROMaster = bTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.ManageClocksOutsideDPSlave:
|
||||
{
|
||||
if (bool.TryParse(val, out var bTemp))
|
||||
{
|
||||
tsid.ManageClocksOutsideOfDataPROSlave = bTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.ClockSlaveInputType:
|
||||
{
|
||||
if (Enum.TryParse(val, out OutputClockSource source))
|
||||
{
|
||||
tsid.ClockSlaveInput = source;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.ClockSlaveOutputType:
|
||||
{
|
||||
if (Enum.TryParse(val, out OutputClockSource source))
|
||||
{
|
||||
tsid.ClockSlaveOutput = source;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("DTS.Common.Import")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("DTS.Common.Import")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2023")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("c1bc06f4-8657-4892-bc4d-1064da01c4c7")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,395 @@
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using static DTS.Common.Enums.Sensors.SensorConstants;
|
||||
using Microsoft.VisualBasic.FileIO;
|
||||
using System.IO;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Slice.Users;
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Import.Parsers;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.Import.Factories;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class DTSCSVSensorsParser : ParseVariantBase
|
||||
{
|
||||
private readonly List<string> Errors = new List<string>();
|
||||
private readonly User _currentUser;
|
||||
private readonly CsvImportOptions _csvImportOptions;
|
||||
private readonly ICalibrationImport _calibrationImport;
|
||||
private readonly ZeroMethodOptions _zeroMethodOptions;
|
||||
private readonly IImportNotification _importNotification;
|
||||
public DTSCSVSensorsParser(IImportNotification importNotification, User user, CsvImportOptions csvImportOptions,
|
||||
ICalibrationImport calibrationImport, ZeroMethodOptions zeroMethodOptions)
|
||||
{
|
||||
_currentUser = user;
|
||||
_csvImportOptions = csvImportOptions;
|
||||
_calibrationImport = calibrationImport;
|
||||
_zeroMethodOptions = zeroMethodOptions;
|
||||
_importNotification = importNotification;
|
||||
}
|
||||
|
||||
public bool ImportCreateDynamicGroups { get; set; }
|
||||
public bool UseISOCodeFilterMapping { get; set; }
|
||||
public bool UseZeroForUnfiltered { get; set; }
|
||||
|
||||
|
||||
private ISquibSettingDefaults GetSquibDefaults()
|
||||
{
|
||||
return SquibSettingDefaults.GetSquibSettingsDefault(_currentUser.UserName);
|
||||
}
|
||||
private IDigitalOutDefaults GetDigitalOutDefaults()
|
||||
{
|
||||
return DigitalOutputDefaults.GetDigitalOutDefault(_currentUser.UserName);
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
|
||||
if (string.IsNullOrEmpty(FileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (importObject == null)
|
||||
{
|
||||
throw new ArgumentNullException("importObject", "importObject can't be null or empty");
|
||||
}
|
||||
|
||||
importObject = ParseSensor(importObject, FileName);
|
||||
AssignErrorsToImportObject(ref importObject);
|
||||
}
|
||||
|
||||
private void AssignErrorsToImportObject(ref ImportObject importObject)
|
||||
{
|
||||
//FB 42971 Assign errors in this parser to the import object errors property to be reported to user
|
||||
foreach (var error in Errors)
|
||||
{
|
||||
importObject.AddError(new ImportError { ContinueImportOnError = true, Message = error, Severity = ImportSeverityError.Error });
|
||||
}
|
||||
}
|
||||
|
||||
private ImportObject ParseSensor(ImportObject importObject, string filename)
|
||||
{
|
||||
var columns = new List<CSVImportTags.Tags>();
|
||||
var line = 2;
|
||||
var version = 0;
|
||||
var sensorGroupNameLookup = new Dictionary<string, string>();
|
||||
var sensorGroupTypeLookup = new Dictionary<string, string>();
|
||||
var groupNameTestObjectLookup = new Dictionary<string, string>();
|
||||
var sensorISOCode = new Dictionary<string, string>();
|
||||
var sensorISOChannelName = new Dictionary<string, string>();
|
||||
var sensorUserCode = new Dictionary<string, string>();
|
||||
var sensorUserChannelName = new Dictionary<string, string>();
|
||||
var sensorDASSerialNumber = new Dictionary<string, string>();
|
||||
var sensorDASChannelIdx = new Dictionary<string, int>();
|
||||
var pp = new ParseParameters()
|
||||
{
|
||||
ImportCulture = _csvImportOptions.ImportCulture,
|
||||
StripBackslash = _csvImportOptions.StripBackSlash,
|
||||
SensorGroupNameLookup = sensorGroupNameLookup,
|
||||
SensorGroupTypeLookup = sensorGroupTypeLookup,
|
||||
GroupNameToTestObjectLookup = groupNameTestObjectLookup,
|
||||
UseISOCodeFilterMapping = UseISOCodeFilterMapping,
|
||||
UseZeroForUnfiltered = UseZeroForUnfiltered,
|
||||
SensorISOCode = sensorISOCode,
|
||||
SensorISOChannelName = sensorISOChannelName,
|
||||
SensorUserCode = sensorUserCode,
|
||||
SensorUserChannelName = sensorUserChannelName,
|
||||
SensorDASSerialNumber = sensorDASSerialNumber,
|
||||
SensorDASChannelIndex = sensorDASChannelIdx
|
||||
};
|
||||
|
||||
using (var parser = new TextFieldParser(filename, Encoding.GetEncoding(_csvImportOptions.Encoding), true))
|
||||
{
|
||||
parser.TextFieldType = FieldType.Delimited;
|
||||
parser.SetDelimiters(_csvImportOptions.FieldSeparator);
|
||||
string[] tokens = parser.ReadFields();
|
||||
|
||||
if (tokens != null && tokens[0] == "Version")
|
||||
{
|
||||
var tokens2 = parser.ReadFields();
|
||||
if (tokens2 != null)
|
||||
{
|
||||
int.TryParse(tokens2[0], out version);
|
||||
}
|
||||
if (version == 6)
|
||||
{
|
||||
//read until you have no empty start and the tag is < 5
|
||||
while (!parser.EndOfData)
|
||||
{
|
||||
tokens = parser.ReadFields();
|
||||
if (null == tokens || string.IsNullOrWhiteSpace(tokens[0])) { continue; }
|
||||
var tag = CSVImportTags.GetTagForString(tokens[0]);
|
||||
if (tag == CSVImportTags.Tags.Unknown) { continue; }
|
||||
var tagVersion = CSVImportTags.GetVersionForTag(tag);
|
||||
if (tagVersion > 4) { continue; }
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parser.ReadLine();
|
||||
tokens = parser.ReadFields();
|
||||
}
|
||||
}
|
||||
|
||||
if (tokens == null)
|
||||
{
|
||||
Errors.Clear();
|
||||
Errors.Add("No tokens to parse");
|
||||
return importObject;
|
||||
}
|
||||
|
||||
foreach (var token in tokens)
|
||||
{
|
||||
columns.Add(CSVImportTags.GetTagForString(token));
|
||||
}
|
||||
|
||||
if (0 == columns.Count)
|
||||
{
|
||||
//NONE of the columns row was recognized, PopulateSensor below will fail as it uses this to populate the sensor
|
||||
//this will not import any further, so shortcut to an error to the user
|
||||
//14745 Vague error message when Test Setup import is attempted
|
||||
|
||||
Errors.Clear();
|
||||
Errors.Add(StringResources.ImportSensorsPreviewControl_NoColumnsInTDCCSV);
|
||||
return importObject;
|
||||
}
|
||||
|
||||
var squibDefaults = GetSquibDefaults();
|
||||
var digitalOutDefaults = GetDigitalOutDefaults();
|
||||
|
||||
//18259 DataPRO XML and CSV imports let you import inconsistent SensitvityUnits
|
||||
var sensorsWithUpdatedSensitivityUnits = new List<string>();
|
||||
while (!parser.EndOfData)
|
||||
{
|
||||
tokens = parser.ReadFields();
|
||||
if (null == tokens) { break; }
|
||||
var sd = new SensorData();
|
||||
var sc = new SensorCalibration();
|
||||
pp.SensorData = sd;
|
||||
pp.SensorCal = sc;
|
||||
pp.SquibDefaults = squibDefaults;
|
||||
pp.DigitalOutDefaults = digitalOutDefaults;
|
||||
if (!PopulateSensor(columns, tokens, File.GetLastWriteTime(filename), pp))
|
||||
{
|
||||
//pp.Errors contains all the errors related to this sensor which is parsed
|
||||
var errorMessage = $"Line {line}: {string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator, pp.Errors)}";
|
||||
Errors.Add(errorMessage);
|
||||
line++;
|
||||
continue;
|
||||
}
|
||||
if (!sc.IsProportional && sc.Records.Records[0].SensitivityUnits == SensUnits.mVperVperEU)
|
||||
{
|
||||
sc.Records.Records[0].SensitivityUnits = SensUnits.mVperEU;
|
||||
if (!sensorsWithUpdatedSensitivityUnits.Contains(sd.SerialNumber))
|
||||
{
|
||||
sensorsWithUpdatedSensitivityUnits.Add(sd.SerialNumber);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sd.SerialNumber.StartsWith(Constants.ISO_CH_ONLY_PREFIX))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(sd.SerialNumber))
|
||||
{
|
||||
importObject.AddSensorLookup(sd.SerialNumber, sd);
|
||||
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(sd.SerialNumber))
|
||||
{
|
||||
importObject.AddCalibrationLookup(sd.SerialNumber, new List<SensorCalibration>(new[] { sc }));
|
||||
}
|
||||
}
|
||||
|
||||
// this is for compatability for import test setups
|
||||
importObject.AddSensor(sd);
|
||||
importObject.AddSensorChannelCodeLookup(sd.SettingName, sd.SerialNumber);
|
||||
// this is for compatability for import test setups
|
||||
importObject.AddCalibration(sc);
|
||||
line++;
|
||||
}
|
||||
|
||||
if (sensorsWithUpdatedSensitivityUnits.Any())
|
||||
{
|
||||
var msg = $"{StringResources.SensorsUpdatedSensitivityUnits} {string.Join(", ", sensorsWithUpdatedSensitivityUnits.ToArray())}";
|
||||
_importNotification.ReportErrors(new List<string>(new[] { msg }));
|
||||
}
|
||||
}
|
||||
importObject.AssignSensorGroupNameLookup(sensorGroupNameLookup);
|
||||
importObject.AssignSensorGroupTypeLookup(sensorGroupTypeLookup);
|
||||
importObject.AssignGroupNameTestObjectLookup(groupNameTestObjectLookup);
|
||||
importObject.AssignParseParameters(pp);
|
||||
return importObject;
|
||||
}
|
||||
|
||||
private void Preparse(ParseParameters pp)
|
||||
{
|
||||
var sd = (SensorData)pp.SensorData;
|
||||
sd.Initialize(pp.SquibDefaults);
|
||||
sd.Initialize(pp.DigitalOutDefaults);
|
||||
}
|
||||
private void PostParse(ParseParameters pp)
|
||||
{
|
||||
var sd = (SensorData)pp.SensorData;
|
||||
var sc = (SensorCalibration)pp.SensorCal;
|
||||
sd.InitializeTag(sd.Bridge);
|
||||
|
||||
pp.SensorCal.SerialNumber = pp.SensorData.SerialNumber;
|
||||
if (!double.IsNaN(pp.IrtraccExponent) && pp.SensorData.SensorCategory == (int)SensorInformationFile.TDCSensorCategory.IRTracc)
|
||||
{
|
||||
pp.SensorCal.IsProportional = false;
|
||||
pp.SensorCal.NonLinear = true;
|
||||
if (pp.SensorCal.Records.Records[0].Poly.NonLinearStyle == NonLinearStyles.IRTraccAverageOverTime)
|
||||
{
|
||||
pp.SensorCal.Records.Records[0].Poly.MMPerV = 1000D / pp.Sensitivity;
|
||||
pp.SensorCal.Records.Records[0].Poly.LinearizationExponent = pp.IrtraccExponent;
|
||||
pp.SensorCal.Records.Records[0].Poly.NonLinearStyle = NonLinearStyles.IRTraccAverageOverTime;
|
||||
}
|
||||
pp.SensorCal.Records.Records[0].Poly.MarkValid(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
pp.SensorCal.Records.Records[0].Sensitivity = pp.Sensitivity;
|
||||
if (pp.SensorCal.IsProportional) { pp.SensorCal.Records.Records[0].Excitation = pp.SensorData.SupportedExcitation.First(); }
|
||||
}
|
||||
if (!double.IsNaN(pp.OriginalOffset))
|
||||
{
|
||||
pp.SensorCal.InitialOffsets.Offsets[0].EU = pp.OriginalOffset;
|
||||
pp.SensorCal.InitialOffsets.Offsets[0].Form = InitialOffsetTypes.EU;
|
||||
}
|
||||
pp.SensorCal.ZeroMethods = new ZeroMethods(new[] { new ZeroMethod(pp.ZeroType, pp.ZeroStart, pp.ZeroEnd) });
|
||||
if (sd.SerialNumber.StartsWith(Constants.ISO_CH_ONLY_PREFIX) && !string.IsNullOrEmpty(sd.ISOCode)) { pp.Errors = new List<string>(); }
|
||||
|
||||
//warn if we are analog and have 0 sensitivity ...
|
||||
if (pp.SensorCal.Records.Records[0].Sensitivity == 0D && !sd.IsDigitalOutput() && !sd.IsDigitalInput() && !sd.IsSquib()
|
||||
&& !sd.IsUart() && !sd.IsStreamInput() && !sd.IsStreamOutput())
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.InvalidEmptySensitivity, sd.SerialNumber));
|
||||
}
|
||||
//warn if we are analog and have invalid capacity
|
||||
if (sd.Capacity < 1 && !sd.IsDigitalInput() && !sd.IsDigitalOutput() && !sd.IsSquib()
|
||||
&& !sd.IsUart() && !sd.IsStreamOutput() && !sd.IsStreamInput())
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.ImportSensor_InvalidCapacity, sd.SerialNumber,
|
||||
sd.Capacity));
|
||||
}
|
||||
//warn if we are analog and have invalid excitation
|
||||
if (IsAnalogWithInvalidExcitation(sd, sc))
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.InvalidExcitation,
|
||||
pp.SensorCal.Records.Records[0].Excitation));
|
||||
}
|
||||
if (IsAnalogWithInvalidSensitivity(sd, sc))
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.InvalidEmptySensitivity,
|
||||
sd.SerialNumber));
|
||||
}
|
||||
}
|
||||
private void Parse(CSVImportTags.Tags tag, string sValue, ParseParameters pp,
|
||||
IReadOnlyDictionary<int, IParseCSVSensor> parsers)
|
||||
{
|
||||
var version = CSVImportTags.GetVersionForTag(tag);
|
||||
if (parsers.ContainsKey(version))
|
||||
{
|
||||
parsers[version].ParseVersion(tag, sValue, pp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// scans throw a line of tokens in an expected column order and populates a sensor and a sensor calibration with data from that line
|
||||
/// errors is populated with any errors encountered during the import
|
||||
/// returns true if any errors were detected.
|
||||
/// </summary>
|
||||
/// <param name="columns"></param>
|
||||
/// <param name="tokens"></param>
|
||||
/// <param name="sd"></param>
|
||||
/// <param name="errors"></param>
|
||||
/// <param name="sc"></param>
|
||||
/// <param name="fileDateTime"></param>
|
||||
/// <param name="importCulture"></param>
|
||||
/// <param name="sensorGroupNameLookup"></param>
|
||||
/// <param name="sensorGroupTypeLookup"></param>
|
||||
/// <param name="squibDefaults"></param>
|
||||
/// <param name="digitalOutDefaults"></param>
|
||||
/// <param name="groupNameToTestObjectLookup"></param>
|
||||
/// <param name="stripBackslash"></param>
|
||||
/// <param name="useISOCodeFilterMapping"></param>
|
||||
/// <param name="useZeroForUnfiltered"></param>
|
||||
/// <returns></returns>
|
||||
private bool PopulateSensor(IReadOnlyList<CSVImportTags.Tags> columns,
|
||||
string[] tokens,
|
||||
DateTime fileDateTime,
|
||||
ParseParameters pp
|
||||
)
|
||||
{
|
||||
pp.SensorData.LastModified = fileDateTime;
|
||||
pp.IrtraccExponent = double.NaN;
|
||||
pp.Sensitivity = double.NaN;
|
||||
pp.SensorCal.ModifyDate = DateTime.Now;
|
||||
pp.ZeroType = pp.SensorCal.ZeroMethods.Methods.First().Method;
|
||||
pp.ZeroEnd = pp.SensorCal.ZeroMethods.Methods.First().End;
|
||||
pp.ZeroStart = pp.SensorCal.ZeroMethods.Methods.First().Start;
|
||||
pp.SavedIsProportional = false;
|
||||
pp.SavedRemoveOffset = false;
|
||||
//FB 42971 for each senosr starts with no errors
|
||||
pp.Errors = new List<string>();
|
||||
Preparse(pp);
|
||||
|
||||
var parsers = CSVSensorParserFactory.CreateCSVParsers(_calibrationImport, _zeroMethodOptions,
|
||||
_importNotification, ImportCreateDynamicGroups, UseISOCodeFilterMapping,
|
||||
UseZeroForUnfiltered);
|
||||
|
||||
for (var i = 0; i < columns.Count; i++)
|
||||
{
|
||||
var field = columns[i];
|
||||
var val = tokens[i];
|
||||
if (val.StartsWith("'") && !val.StartsWith("''")) { val = val.Substring(1); }
|
||||
try
|
||||
{
|
||||
Parse(field, val, pp, parsers);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log($"Failed to parse tags version {i}", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PostParse(pp);
|
||||
|
||||
return !pp.Errors.Any();
|
||||
}
|
||||
|
||||
private static bool IsAnalogWithInvalidExcitation(SensorData sd, SensorCalibration sc)
|
||||
{
|
||||
return sc.Records.Records[0].Excitation ==
|
||||
ExcitationVoltageOptions.ExcitationVoltageOption.Undefined &&
|
||||
(sd.Bridge == BridgeType.FullBridge ||
|
||||
sd.Bridge == BridgeType.HalfBridge ||
|
||||
sd.Bridge == BridgeType.QuarterBridge);
|
||||
}
|
||||
private static bool IsAnalogWithInvalidSensitivity(SensorData sd, SensorCalibration sc)
|
||||
{
|
||||
if ( sd == null || sc == null || null == sc.Records || null == sc.Records.Records || 0 == sc.Records.Records.Length) { return true; }
|
||||
return sd.IsAnalog() && Math.Abs(sc.Records.Records[0].Sensitivity) < .0000001;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseMMECustomDirections : XMLParseBase
|
||||
{
|
||||
public XMLParseMMECustomDirections(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AddDirections(ParseCustomDirections(_root));
|
||||
}
|
||||
|
||||
private IEnumerable<ISO.MMEDirections> ParseCustomDirections(XmlElement root)
|
||||
{
|
||||
List<ISO.MMEDirections> list = new List<ISO.MMEDirections>();
|
||||
|
||||
foreach (var child in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return list; }
|
||||
if (child is XmlElement)
|
||||
{
|
||||
list.Add(ISO.MMEDirections.ReadXML(child as XmlElement));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class CSVFile
|
||||
{
|
||||
private readonly string _filename;
|
||||
public CSVFile(string filename)
|
||||
{
|
||||
_filename = filename;
|
||||
}
|
||||
public static bool IsInUse(string filename)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(filename))
|
||||
{
|
||||
try
|
||||
{
|
||||
_ = File.ReadAllLines(filename);
|
||||
return false;
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//We can supress this exception since we are interested in IOException only
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//FB 40598 check the format of csv and determine if is test setup or not
|
||||
public static bool IsCSVFileForTestSetupImport(string filename, CsvImportOptions csvImportOptions)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var csvReader = CsvUtil.CreateCsvReader(filename))
|
||||
{
|
||||
var tokens = CsvUtil.ReadFields(csvReader);
|
||||
|
||||
if (tokens != null && tokens[0] == "Version")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// return false later
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//FB 43815 Get the CSV file version
|
||||
public static int GetCsvVersion(string filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var csvReader = CsvUtil.CreateCsvReader(filename))
|
||||
{
|
||||
var tokens = CsvUtil.ReadFields(csvReader);
|
||||
|
||||
if (tokens != null && tokens[0] == "Version")
|
||||
{
|
||||
var tokens2 = CsvUtil.ReadFields(csvReader);
|
||||
if (tokens2 != null)
|
||||
{
|
||||
var version = Convert.ToInt32(tokens2[0]);
|
||||
return version;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int LineCount
|
||||
{
|
||||
get
|
||||
{
|
||||
var count = 0;
|
||||
if (!string.IsNullOrEmpty(_filename))
|
||||
{
|
||||
string[] lines;
|
||||
try
|
||||
{
|
||||
lines = File.ReadAllLines(_filename);
|
||||
return lines.Count();
|
||||
}
|
||||
|
||||
catch (Exception)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.Parsers
|
||||
{
|
||||
public class DefaultParseImport : IParseImport
|
||||
{
|
||||
private ImportObject _importObject;
|
||||
private readonly IEnumerable<IParseVariant> _parseVariants;
|
||||
|
||||
|
||||
public DefaultParseImport(ImportObject importObject, IEnumerable<IParseVariant> parseVariants)
|
||||
{
|
||||
_importObject = importObject;
|
||||
_parseVariants = parseVariants;
|
||||
}
|
||||
public ImportObject Parse(IEnumerable<string> importFiles)
|
||||
{
|
||||
ParseProcessor parseProcesser = new ParseProcessor(_importObject, importFiles, _parseVariants);
|
||||
_importObject = parseProcesser.Process();
|
||||
|
||||
return _importObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// handles the Version 0 Channel name tag
|
||||
/// </summary>
|
||||
/// <param name="val"></param>
|
||||
/// <param name="pp"></param>
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseLabDetails : XMLParseBase
|
||||
{
|
||||
public XMLParseLabDetails(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingLabDetails });
|
||||
var details = ParseLabDetails(_root);
|
||||
var newRoot = ConvertLabDetails(details);
|
||||
details = ParseLabDetails(newRoot);
|
||||
importObject.AddLabDetailsList(details);
|
||||
}
|
||||
|
||||
private XmlElement ConvertLabDetails(IEnumerable<ISO.LabratoryDetails> details)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.LabDetails.ToString());
|
||||
foreach (var c in details)
|
||||
{
|
||||
_writer.Flush();
|
||||
c.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
}
|
||||
private List<ISO.LabratoryDetails> ParseLabDetails(XmlElement root)
|
||||
{
|
||||
List<ISO.LabratoryDetails> details = new List<ISO.LabratoryDetails>();
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return details; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
details.Add(ISO.LabratoryDetails.ReadXML(node as XmlElement));
|
||||
}
|
||||
}
|
||||
return details;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Import.Enums;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class ImportStatus
|
||||
{
|
||||
public string Status { get; set; }
|
||||
public PossibleStatus PossibleStatus { get; set; }
|
||||
public ImportExtraStatus ExtraStatus { get; set; }
|
||||
}
|
||||
public interface IImportNotification
|
||||
{
|
||||
Action ImportDone { get; }
|
||||
Action<List<string>> ReportErrors { get; }
|
||||
Action<double> SetProgress { get; }
|
||||
Action<ImportStatus> SetStatus { get; }
|
||||
}
|
||||
|
||||
public class ImportNotification : IImportNotification
|
||||
{
|
||||
public ImportNotification(Action<List<string>> reportErrors, Action<ImportStatus> setStatus, Action<double> setProgress, Action importDone)
|
||||
{
|
||||
ReportErrors = reportErrors;
|
||||
SetStatus = setStatus;
|
||||
SetProgress = setProgress;
|
||||
ImportDone = importDone;
|
||||
}
|
||||
|
||||
public ImportNotification()
|
||||
{
|
||||
ReportErrors = (x) => { };
|
||||
SetStatus = (x) => { };
|
||||
SetProgress = (x) => { };
|
||||
ImportDone = () => { };
|
||||
}
|
||||
|
||||
public Action<List<string>> ReportErrors { get; private set; }
|
||||
public Action<ImportStatus> SetStatus { get; private set; }
|
||||
public Action<double> SetProgress { get; private set; }
|
||||
public Action ImportDone { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.ImportOptions
|
||||
{
|
||||
public class EqxImportOptions
|
||||
{
|
||||
public bool OverwriteExistingSensors { get; set; } = true;
|
||||
public bool ImportSensorModels { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Import.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveLabDetails : SaveVariantBase
|
||||
{
|
||||
|
||||
public SaveLabDetails(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingLabDetails, PossibleStatus = PossibleStatus.Importing });
|
||||
var invalidLabDetails = false;
|
||||
foreach (var l in _importObject.LabDetails())
|
||||
{
|
||||
if (IsCancelled()) { return; }
|
||||
|
||||
if (l.IsInvalidBlank())
|
||||
{
|
||||
invalidLabDetails = true;
|
||||
}
|
||||
else { LabratoryDetailsList.AddLab(new LabratoryDetails(l)); }
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
using DTS.Common.Classes.Groups.ChannelSettings;
|
||||
using DTS.Common.Classes.Groups;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface.Channels;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.Interface.GroupTemplate;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLPre20ParseGroups : XMLParseBase
|
||||
{
|
||||
private readonly ISO.ISO13499FileDb _iSO13499FileDb;
|
||||
private readonly XMLParseGroups _xmlParseGroups;
|
||||
public XMLPre20ParseGroups(XmlElement root, double importedVersion, DTS.Common.ISO.ISO13499FileDb iSO13499FileDb,
|
||||
XMLParseGroups xmlParseGroups, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_iSO13499FileDb = iSO13499FileDb;
|
||||
_xmlParseGroups = xmlParseGroups;
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
var groups = ParsePre20Groups(ref importObject);
|
||||
importObject.AddGroups(groups);
|
||||
|
||||
var newRoot = MigratePre20Groups(groups, ref importObject);
|
||||
var staticGroups = _xmlParseGroups.ParseGroups(newRoot, ref importObject);
|
||||
importObject.AddStaticGroups(staticGroups);
|
||||
}
|
||||
|
||||
private XmlElement MigratePre20Groups(IEnumerable<DataPROWin7.DataModel.TestObject> groups, ref ImportObject importObject)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.Groups.ToString());
|
||||
var count = -1;
|
||||
foreach (var g in groups)
|
||||
{
|
||||
if (!g.GetISOTestObject().Embedded && !g.SysBuilt)
|
||||
{
|
||||
//Only make static Groups out of non-embedded and non-Added Groups
|
||||
IGroup iGroup = GroupHelper.CreateEmptyGroup();
|
||||
iGroup.Name = g.SerialNumber;
|
||||
|
||||
iGroup.LastModified = g.LastModified;
|
||||
iGroup.LastModifiedBy = g.LastModifiedBy;
|
||||
iGroup.Embedded = false;
|
||||
|
||||
iGroup.Id = count;
|
||||
count--;
|
||||
_groupIdMapping[iGroup.Name] = iGroup.Id;
|
||||
|
||||
iGroup.IncludedHardwareStringList = g.GetISOTestObject().HardwareIds;
|
||||
var dasIdList = new List<string>();
|
||||
foreach (var hardwareString in iGroup.IncludedHardwareStringList)
|
||||
{
|
||||
dasIdList.Add(hardwareString.Substring(0, hardwareString.IndexOf('_')));
|
||||
}
|
||||
iGroup.IncludedHardwareStringList = dasIdList.ToArray();
|
||||
foreach (var ch in g.GetISOTestObject().AllChannels)
|
||||
{
|
||||
if (!ch.Required || string.IsNullOrEmpty(ch.SensorSerialNumber)) continue;
|
||||
|
||||
var groupChannel = new GroupChannel(true, iGroup.Name, iGroup, new IChannelSetting[0]);
|
||||
groupChannel.IsoChannelName = ch.NameOfTheChannel; //???
|
||||
groupChannel.UserChannelName = ch.NameOfTheChannel; //???
|
||||
groupChannel.UserCode = string.Empty;
|
||||
if (!string.IsNullOrWhiteSpace(ch.HardwareId))
|
||||
{
|
||||
var hardwareUnderscoreSplit = ch.HardwareId.Split('_');
|
||||
groupChannel.Hardware = hardwareUnderscoreSplit[0];
|
||||
|
||||
foreach (var hardware in importObject.Hardware())
|
||||
{
|
||||
if (hardware.SerialNumber == groupChannel.Hardware)
|
||||
{
|
||||
groupChannel.DASId = hardware.DASId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var hardwareXSplit = ch.HardwareId.Split('x');
|
||||
groupChannel.DASChannelIndex = Convert.ToInt32(hardwareXSplit[1]) - 1;
|
||||
}
|
||||
var channelParts = ch.GetId().Split('_');
|
||||
groupChannel.GroupChannelOrder = Convert.ToInt32(channelParts[channelParts.Length - 1]);
|
||||
groupChannel.TestSetupOrder = -1;
|
||||
foreach (var sensor in importObject.Sensors())
|
||||
{
|
||||
if (sensor.SerialNumber == ch.SensorSerialNumber)
|
||||
{
|
||||
groupChannel.SetSensorData(sensor, null);
|
||||
groupChannel.SensorId = sensor.DatabaseId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
groupChannel.IsDisabled = false;
|
||||
groupChannel.LastModified = g.LastModified;
|
||||
groupChannel.LastModifiedBy = g.LastModifiedBy;
|
||||
var sensorSettings = g.GetISOTestObject().GetSensorSettings(ch.GetId(), ch.SensorSerialNumber);
|
||||
var channelSettingList = new List<DTS.Common.Interface.Channels.IChannelSetting>();
|
||||
foreach (var sensorSetting in sensorSettings)
|
||||
{
|
||||
var channelSettingBase = new ChannelSettingBase((int)sensorSetting.Setting + 1,
|
||||
sensorSetting.Setting.ToString(),
|
||||
sensorSetting.Value);
|
||||
switch (sensorSetting.Setting)
|
||||
{
|
||||
case SensorConstants.SensorSettings.OutputMode:
|
||||
case SensorConstants.SensorSettings.SQMode:
|
||||
case SensorConstants.SensorSettings.DIMode:
|
||||
case SensorConstants.SensorSettings.UartBaudRate:
|
||||
case SensorConstants.SensorSettings.UartDataBits:
|
||||
if (int.TryParse(sensorSetting.Value, out var tmp))
|
||||
{
|
||||
channelSettingBase.IntValue = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case SensorConstants.SensorSettings.CFC:
|
||||
//FB 15574 convert cfc iso to FilterClass and replace the cfc setting with filter class
|
||||
var cfc = sensorSetting.Value;
|
||||
var filterClass = FilterClass.GetFilterClassSettingFromCFC(cfc);
|
||||
|
||||
channelSettingBase = new ChannelSettingBase((int)SensorConstants.SensorSettings.FilterClass + 1,
|
||||
SensorConstants.SensorSettings.FilterClass.ToString(), filterClass);
|
||||
channelSettingBase.Value = filterClass;
|
||||
|
||||
groupChannel.IsoCode = ch.ISOCode.Substring(0, 15) + cfc;
|
||||
break;
|
||||
case SensorConstants.SensorSettings.Polarity:
|
||||
case SensorConstants.SensorSettings.Position:
|
||||
case SensorConstants.SensorSettings.ZeroMethod:
|
||||
case SensorConstants.SensorSettings.UserValue1:
|
||||
case SensorConstants.SensorSettings.UserValue2:
|
||||
case SensorConstants.SensorSettings.UserValue3:
|
||||
case SensorConstants.SensorSettings.InitialOffset:
|
||||
case SensorConstants.SensorSettings.UartStopBits:
|
||||
case SensorConstants.SensorSettings.UartParity:
|
||||
case SensorConstants.SensorSettings.UartFlowControl:
|
||||
case SensorConstants.SensorSettings.UartDataFormat:
|
||||
channelSettingBase.Value = sensorSetting.Value;
|
||||
break;
|
||||
case SensorConstants.SensorSettings.LimitDuration:
|
||||
channelSettingBase.BoolValue = Convert.ToBoolean(sensorSetting.Value);
|
||||
break;
|
||||
case SensorConstants.SensorSettings.Range:
|
||||
case SensorConstants.SensorSettings.Duration:
|
||||
case SensorConstants.SensorSettings.Delay:
|
||||
case SensorConstants.SensorSettings.DefaultValue:
|
||||
case SensorConstants.SensorSettings.ActiveValue:
|
||||
case SensorConstants.SensorSettings.ZeroMethodStart:
|
||||
case SensorConstants.SensorSettings.ZeroMethodEnd:
|
||||
channelSettingBase.DoubleValue = Convert.ToDouble(sensorSetting.Value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
channelSettingList.Add(channelSettingBase);
|
||||
|
||||
}
|
||||
groupChannel.ChannelSettings = channelSettingList.ToArray();
|
||||
|
||||
iGroup.GroupChannelList.Add(groupChannel);
|
||||
}
|
||||
|
||||
_writer.Flush();
|
||||
iGroup.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
}
|
||||
private IEnumerable<DataPROWin7.DataModel.TestObject> ParsePre20Groups(ref ImportObject importObject)
|
||||
{
|
||||
List<DataPROWin7.DataModel.TestObject> groups = new List<DataPROWin7.DataModel.TestObject>();
|
||||
var importedHardware = new Dictionary<string, DataPROWin7.DataModel.DASHardware>();
|
||||
foreach (var h in importObject.Hardware())
|
||||
{
|
||||
importedHardware[h.GetHardware().GetId()] = h;
|
||||
}
|
||||
|
||||
var templateLookup = new Dictionary<string, ISO.TestObjectTemplate>();
|
||||
var templateLookup2 = new Dictionary<string, DataPROWin7.DataModel.TestObjectTemplate>();
|
||||
|
||||
foreach (var template in importObject.GroupTemplates())
|
||||
{
|
||||
templateLookup[template.TemplateName] = template.ToISOTestObjectTemplate();
|
||||
templateLookup2[template.TemplateName] = template;
|
||||
}
|
||||
foreach (var node in _root.ChildNodes)
|
||||
{
|
||||
if (!(node is XmlElement)) continue;
|
||||
var to = DataPROWin7.DataModel.TestObject.ReadXML(node as XmlElement, templateLookup, importObject.Calibrations()?.ToList(), importObject.Sensors()?.ToList());
|
||||
if (string.IsNullOrEmpty(to.Template)) continue;
|
||||
if (!templateLookup2.ContainsKey(to.Template))
|
||||
{
|
||||
var db = _iSO13499FileDb;
|
||||
var template = new DataPROWin7.DataModel.TestObjectTemplate(templateLookup[to.Template], ref db);
|
||||
templateLookup2[to.Template] = template;
|
||||
}
|
||||
groups.Add(new DataPROWin7.DataModel.TestObject(to, to.SysBuilt, templateLookup2[to.Template], importedHardware));
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Classes;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.Common.Import.Factories;
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
using DTS.Common.Import.Parsers;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.Common.Storage;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.SensorDB;
|
||||
using Microsoft.VisualBasic.FileIO;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class DTSCSVTestSetupParser : ParseVariantBase
|
||||
{
|
||||
private readonly IImportNotification _importNotification;
|
||||
private readonly CsvImportOptions _csvImportOptions;
|
||||
private readonly TestSetupImportData _defaultsTestSetupImportData;
|
||||
private readonly IGroupImport _groupImport;
|
||||
//FB 36905
|
||||
private readonly bool _createDynamicGroups;
|
||||
public DTSCSVTestSetupParser(IImportNotification importNotification, CsvImportOptions csvImportOptions, TestSetupImportData testSetupImportData, IGroupImport groupImport, bool createDynamicGroups)
|
||||
{
|
||||
_csvImportOptions = csvImportOptions;
|
||||
_defaultsTestSetupImportData = testSetupImportData;
|
||||
_importNotification = importNotification;
|
||||
_groupImport = groupImport;
|
||||
_createDynamicGroups = createDynamicGroups;
|
||||
}
|
||||
|
||||
public static TestTemplate CreateTestSetup(TestSetupImportData tsid, DASHardware[] allDAS)
|
||||
{
|
||||
var t = new TestTemplate
|
||||
{
|
||||
Name = tsid.Name,
|
||||
Description = tsid.Description,
|
||||
SamplesPerSecondAggregate = tsid.SamplesPerSecond,
|
||||
PostTriggerSeconds = tsid.PosttriggerSeconds,
|
||||
PreTriggerSeconds = tsid.PretriggerSeconds,
|
||||
RecordingMode = tsid.RecordingMode,
|
||||
CalibrationBehavior = tsid.CalibrationBehavior
|
||||
};
|
||||
|
||||
AddHardwareToTestSetup(t, tsid, allDAS);
|
||||
|
||||
SetClockSyncs(t, tsid);
|
||||
if (RecordingModeExtensions.IsAStreamMode(tsid.RecordingMode))
|
||||
{
|
||||
t.DoStreaming = true;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
private static void SetClockSyncs(TestTemplate t, TestSetupImportData tsid)
|
||||
{
|
||||
if (tsid.ManageClocksOutsideOfDataPROMaster)
|
||||
{
|
||||
t.ClockSyncProfileMaster = ClockSyncProfile.Manual;
|
||||
}
|
||||
if (tsid.ManageClocksOutsideOfDataPROSlave)
|
||||
{
|
||||
t.ClockSyncProfileSlave = ClockSyncProfile.Manual;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void AddHardwareToTestSetup(TestTemplate t, TestSetupImportData tsid, DASHardware[] allDAS)
|
||||
{
|
||||
if (null != tsid.SampleRateForDAS && 0 != tsid.SampleRateForDAS.Count)
|
||||
{
|
||||
using (var e = tsid.SampleRateForDAS.GetEnumerator())
|
||||
{
|
||||
while (e.MoveNext())
|
||||
{
|
||||
var das = Array.Find(allDAS, d => d.SerialNumber.Equals(e.Current.Key));
|
||||
if (null == das) { continue; }
|
||||
t.AddHardware(das.DASId);
|
||||
if (tsid.IsClockMaster.ContainsKey(das.SerialNumber))
|
||||
{
|
||||
t.DASClockMasterList[das.SerialNumber] = tsid.IsClockMaster[das.SerialNumber];
|
||||
}
|
||||
if (tsid.DomainIdForDAS.ContainsKey(das.SerialNumber))
|
||||
{
|
||||
t.DASPTPDomainIDList[das.SerialNumber] = Convert.ToByte(t.DASPTPDomainIDList[das.SerialNumber]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void UpdateDASSampleRate(TestTemplate t, TestSetupImportData tsid, DASHardware[] allDAS)
|
||||
{
|
||||
if (null != tsid.SampleRateForDAS && 0 != tsid.SampleRateForDAS.Count)
|
||||
{
|
||||
using (var e = tsid.SampleRateForDAS.GetEnumerator())
|
||||
{
|
||||
while (e.MoveNext())
|
||||
{
|
||||
var das = Array.Find(allDAS, d => d.SerialNumber.Equals(e.Current.Key));
|
||||
if (null == das) { continue; }
|
||||
//why are there two places for this information?
|
||||
t.SetSampleRateForHardware(das, Convert.ToDouble(e.Current.Value));
|
||||
t.DASSampleRateList[das.SerialNumber] = Convert.ToDouble(e.Current.Value);
|
||||
}
|
||||
}
|
||||
if (tsid.SampleRateForDAS.Distinct().Count() > 1)
|
||||
{
|
||||
t.CommonStatusLine = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
if (string.IsNullOrEmpty(FileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (importObject == null)
|
||||
{
|
||||
throw new ArgumentNullException("importObject", "importObject can't be null or empty");
|
||||
}
|
||||
//FB 40598 Check if the file is supported for test setup import
|
||||
|
||||
if (!CSVFile.IsCSVFileForTestSetupImport(FileName, _csvImportOptions))
|
||||
{
|
||||
importObject.AddError(new ImportError { Message = StringResources.Import_CSVFileNotForTestSetup, ContinueImportOnError = false, Severity = ImportSeverityError.Critical });
|
||||
return;
|
||||
}
|
||||
|
||||
var tsid = ParseTestSetup(FileName);
|
||||
|
||||
if (tsid == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (importObject.TestSetups().Any(p => p.Name == tsid.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var allDAS = DataPROWin7.DataModel.Classes.Hardware.DASHardwareList.GetAllHardware();
|
||||
var t = CreateTestSetup(tsid, allDAS);
|
||||
//FB 36879 Add the hardware list for the test setup
|
||||
if (t != null)
|
||||
{
|
||||
importObject.AddHardwareList(t.GetHardware());
|
||||
}
|
||||
|
||||
if (tsid.Tags != null)
|
||||
{
|
||||
t?.SetTags(tsid.Tags.ToArray(), DbOperations.GetSQLCommand, DbOperations.TagsGet,
|
||||
DbOperations.TagsGetId, DbOperations.TagsInsert);
|
||||
}
|
||||
|
||||
//FB Assign the parse parameters
|
||||
_groupImport.ParseParameters = importObject.ParseParameters();
|
||||
|
||||
AssignCalibrations(ref importObject);
|
||||
|
||||
var res = AssignGroupsToTestSetup(t, importObject.SensorGroupNamesLookup(), null, importObject.StaticGroups().ToList(),
|
||||
importObject.Sensors().ToList(), _groupImport, _importNotification, tsid.Version);
|
||||
|
||||
var staticGroups = res?.Item2;
|
||||
var sensors = res?.Item3;
|
||||
var testSetup = res?.Item1;
|
||||
|
||||
if (staticGroups != null)
|
||||
{
|
||||
importObject.AddStaticGroups(staticGroups);
|
||||
}
|
||||
|
||||
var cleanedSensors = GroupHelper.CleanUneededSensorDataPlaceHolder(importObject.CalibrationsLookup(), sensors);
|
||||
if (cleanedSensors != null)
|
||||
{
|
||||
importObject.ClearSensors();
|
||||
|
||||
importObject.AddSensors(cleanedSensors);
|
||||
}
|
||||
|
||||
UpdateDASSampleRate(t, tsid, allDAS);
|
||||
|
||||
if (testSetup != null)
|
||||
{
|
||||
importObject.AddTestSetup(testSetup);
|
||||
//FB 38039, 40758 Identify type of import by number of test setups
|
||||
importObject.TestSetupImportFileFormat = importObject.GetImportFileFormat();
|
||||
}
|
||||
|
||||
importObject.SourceFormat = ImportFormats.DTS_CSV;
|
||||
}
|
||||
/// <summary>
|
||||
/// set the calibration for the sensor based on the most recent in the import
|
||||
/// this is necessary as it was coming in with the latest calibration from the database (which
|
||||
/// will be empty in a brand new import)
|
||||
/// http://manuscript.dts.local/f/cases/43722/When-Importing-Csv-test-setup-software-zero-method-in-test-setup-parameters-does-not-match-import
|
||||
/// </summary>
|
||||
private void AssignCalibrations(ref ImportObject importObject)
|
||||
{
|
||||
if (null == importObject) { return; }
|
||||
if (null == importObject.Sensors() || !importObject.Sensors().Any()) { return; }
|
||||
if (null == importObject.Calibrations() || !importObject.Calibrations().Any()) { return; }
|
||||
|
||||
foreach( var sensor in importObject.Sensors())
|
||||
{
|
||||
var cals = importObject.CalibrationLookup(sensor.SerialNumber);
|
||||
if (null == cals || 0 == cals.Count) { return; }
|
||||
cals.Sort();
|
||||
sensor.Calibration = cals[cals.Count - 1];
|
||||
}
|
||||
|
||||
}
|
||||
//FB 36879 Single Responsibility principle , moved the method to this class
|
||||
private Tuple<TestTemplate, List<IGroup>, List<SensorData>> AssignGroupsToTestSetup(TestTemplate testTemplate, Dictionary<string, string> sensorGroupNameLookup, Dictionary<string, List<string>> groupNameSensorListLookup,
|
||||
List<IGroup> existingStaticGroups, List<SensorData> sensors, IGroupImport groupImport, IImportNotification importNotification, int csvVersion)
|
||||
{
|
||||
try
|
||||
{
|
||||
_ = GroupHelper.ReverseChannelOrder(testTemplate, sensorGroupNameLookup, sensors);
|
||||
|
||||
var groupSensorLookup = groupImport.GetGroupSensorLookup(sensors, sensorGroupNameLookup, groupNameSensorListLookup);
|
||||
|
||||
sensors = GroupHelper.NormalizeSensorIds(sensors);
|
||||
//FB 36905
|
||||
var testAndGroups = groupImport.CreateGroups(sensors, groupSensorLookup, testTemplate, _createDynamicGroups, existingStaticGroups, importNotification.SetProgress);
|
||||
|
||||
if (testAndGroups == null)
|
||||
{
|
||||
TestTemplate noTestSetup = null;
|
||||
List<IGroup> noGroup = null;
|
||||
return Tuple.Create(noTestSetup, noGroup, sensors);
|
||||
}
|
||||
return Tuple.Create(testAndGroups.Item1, testAndGroups.Item2, sensors);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
importNotification.ReportErrors(new List<string> { ex.Message });
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private TestSetupImportData ParseTestSetup(string filename)
|
||||
{
|
||||
var tsid = new TestSetupImportData()
|
||||
{
|
||||
SamplesPerSecond = _defaultsTestSetupImportData.SamplesPerSecond,
|
||||
Tags = new List<string>(),
|
||||
Version = 0,
|
||||
RecordingMode = _defaultsTestSetupImportData.RecordingMode,
|
||||
PretriggerSeconds = _defaultsTestSetupImportData.PretriggerSeconds,
|
||||
PosttriggerSeconds = _defaultsTestSetupImportData.PosttriggerSeconds,
|
||||
CalibrationBehavior = _defaultsTestSetupImportData.CalibrationBehavior
|
||||
};
|
||||
using (var parser = new TextFieldParser(filename, Encoding.GetEncoding(_csvImportOptions.Encoding), true))
|
||||
{
|
||||
parser.TextFieldType = FieldType.Delimited;
|
||||
parser.SetDelimiters(_csvImportOptions.FieldSeparator);
|
||||
var parsers = CSVTestParserFactory.CreateCSVParsers();
|
||||
|
||||
parsers[0].ParseVersion(parser, tsid);
|
||||
|
||||
if (tsid.Version == 6)
|
||||
{
|
||||
for (var i = 1; i < parsers.Length; i++)
|
||||
{
|
||||
parsers[i].ParseVersion(parser, tsid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tsid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public abstract class SaveVariantBase : IPersistImport
|
||||
{
|
||||
protected ImportObject _importObject;
|
||||
protected readonly IPersistCalculator _persistCalculator;
|
||||
protected readonly IImportNotification _importNotification;
|
||||
public abstract void Save();
|
||||
|
||||
protected readonly Func<bool> IsCancelled;
|
||||
|
||||
protected SaveVariantBase(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification,
|
||||
Func<bool> isCancelled = null)
|
||||
{
|
||||
IsCancelled = isCancelled == null ? () => false : isCancelled;
|
||||
_persistCalculator = persistCalculator;
|
||||
_importNotification = importNotification;
|
||||
_importObject = importObject;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using DataPROWin7.DataModel.Classes.Hardware;
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.Common.Interface.DASFactory.Diagnostics;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveHardware : SaveVariantBase
|
||||
{
|
||||
public Dictionary<int, int> OldDASIdToNewDASId { get; set; } = new Dictionary<int, int>();
|
||||
|
||||
//track das.TestId so that we can update it if test id is updated
|
||||
//key here is the old test id in das.TestId
|
||||
public Dictionary<int, List<IISOHardware>> TestIdToHardware { get; set; } = new Dictionary<int, List<IISOHardware>>();
|
||||
public SaveHardware(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingHardware, PossibleStatus = PossibleStatus.Importing });
|
||||
_importObject.Hardware().ToList().Sort();
|
||||
|
||||
foreach (var h in _importObject.Hardware())
|
||||
{
|
||||
if (IsCancelled()) { return; }
|
||||
|
||||
var oldId = h.DASId;
|
||||
DASHardwareList.GetList().Commit(h, false, true); //false and true are the defaults
|
||||
if (h.DASId != oldId)
|
||||
{
|
||||
OldDASIdToNewDASId[oldId] = h.DASId;
|
||||
}
|
||||
|
||||
var iso = h.GetHardware();
|
||||
if (null != iso.TestId)
|
||||
{
|
||||
var id = (int)iso.TestId;
|
||||
if (!TestIdToHardware.ContainsKey(id))
|
||||
{
|
||||
TestIdToHardware[id] = new List<IISOHardware>();
|
||||
}
|
||||
TestIdToHardware[id].Add(iso);
|
||||
}
|
||||
_persistCalculator.AddDone(); //for each hardware
|
||||
_persistCalculator.AddDone(h.Channels?.Length ?? 0);
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseCalibrations : XMLParseBase
|
||||
{
|
||||
public XMLParseCalibrations(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingCalibrations });
|
||||
var scs = ParseCalibrations(_root);
|
||||
var newRoot = ConvertCalibrations(scs);
|
||||
importObject.AddCalibrations(ParseCalibrations(newRoot));
|
||||
|
||||
}
|
||||
public XmlElement ConvertCalibrations(IEnumerable<SensorCalibration> calibrations)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.Calibrations.ToString());
|
||||
foreach (var c in calibrations)
|
||||
{
|
||||
_writer.Flush();
|
||||
c.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
}
|
||||
|
||||
public IEnumerable<SensorCalibration> ParseCalibrations(XmlElement root)
|
||||
{
|
||||
List<SensorCalibration> scs = new List<SensorCalibration>();
|
||||
if (_importedVersion >= FileUtils.DataPROPre20XmlVersion)
|
||||
{
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return scs; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
var sc = new SensorCalibration();
|
||||
sc.ReadXML(node as XmlElement);
|
||||
scs.Add(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_importedVersion == 1.0D)
|
||||
{
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return scs; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
var sc = new SensorCalibration();
|
||||
sc.ReadXML(node as XmlElement);
|
||||
|
||||
sc.Records.Records[0].AtCapacity = false;
|
||||
|
||||
if (sc.NonLinear)
|
||||
{
|
||||
sc.Records.Records[0].SensitivityUnits = SensorConstants.SensUnits.NONE;
|
||||
}
|
||||
else if (sc.IsProportional)
|
||||
{
|
||||
sc.Records.Records[0].SensitivityUnits = SensorConstants.SensUnits.mVperVperEU;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.Records.Records[0].SensitivityUnits = SensorConstants.SensUnits.mVperEU;
|
||||
}
|
||||
scs.Add(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
return scs;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using CsvHelper;
|
||||
using DTS.Common.Classes;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.Common.Import.Parsers.CSV
|
||||
{
|
||||
public class Version5CSVTestParser : IParseCSVTest
|
||||
{
|
||||
private InputClockSource ParseInputClockSource(string val)
|
||||
{
|
||||
return Enum.TryParse(val, out InputClockSource source) ? source : default;
|
||||
}
|
||||
|
||||
private OutputClockSource ParseOutputClockSource(string val)
|
||||
{
|
||||
return Enum.TryParse(val, out OutputClockSource source) ? source : default;
|
||||
}
|
||||
|
||||
private static bool ParseBoolValue(string val)
|
||||
{
|
||||
return bool.TryParse(val, out var bTemp) ? bTemp : default;
|
||||
}
|
||||
|
||||
public int Version => 5;
|
||||
public void ParseVersion(CsvReader csvReader, TestSetupImportData tsid)
|
||||
{
|
||||
var foundHeader = false;
|
||||
List<string> tokens = new List<string>();
|
||||
while (!foundHeader && csvReader.Read())
|
||||
{
|
||||
tokens = CsvUtil.ReadFields(csvReader, false);
|
||||
|
||||
if (null == tokens) { return; }
|
||||
if (0 == tokens.Count || string.IsNullOrEmpty(tokens[0])) { continue; }
|
||||
var field = CSVImportTags.GetTagForString(tokens[0]);
|
||||
var version = CSVImportTags.GetVersionForTag(field);
|
||||
if (version != 5) { return; } //no version 5 tokens in here ...
|
||||
foundHeader = true;
|
||||
}
|
||||
|
||||
var tokens2 = CsvUtil.ReadFields(csvReader);
|
||||
|
||||
if (null == tokens2) { return; }
|
||||
|
||||
for (var i = 0; i < tokens.Count && i < tokens2.Count; i++)
|
||||
{
|
||||
GetValueForField(tsid, tokens, tokens2, i);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetValueForField(TestSetupImportData tsid, List<string> tokens, List<string> tokens2, int index)
|
||||
{
|
||||
var field = CSVImportTags.GetTagForString(tokens[index]);
|
||||
var val = tokens2[index];
|
||||
switch (field)
|
||||
{
|
||||
case CSVImportTags.Tags.ClockMasterInputType:
|
||||
{
|
||||
tsid.ClockMasterInput = ParseInputClockSource(val);
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.ClockMasterOutputType:
|
||||
{
|
||||
tsid.ClockMasterOutput = ParseOutputClockSource(val);
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.ManageClocksOutsideDPMaster:
|
||||
{
|
||||
tsid.ManageClocksOutsideOfDataPROMaster = ParseBoolValue(val);
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.ManageClocksOutsideDPSlave:
|
||||
{
|
||||
tsid.ManageClocksOutsideOfDataPROSlave = ParseBoolValue(val);
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.ClockSlaveInputType:
|
||||
{
|
||||
tsid.ClockSlaveInput = ParseOutputClockSource(val);
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.ClockSlaveOutputType:
|
||||
{
|
||||
tsid.ClockSlaveOutput = ParseOutputClockSource(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace DTS.Common.Import.Interfaces
|
||||
{
|
||||
public interface IParseVariant
|
||||
{
|
||||
string FileName { get; set; }
|
||||
void Parse(ref ImportObject importObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public abstract class XMLParseBase : IParseVariant
|
||||
{
|
||||
protected static readonly Dictionary<int, int> _dasIdMapping = new Dictionary<int, int>();
|
||||
//Use string to handle both new (Id (int.ToString())) and old (Name (string)) exports
|
||||
protected static readonly Dictionary<string, int> _groupIdMapping = new Dictionary<string, int>();
|
||||
protected static readonly Dictionary<int, int> _sensorIdMapping = new Dictionary<int, int>();
|
||||
protected static readonly Dictionary<long, long> _channelIdMapping = new Dictionary<long, long>();
|
||||
|
||||
protected double _importedVersion;
|
||||
|
||||
protected readonly Func<bool> IsCancelled;
|
||||
protected readonly XmlElement _root;
|
||||
protected XmlWriter _writer;
|
||||
private readonly XmlDocument _doc;
|
||||
|
||||
public string FileName { get; set; }
|
||||
public abstract void Parse(ref ImportObject importObject);
|
||||
|
||||
protected XMLParseBase(XmlElement root, double importedVersion, Func<bool> isCancelled = null)
|
||||
{
|
||||
_importedVersion = importedVersion;
|
||||
|
||||
IsCancelled = isCancelled == null ? () => false : isCancelled;
|
||||
|
||||
_root = root;
|
||||
|
||||
_doc = new XmlDocument();
|
||||
_writer = _doc.CreateNavigator().AppendChild();
|
||||
}
|
||||
|
||||
protected XmlElement GetXmlElement()
|
||||
{
|
||||
_writer.Close();
|
||||
return _doc.DocumentElement;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
using DataPROWin7.DataModel.Classes.Hardware;
|
||||
using DTS.Common.Classes.Groups.ChannelSettings;
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.Common.Interface.Channels;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.Common.Storage;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveGroups : SaveVariantBase
|
||||
{
|
||||
public bool CanCurrentUserCommitChannelCodes { get; set; } = true;
|
||||
public IChannelSetting DefaultZeroMethod { get; set; }
|
||||
public IChannelSetting DefaultZeroStart { get; set; }
|
||||
public IChannelSetting DefaultZeroEnd { get; set; }
|
||||
public IChannelSetting DefaultInitialOffset { get; set; }
|
||||
public Dictionary<int?, int> OldGroupIdToNewGroupId { get; set; } = new Dictionary<int?, int>();
|
||||
|
||||
private readonly SaveHardware _saveHardware;
|
||||
public SaveGroups(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification,
|
||||
SaveHardware saveHardware, Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
_saveHardware = saveHardware;
|
||||
}
|
||||
|
||||
private static void SetGroupId(IGroup group)
|
||||
{
|
||||
var hResult = DbOperations.GroupsGet(null, group.Name, null, null, null, out var dbGroups);
|
||||
if (0 == hResult && null != dbGroups && dbGroups.Any())
|
||||
{
|
||||
foreach (var groupRecord in dbGroups)
|
||||
{
|
||||
group.Id = groupRecord.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// if HardwareStringList is present, go and use that to look up the DASIds, which is what we actually want
|
||||
/// ... I'm not sure why groups has a HardwareListString other than import convenience which seems like a poor reason
|
||||
/// </summary>
|
||||
/// <param name="group"></param>
|
||||
private static void FixGroupHardware(IGroup group, IReadOnlyDictionary<string, int> idToDASId)
|
||||
{
|
||||
|
||||
var includedDASIds = new List<int>();
|
||||
foreach (var str in group.IncludedHardwareStringList.Where(str => idToDASId.ContainsKey(str)))
|
||||
{
|
||||
var id = idToDASId[str];
|
||||
if (!includedDASIds.Contains(id))
|
||||
{
|
||||
includedDASIds.Add(id);
|
||||
}
|
||||
}
|
||||
//this is just for safety purposes, we want to avoid wiping out IncludedHardware if we have values
|
||||
//for it already
|
||||
foreach (var hid in group.IncludedHardware)
|
||||
{
|
||||
if (!includedDASIds.Contains(hid))
|
||||
{
|
||||
includedDASIds.Add(hid);
|
||||
}
|
||||
}
|
||||
group.SetIncludedHardware(includedDASIds.ToArray());
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingGroups, PossibleStatus = PossibleStatus.Importing });
|
||||
//build a lookup of old id scheme to new
|
||||
var allHardware = DASHardwareList.GetAllHardware();
|
||||
var idToDASId = new Dictionary<string, int>();
|
||||
foreach (var h in allHardware)
|
||||
{
|
||||
idToDASId[h.GetHardware().SerialNumber] = h.DASId;
|
||||
}
|
||||
|
||||
var channelDefaults = DbOperations.GetChannelSettingDefaults();
|
||||
DefaultZeroMethod = (from defaults in channelDefaults
|
||||
where defaults.SettingName == ChannelSettingBase.ZEROMETHOD
|
||||
select defaults).First();
|
||||
DefaultZeroStart = (from defaults in channelDefaults
|
||||
where defaults.SettingName == ChannelSettingBase.ZEROMETHODSTART
|
||||
select defaults).First();
|
||||
DefaultZeroEnd = (from defaults in channelDefaults
|
||||
where defaults.SettingName == ChannelSettingBase.ZEROMETHODEND
|
||||
select defaults).First();
|
||||
DefaultInitialOffset = (from defaults in channelDefaults
|
||||
where defaults.SettingName == ChannelSettingBase.INITIAL_OFFSET
|
||||
select defaults).First();
|
||||
var missingDASGroupList = new List<string>();
|
||||
var allSensorsInDb = SensorDB.SensorsCollection.SensorsList.GetAllSensors(true);
|
||||
foreach (var g in _importObject.StaticGroups())
|
||||
{
|
||||
if (IsCancelled()) { return; }
|
||||
if (!g.Embedded)
|
||||
{
|
||||
foreach (var ch in g.GroupChannelList)
|
||||
{
|
||||
var oldSensorDatabaseIdToNew = _importObject.OldSensorDatabaseIdsToNew();
|
||||
if (oldSensorDatabaseIdToNew.ContainsKey(ch.SensorId))
|
||||
{
|
||||
ch.SensorId = oldSensorDatabaseIdToNew[ch.SensorId];
|
||||
var match = Array.Find(allSensorsInDb, s => s.DatabaseId == ch.SensorId);
|
||||
if (null != match)
|
||||
{
|
||||
ch.SetSensorData(match, null, false);
|
||||
}
|
||||
}
|
||||
if (_saveHardware.OldDASIdToNewDASId.ContainsKey(ch.DASId))
|
||||
{
|
||||
ch.DASId = _saveHardware.OldDASIdToNewDASId[ch.DASId];
|
||||
}
|
||||
else
|
||||
{
|
||||
//19045 If a Channel in a Group in an export has a DASId that doesn't
|
||||
//match any DAS in the export, set it as it should have been exported (-1).
|
||||
ch.DASId = -1;
|
||||
if (!missingDASGroupList.Contains(g.DisplayName))
|
||||
{
|
||||
missingDASGroupList.Add(g.DisplayName);
|
||||
}
|
||||
}
|
||||
//15262 Absolute zero sensors in test setup change to ave over time after import.
|
||||
//zero method may not be populated on older imports
|
||||
//make sure we fix this in the static group before it's commited
|
||||
SaveSensor.FixMissingZeroMethodParameter(ch, DefaultZeroMethod, DefaultZeroStart, DefaultZeroEnd);
|
||||
SaveSensor.FixMissingInitialOffset(ch, DefaultInitialOffset);
|
||||
}
|
||||
//Save off the normalized static Group Id
|
||||
var normalizedStaticGroupId = g.Id;
|
||||
SetGroupId(g);
|
||||
//fix the hardware for the group!
|
||||
FixGroupHardware(g, idToDASId);
|
||||
g.Save(g.GroupChannelList.ToArray(), CanCurrentUserCommitChannelCodes);
|
||||
//Map the normalized static Group Id to the new Id
|
||||
OldGroupIdToNewGroupId[normalizedStaticGroupId] = g.Id;
|
||||
}
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
|
||||
if (missingDASGroupList.Any())
|
||||
{
|
||||
_importObject.AddError(new ImportError
|
||||
{
|
||||
Message = $"{StringResources.GroupsHadChannelsAssignedToUnknownDAS} {string.Join(", ", missingDASGroupList.ToArray())}",
|
||||
ContinueImportOnError = true,
|
||||
Severity = ImportSeverityError.Warning
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Slice.Users;
|
||||
using DTS.Common.Import.DatabaseLocks;
|
||||
namespace DTS.Common.Import.Factories
|
||||
{
|
||||
public static class DatabaseLocksFactory
|
||||
{
|
||||
//FB 36740 Factory to build objects which implement ILockImport
|
||||
public static List<ILockImport> Create(ImportObject importObject, User user, double strandedLockTimeoutMinutes)
|
||||
{
|
||||
List<ILockImport> lockImports = new List<ILockImport>();
|
||||
|
||||
if (importObject.TestSetups().Any())
|
||||
{
|
||||
var testSetupsLock = new LockImportTestSetups(user, strandedLockTimeoutMinutes);
|
||||
lockImports.Add(testSetupsLock);
|
||||
}
|
||||
|
||||
if (importObject.Sensors().Any())
|
||||
{
|
||||
var sensorsLock = new LockImportSensors(user, strandedLockTimeoutMinutes);
|
||||
lockImports.Add(sensorsLock);
|
||||
}
|
||||
|
||||
if (importObject.StaticGroups().Any())
|
||||
{
|
||||
var groupsLock = new LockImportGroups(user, strandedLockTimeoutMinutes);
|
||||
lockImports.Add(groupsLock);
|
||||
}
|
||||
|
||||
return lockImports;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public sealed class TsetSetupImportSensorInfo
|
||||
{
|
||||
public TsetSetupImportSensorInfo(string serialNumber, string isoCode, string isoChannelName,
|
||||
string userCode, string userChannelName, string dasSerialNumber, int dasChannelIdx)
|
||||
{
|
||||
SerialNumber = serialNumber;
|
||||
IsoCode = isoCode;
|
||||
IsoChannelName = isoChannelName;
|
||||
UserCode = userCode;
|
||||
UserChannelName = userChannelName;
|
||||
DASSerialNumber = dasSerialNumber;
|
||||
DASChannelIndex = dasChannelIdx;
|
||||
}
|
||||
public TsetSetupImportSensorInfo(string serialNumber, string isoCode)
|
||||
{
|
||||
SerialNumber = serialNumber;
|
||||
IsoCode = isoCode;
|
||||
}
|
||||
public string IsoCode { get; }
|
||||
public string IsoChannelName { get; }
|
||||
public string UserCode { get; }
|
||||
public string UserChannelName { get; }
|
||||
public string SerialNumber { get; }
|
||||
public string GroupType { get; set; }
|
||||
public string DASSerialNumber { get; }
|
||||
public int DASChannelIndex { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.Common.Interface.Channels;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.SensorDB;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{ //FB 38039 Checkout testsetup save vriant
|
||||
public class SaveCheckoutTestSetup : SaveVariantBase
|
||||
{
|
||||
private readonly SaveCustomChannels _saveCustomChannels;
|
||||
private readonly SaveHardware _saveHardware;
|
||||
private readonly SaveGroups _saveGroups;
|
||||
private readonly string _setupName;
|
||||
public User CurrentUser { get; set; }
|
||||
public SaveCheckoutTestSetup(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification,
|
||||
SaveCustomChannels saveCustomChannels, SaveHardware saveHardware, SaveGroups saveGroups,
|
||||
Func<bool> isCancelled = null, string setupName = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
_saveCustomChannels = saveCustomChannels;
|
||||
_saveHardware = saveHardware;
|
||||
_saveGroups = saveGroups;
|
||||
_setupName = setupName;
|
||||
}
|
||||
private void ConfigureCheckoutTestSetup(TestTemplate TestSetupCheckout)
|
||||
{
|
||||
TestSetupCheckout.DoROIDownload = true;
|
||||
|
||||
TestSetupCheckout.ViewROIDownload = true;
|
||||
|
||||
TestSetupCheckout.DownloadAll = true;
|
||||
|
||||
TestSetupCheckout.ViewDownloadAll = true;
|
||||
|
||||
TestSetupCheckout.RequireUserConfirmationOnErrors = false;
|
||||
|
||||
TestSetupCheckout.UploadData = false;
|
||||
|
||||
TestSetupCheckout.ViewDiagnostics = true;
|
||||
|
||||
TestSetupCheckout.VerifyChannels = true;
|
||||
|
||||
TestSetupCheckout.ViewExport = false;
|
||||
|
||||
TestSetupCheckout.DefaultNumberRealtimeGraphs = 1;
|
||||
|
||||
TestSetupCheckout.ExportFormats = DTS.Common.Enums.SupportedExportFormatBitFlags.none; // no export for this test
|
||||
|
||||
TestSetupCheckout.AllowMissingSensors = true;
|
||||
|
||||
TestSetupCheckout.StrictDiagnostics = false;
|
||||
|
||||
TestSetupCheckout.AutomaticProgression = true;
|
||||
|
||||
TestSetupCheckout.DoAutoArm = false;
|
||||
|
||||
TestSetupCheckout.DoStreaming = false;
|
||||
|
||||
TestSetupCheckout.DoEnableRepeat = false;
|
||||
|
||||
TestSetupCheckout.AllowSensorIdToBlankChannel = true;
|
||||
TestSetupCheckout.AllowMissingSensors = true;
|
||||
TestSetupCheckout.CheckoutMode = true;
|
||||
TestSetupCheckout.QuitTestWithoutWarning = true;
|
||||
TestSetupCheckout.SuppressMissingSensorsWarning = true;
|
||||
TestSetupCheckout.NotAllChannelsViewer = true;
|
||||
TestSetupCheckout.NotAllChannelsRealTime = true;
|
||||
TestSetupCheckout.CheckListRequirePass = false;
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
|
||||
var testSetups = _importObject.TestSetups();
|
||||
|
||||
if (_importObject.TestSetupImportFileFormat == ImportFileFormat.SingleTestSetup)
|
||||
{
|
||||
var testSetup = testSetups.FirstOrDefault();
|
||||
if (testSetup == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
testSetup.Name = _setupName;
|
||||
testSetup.TestId = _setupName;
|
||||
testSetup.TestSetupUniqueId = Guid.NewGuid().ToString();
|
||||
ConfigureCheckoutTestSetup(testSetup);
|
||||
}
|
||||
|
||||
|
||||
Dictionary<string, string> oldIdToNewIdLookup = new Dictionary<string, string>();
|
||||
|
||||
SaveTestSetupHelper.UpdateLevelTriggers(ref oldIdToNewIdLookup, _saveCustomChannels, testSetups);
|
||||
|
||||
SaveTestSetupHelper.DeleteExistingTestSetups(testSetups, CurrentUser.UserName);
|
||||
|
||||
Dictionary<string, DASHardware> hardwareLookup = SaveTestSetupHelper.PopulateHarwareLookup();
|
||||
|
||||
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingTestSetups, PossibleStatus = PossibleStatus.Importing });
|
||||
foreach (var t in testSetups)
|
||||
{
|
||||
SaveTestSetupHelper.FixDasAff(hardwareLookup, t);
|
||||
|
||||
//keep track of test id prior to commit, so that we can correct das.TestId
|
||||
//if we need to
|
||||
var idPriorToCommit = t.Id;
|
||||
t.Id = 0;
|
||||
|
||||
Dictionary<IGroup, IGroupChannel[]> groupChannelsLookup = new Dictionary<IGroup, IGroupChannel[]>();
|
||||
var allSensorsInDb = SensorsCollection.SensorsList.GetAllSensors(true);
|
||||
|
||||
foreach (var cfg in t.ChannelsForGroup)
|
||||
{
|
||||
IGroup checkoutGroup = GroupHelper.CreateEmptyGroup();
|
||||
checkoutGroup.Name = cfg.Key.DisplayName;
|
||||
checkoutGroup.DisplayName = checkoutGroup.Name;
|
||||
checkoutGroup.DisplayOrder = cfg.Key.DisplayOrder;
|
||||
|
||||
List<IGroupChannel> groupChannelList = new List<IGroupChannel>();
|
||||
foreach (var ch in cfg.Value)
|
||||
{
|
||||
var match = allSensorsInDb?.FirstOrDefault(s => s.DatabaseId == ch.SensorId);
|
||||
if (null != match)
|
||||
{
|
||||
ch.SetSensorData(match, null, false);
|
||||
}
|
||||
|
||||
if (_saveHardware.OldDASIdToNewDASId.ContainsKey(ch.DASId))
|
||||
{
|
||||
ch.DASId = _saveHardware.OldDASIdToNewDASId[ch.DASId];
|
||||
}
|
||||
//15262 Absolute zero sensors in test setup change to ave over time after import.
|
||||
//zero method may be undefined on older imports
|
||||
//make sure we set the zero method before embedded group is committed ...
|
||||
SaveSensor.FixMissingZeroMethodParameter(ch, _saveGroups.DefaultZeroMethod, _saveGroups.DefaultZeroStart, _saveGroups.DefaultZeroEnd);
|
||||
SaveSensor.FixMissingInitialOffset(ch, _saveGroups.DefaultInitialOffset);
|
||||
groupChannelList.Add(ch);
|
||||
}
|
||||
groupChannelsLookup[checkoutGroup] = groupChannelList.ToArray();
|
||||
}
|
||||
|
||||
|
||||
t.Groups.Clear();
|
||||
t.ChannelsForGroup.Clear();
|
||||
|
||||
t.ChannelsForGroup = groupChannelsLookup;
|
||||
foreach (var g in groupChannelsLookup)
|
||||
{
|
||||
t.Groups.Add(g.Key);
|
||||
}
|
||||
|
||||
var hardwareIncluded = t.AddedHardware.ToList();
|
||||
var hardwareRemoved = t.RemovedHardware.ToList();
|
||||
|
||||
var listToProcess = new List<Tuple<int, int>>();
|
||||
using (var e = _saveHardware.OldDASIdToNewDASId.GetEnumerator())
|
||||
{
|
||||
while (e.MoveNext())
|
||||
{
|
||||
listToProcess.Add(new Tuple<int, int>(e.Current.Key, e.Current.Value));
|
||||
}
|
||||
}
|
||||
//arrange the to process by the largest new id
|
||||
listToProcess.Sort((a, b) =>
|
||||
{
|
||||
if (a == b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return b.Item2.CompareTo(a.Item2);
|
||||
});
|
||||
|
||||
foreach (var tuple in listToProcess)
|
||||
{
|
||||
if (tuple.Item1 == tuple.Item2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hardwareIncluded.Contains(tuple.Item1))
|
||||
{
|
||||
hardwareIncluded.Remove(tuple.Item1);
|
||||
hardwareIncluded.Add(tuple.Item2);
|
||||
}
|
||||
|
||||
if (hardwareRemoved.Contains(tuple.Item1))
|
||||
{
|
||||
hardwareRemoved.Remove(tuple.Item1);
|
||||
hardwareRemoved.Add(tuple.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
SaveTestSetupHelper.AddHardwareFromEmbeddedGroups(t, _saveGroups, hardwareRemoved, hardwareIncluded);
|
||||
|
||||
t.ReplaceCalculatedChannel(oldIdToNewIdLookup);
|
||||
|
||||
if (IsCancelled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TestTemplateList.TestTemplatesList.Commit(t, false);
|
||||
if (idPriorToCommit > 0 && _saveHardware.TestIdToHardware.ContainsKey(idPriorToCommit))
|
||||
{
|
||||
foreach (var enumH in _saveHardware.TestIdToHardware[idPriorToCommit])
|
||||
{
|
||||
enumH.TestId = t.Id;
|
||||
enumH.Update();
|
||||
}
|
||||
}
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
|
||||
oldIdToNewIdLookup.Clear();
|
||||
|
||||
if (_importObject.Errors().Any())
|
||||
{
|
||||
//report errors
|
||||
}
|
||||
//FB 36879 Still parsing it should report as Working status
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.None, PossibleStatus = PossibleStatus.Working });
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Policy;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseSensors : XMLParseBase
|
||||
{
|
||||
public XMLParseSensors(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled) { }
|
||||
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingSensors });
|
||||
var sensors = ParseSensors(_root);
|
||||
var newRoot = ConvertSensors(sensors);
|
||||
importObject.AddSensors(ParseSensors(newRoot));
|
||||
}
|
||||
public XmlElement ConvertSensors(IEnumerable<SensorData> sensors)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.Sensors.ToString());
|
||||
//normalize to -2 ... -n (preserve -1 for invalid)
|
||||
var count = -2;
|
||||
foreach (var sd in sensors)
|
||||
{
|
||||
_sensorIdMapping[sd.DatabaseId] = count;
|
||||
sd.DatabaseId = count;
|
||||
count--;
|
||||
_writer.Flush();
|
||||
sd.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
|
||||
return GetXmlElement();
|
||||
}
|
||||
|
||||
public IEnumerable<SensorData> ParseSensors(XmlElement root)
|
||||
{
|
||||
List<SensorData> sensors = new List<SensorData>();
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled())
|
||||
{
|
||||
return sensors;
|
||||
}
|
||||
|
||||
if (!(node is XmlElement)) continue;
|
||||
var sd = new SensorData();
|
||||
sd.ReadXML(node as XmlElement);
|
||||
|
||||
sensors.Add(sd);
|
||||
}
|
||||
return sensors;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.ISO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLPre20ParseDASList : XMLParseBase
|
||||
{
|
||||
private readonly XMLParseDASList _xmlParseDASList;
|
||||
public XMLPre20ParseDASList(XmlElement root, double importedVersion, XMLParseDASList xmlParseDASList, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_xmlParseDASList = xmlParseDASList;
|
||||
}
|
||||
public List<DASHardware> ParsePre20DASList(XmlElement root)
|
||||
{
|
||||
List<DASHardware> dasList = new List<DASHardware>();
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (node is XmlElement)
|
||||
{
|
||||
var isoHardware = DataPROWin7.DataModel.DASHardware.ReadXML(node as XmlElement);
|
||||
dasList.Add(new DASHardware(isoHardware));
|
||||
}
|
||||
}
|
||||
return dasList;
|
||||
}
|
||||
|
||||
private XmlElement MigratePre20DASList(List<DASHardware> dasList)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.DASList.ToString());
|
||||
var count = -1;
|
||||
foreach (var h in dasList)
|
||||
{
|
||||
h.SetDASId(count);
|
||||
count--;
|
||||
|
||||
_writer.Flush();
|
||||
h.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
}
|
||||
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
var dasList = ParsePre20DASList(_root);
|
||||
var newRoot = MigratePre20DASList(dasList);
|
||||
importObject.AddHardwareList(_xmlParseDASList.ParseDASList(newRoot));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DataPROWin7.DataModel.Classes.Hardware;
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.SensorDB;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveTestSetup : SaveVariantBase
|
||||
{
|
||||
private readonly SaveCustomChannels _saveCustomChannels;
|
||||
private readonly SaveHardware _saveHardware;
|
||||
private readonly SaveGroups _saveGroups;
|
||||
public User CurrentUser { get; set; }
|
||||
//FB 38039 Get/ Set setup name used in run test
|
||||
public string TestSetupName { get; set; }
|
||||
public SaveTestSetup(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification,
|
||||
SaveCustomChannels saveCustomChannels, SaveHardware saveHardware, SaveGroups saveGroups,
|
||||
Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
_saveCustomChannels = saveCustomChannels;
|
||||
_saveHardware = saveHardware;
|
||||
_saveGroups = saveGroups;
|
||||
}
|
||||
//FB 38039 Default used for run test
|
||||
private void ConfigureDefaultRunTestTestSetup(TestTemplate testSetup)
|
||||
{
|
||||
testSetup.DoROIDownload = true;
|
||||
|
||||
testSetup.ViewROIDownload = true;
|
||||
|
||||
testSetup.DownloadAll = true;
|
||||
|
||||
testSetup.ViewDownloadAll = true;
|
||||
|
||||
testSetup.RequireUserConfirmationOnErrors = true;
|
||||
|
||||
//FB 43757, 43817 keep the default from testsetup default setting for upload data
|
||||
|
||||
testSetup.ViewDiagnostics = true;
|
||||
|
||||
testSetup.VerifyChannels = true;
|
||||
|
||||
testSetup.ViewExport = true;
|
||||
|
||||
testSetup.DefaultNumberRealtimeGraphs = 1;
|
||||
|
||||
testSetup.ExportFormats = DTS.Common.Enums.SupportedExportFormatBitFlags.rdfadc;
|
||||
|
||||
testSetup.AllowMissingSensors = false;
|
||||
|
||||
testSetup.StrictDiagnostics = true;
|
||||
|
||||
testSetup.AutomaticProgression = true;
|
||||
|
||||
testSetup.DoAutoArm = false;
|
||||
|
||||
testSetup.DoEnableRepeat = false;
|
||||
|
||||
testSetup.DoStreaming = false;
|
||||
|
||||
testSetup.AllowSensorIdToBlankChannel = false;
|
||||
testSetup.AllowMissingSensors = false;
|
||||
testSetup.SuppressMissingSensorsWarning = false;
|
||||
testSetup.CheckListRequirePass = true;
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
var testSetups = _importObject.TestSetups();
|
||||
|
||||
if (_importObject.TestSetupImportFileFormat == ImportFileFormat.SingleTestSetup && !string.IsNullOrEmpty(TestSetupName))
|
||||
{
|
||||
//FB 38039 this test is used for run test
|
||||
var testSetup = testSetups.FirstOrDefault();
|
||||
if (testSetup == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
testSetup.Name = TestSetupName;
|
||||
testSetup.TestId = TestSetupName;
|
||||
ConfigureDefaultRunTestTestSetup(testSetup);
|
||||
}
|
||||
|
||||
Dictionary<string, string> oldIdToNewIdLookup = new Dictionary<string, string>();
|
||||
|
||||
SaveTestSetupHelper.UpdateLevelTriggers(ref oldIdToNewIdLookup, _saveCustomChannels, testSetups);
|
||||
|
||||
SaveTestSetupHelper.DeleteExistingTestSetups(testSetups, CurrentUser.UserName);
|
||||
|
||||
Dictionary<string, DASHardware> hardwareLookup = SaveTestSetupHelper.PopulateHarwareLookup();
|
||||
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingTestSetups, PossibleStatus = PossibleStatus.Importing });
|
||||
|
||||
foreach (var t in testSetups)
|
||||
{
|
||||
SaveTestSetupHelper.FixDasAff(hardwareLookup, t);
|
||||
//keep track of test id prior to commit, so that we can correct das.TestId
|
||||
//if we need to
|
||||
var idPriorToCommit = t.Id;
|
||||
t.Id = 0;
|
||||
|
||||
var allSensorsInDb = SensorsCollection.SensorsList.GetAllSensors(true);
|
||||
|
||||
foreach (var channels in t.ChannelsForGroup)
|
||||
{
|
||||
foreach (var ch in channels.Value)
|
||||
{
|
||||
if (_importObject.OldSensorDatabaseIdsToNew().ContainsKey(ch.SensorId))
|
||||
{
|
||||
ch.SensorId = _importObject.OldSensorDatabaseIdToNew(ch.SensorId);
|
||||
var match = allSensorsInDb?.FirstOrDefault(s => s.DatabaseId == ch.SensorId);
|
||||
if (null != match)
|
||||
{
|
||||
ch.SetSensorData(match, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (_saveHardware.OldDASIdToNewDASId.ContainsKey(ch.DASId))
|
||||
{
|
||||
ch.DASId = _saveHardware.OldDASIdToNewDASId[ch.DASId];
|
||||
}
|
||||
//15262 Absolute zero sensors in test setup change to ave over time after import.
|
||||
//zero method may be undefined on older imports
|
||||
//make sure we set the zero method before embedded group is committed ...
|
||||
SaveSensor.FixMissingZeroMethodParameter(ch, _saveGroups.DefaultZeroMethod, _saveGroups.DefaultZeroStart, _saveGroups.DefaultZeroEnd);
|
||||
SaveSensor.FixMissingInitialOffset(ch, _saveGroups.DefaultInitialOffset);
|
||||
}
|
||||
}
|
||||
|
||||
var hardwareIncluded = t.AddedHardware.ToList();
|
||||
var hardwareRemoved = t.RemovedHardware.ToList();
|
||||
|
||||
var listToProcess = new List<Tuple<int, int>>();
|
||||
foreach (var e in _saveHardware.OldDASIdToNewDASId)
|
||||
{
|
||||
listToProcess.Add(new Tuple<int, int>(e.Key, e.Value));
|
||||
}
|
||||
//arrange the to process by the largest new id
|
||||
listToProcess.Sort((a, b) =>
|
||||
{
|
||||
if (a == b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return b.Item2.CompareTo(a.Item2);
|
||||
});
|
||||
|
||||
foreach (var tuple in listToProcess)
|
||||
{
|
||||
if (tuple.Item1 == tuple.Item2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (hardwareIncluded.Contains(tuple.Item2))
|
||||
{
|
||||
throw new Exception("Panic, new id already in list");
|
||||
}
|
||||
|
||||
if (hardwareRemoved.Contains(tuple.Item2))
|
||||
{
|
||||
throw new Exception("Panic, new id already in list");
|
||||
}
|
||||
|
||||
if (hardwareIncluded.Contains(tuple.Item1))
|
||||
{
|
||||
hardwareIncluded.Remove(tuple.Item1);
|
||||
hardwareIncluded.Add(tuple.Item2);
|
||||
}
|
||||
|
||||
if (hardwareRemoved.Contains(tuple.Item1))
|
||||
{
|
||||
hardwareRemoved.Remove(tuple.Item1);
|
||||
hardwareRemoved.Add(tuple.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
SaveTestSetupHelper.AddHardwareFromEmbeddedGroups(t, _saveGroups, hardwareRemoved, hardwareIncluded);
|
||||
|
||||
t.ReplaceCalculatedChannel(oldIdToNewIdLookup);
|
||||
if (IsCancelled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (t.TestSetupUniqueId == null)
|
||||
{
|
||||
t.TestSetupUniqueId = Guid.NewGuid().ToString();
|
||||
}
|
||||
TestTemplateList.TestTemplatesList.Commit(t, false);
|
||||
if (idPriorToCommit > 0 && _saveHardware.TestIdToHardware.ContainsKey(idPriorToCommit))
|
||||
{
|
||||
foreach (var enumH in _saveHardware.TestIdToHardware[idPriorToCommit])
|
||||
{
|
||||
enumH.TestId = t.Id;
|
||||
enumH.Update();
|
||||
}
|
||||
}
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
|
||||
oldIdToNewIdLookup.Clear();
|
||||
|
||||
if (_importObject.Errors().Any())
|
||||
{
|
||||
//report errors
|
||||
}
|
||||
//FB 36879 Still parsing it should report as Working status
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.None, PossibleStatus = PossibleStatus.Working });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public interface IPersistImport
|
||||
{
|
||||
void Save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.ImportOptions
|
||||
{
|
||||
public class CsvImportOptions
|
||||
{
|
||||
public string Encoding { get; set; }
|
||||
public string FieldSeparator { get; set; }
|
||||
public CultureInfo ImportCulture { get; set; }
|
||||
public bool StripBackSlash { get; set; }
|
||||
}
|
||||
public class ZeroMethodOptions
|
||||
{
|
||||
public ZeroMethodType ZeroMethodType { get; set; }
|
||||
public double ZeroMethodStart { get; set; }
|
||||
public double ZeroMethodEnd { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using static DTS.Common.Enums.Sensors.SensorConstants;
|
||||
using System.IO;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Slice.Users;
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
using System.Xml.Linq;
|
||||
using DTS.Common.Import.Parsers;
|
||||
using DTS.Common.Storage;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class EQXSensorsParser : ParseVariantBase
|
||||
{
|
||||
private readonly User _currentUser;
|
||||
private readonly IImportNotification _importNotification;
|
||||
private readonly EquipmentExchange.EQXSensorDatabase _eqxSensorDatabase;
|
||||
private readonly EqxImportOptions _eqxImportOptions;
|
||||
public EQXSensorsParser(IImportNotification importNotification, User user, EqxImportOptions eqxImportOptions,
|
||||
EquipmentExchange.EQXSensorDatabase eqxSensorDatabase)
|
||||
{
|
||||
_currentUser = user;
|
||||
_importNotification = importNotification;
|
||||
_eqxSensorDatabase = eqxSensorDatabase;
|
||||
_eqxImportOptions = eqxImportOptions;
|
||||
}
|
||||
|
||||
const float MAX_EQX_VERSION_SUPPORT = 1.5F;
|
||||
public bool ImportCreateDynamicGroups { get; set; }
|
||||
public bool EQXUseSerialNumberFieldForSN { get; set; }
|
||||
public bool UseZeroForUnfiltered { get; set; }
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
if (string.IsNullOrEmpty(FileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (importObject == null)
|
||||
{
|
||||
throw new ArgumentNullException("importObject", "importObject can't be null or empty");
|
||||
}
|
||||
importObject = ParseSensor(importObject, FileName);
|
||||
|
||||
}
|
||||
//FB 44299
|
||||
private static void SetSensorTypeInSensorDataTags(SensorData sensorData, string tag)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tag)) { return; }
|
||||
|
||||
var allTags = new List<string>();
|
||||
//FB 44299 copied the code from DataPRO sensor, I am not sure why it created a copy of SensorData
|
||||
var sensorDataCopy = new SensorData(sensorData);
|
||||
var currentTags = sensorDataCopy.GetTagsArray(DbOperations.TagsGet);
|
||||
if (currentTags != null && currentTags.Any())
|
||||
{
|
||||
allTags.AddRange(currentTags);
|
||||
}
|
||||
|
||||
if (!allTags.Contains(tag))
|
||||
{
|
||||
allTags.Add(tag);
|
||||
}
|
||||
// Set the tags
|
||||
sensorData.SetTags(allTags.ToArray(), DbOperations.GetSQLCommand, DbOperations.TagsGet, DbOperations.TagsGetId, DbOperations.TagsInsert);
|
||||
}
|
||||
/// <summary>
|
||||
/// Adjusts squibs measurement type if appropriate
|
||||
/// http://manuscript.dts.local/f/cases/44299/SW-Re-Implement-GM-ISF-Style-Real-Time-tags-for-EQX-import
|
||||
/// </summary>
|
||||
private void SetSquibMeasurementType(ISensorData sd)
|
||||
{
|
||||
if (sd.IsSquib() && UseInitSignalTOM)
|
||||
{
|
||||
sd.SquibMeasurementType = SquibMeasurementType.INIT_SIGNAL;
|
||||
}
|
||||
}
|
||||
private ImportObject ParseSensor(ImportObject importObject, string filename)
|
||||
{
|
||||
|
||||
int currentDone = 0;
|
||||
var lines = File.ReadAllLines(filename);
|
||||
|
||||
int totalCount = lines.Count();
|
||||
XDocument xDoc = null;
|
||||
try
|
||||
{
|
||||
xDoc = XDocument.Load(filename);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_importNotification.ReportErrors(new List<string>(new[] { StringResources.ImportSensorsPreviewControl_EQXFileXMLError, ex.Message }));
|
||||
|
||||
return importObject;
|
||||
}
|
||||
|
||||
float eQXEdition = MAX_EQX_VERSION_SUPPORT;
|
||||
var fileInfo = xDoc.Elements("Sensors").Select(x => x.Elements("FileInfo")).FirstOrDefault();
|
||||
if (fileInfo.Any())
|
||||
{
|
||||
var eQXEditionString = fileInfo.Select(x => x.Attribute("DataFormatEdition").Value).FirstOrDefault();
|
||||
|
||||
try
|
||||
{
|
||||
eQXEdition = Convert.ToSingle(eQXEditionString, CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_importNotification.ReportErrors(new List<string>(new[] { StringResources.ImportSensorsPreviewControl_EQXVersionReadError }));
|
||||
return importObject;
|
||||
}
|
||||
}
|
||||
if (eQXEdition > MAX_EQX_VERSION_SUPPORT)
|
||||
{
|
||||
_importNotification.ReportErrors(new List<string>(new[] { string.Format(StringResources.ImportSensorsPreviewControl_EQXVersionError, eQXEdition, MAX_EQX_VERSION_SUPPORT) }));
|
||||
return importObject;
|
||||
}
|
||||
|
||||
_eqxSensorDatabase.Read(filename, (List<string> readErrors) => { _importNotification.ReportErrors(readErrors); }, EQXUseSerialNumberFieldForSN, UseZeroForUnfiltered, ImportCreateDynamicGroups);
|
||||
|
||||
var sensors = _eqxSensorDatabase.GetSensors();
|
||||
var lookup = new Dictionary<string, bool>();
|
||||
var increment = Convert.ToInt32(lines.Length / (double)sensors.Length);
|
||||
foreach (var sd in sensors)
|
||||
{
|
||||
var sc = _eqxSensorDatabase.GetCalibrations(sd.UUID);
|
||||
if (0 == currentDone % 10)
|
||||
{
|
||||
_importNotification.SetProgress(100D * currentDone / totalCount);
|
||||
}
|
||||
//check to see if the sensor had a NULL IDModuleString, if so
|
||||
//check for an existing EID and use that rather than wiping out the EID
|
||||
//18467 Missing IDModuleString in e2x file import is clearing the EID on sensor import
|
||||
if (_eqxSensorDatabase.SensorHasNullIDModule(sd.UUID) && _eqxSensorDatabase.GetSensorNullIdModuleValue(sd.UUID))
|
||||
{
|
||||
var existing = SensorsCollection.SensorsList.GetSensorBySerialNumber(sd.SerialNumber);
|
||||
if (null != existing)
|
||||
{
|
||||
sd.EID = existing.EID;
|
||||
}
|
||||
}
|
||||
|
||||
var sensorType = ChannelTypeUtility.ParseSensorKnownChannelType(sd.SerialNumber);
|
||||
SetSensorTypeInSensorDataTags(sd, sensorType);
|
||||
|
||||
SetSquibMeasurementType(sd);
|
||||
|
||||
currentDone += increment;
|
||||
|
||||
if (!string.IsNullOrEmpty(sd.SerialNumber))
|
||||
{
|
||||
importObject.AddSensorLookup(sd.SerialNumber, sd);
|
||||
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(sd.SerialNumber))
|
||||
{
|
||||
importObject.AddCalibrationLookup(sd.SerialNumber, sc);
|
||||
}
|
||||
|
||||
|
||||
// this is for compatability for import test setups
|
||||
if (importObject.Sensors().FirstOrDefault(s => s.SerialNumber == sd.SerialNumber) == null)
|
||||
{
|
||||
importObject.AddSensor(sd);
|
||||
}
|
||||
importObject.AddSensorChannelCodeLookup(sd.SettingName, sd.SerialNumber);
|
||||
// this is for compatability for import test setups
|
||||
importObject.AddCalibrations(sc);
|
||||
|
||||
var key = $"{sd.Manufacturer}_{sd.Model}";
|
||||
sc.Sort();
|
||||
|
||||
if (!lookup.ContainsKey(key) && sc.Any())
|
||||
{
|
||||
var model = FactorySensorModel.CreateModelFromSensor(sd, sc[0], _currentUser);
|
||||
importObject.AddSensorModelLookup(key, model);
|
||||
lookup[key] = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//15609 Sensors not usable after EQX import
|
||||
//warn on invalid excitation problems
|
||||
var errors = GetExcitationErrors();
|
||||
|
||||
//TODO Report the errors
|
||||
|
||||
return importObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns a list of any excitation errors for sensors in the import file
|
||||
/// created for EQX processing
|
||||
/// 15609 Sensors not usable after EQX import
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private List<string> GetExcitationErrors()
|
||||
{
|
||||
if (null == _eqxSensorDatabase) { return new List<string>(); }
|
||||
var errors = new List<string>();
|
||||
var sensors = _eqxSensorDatabase.GetSensors();
|
||||
foreach (var sd in sensors)
|
||||
{
|
||||
switch (sd.Bridge)
|
||||
{
|
||||
case BridgeType.DigitalInput:
|
||||
case BridgeType.SQUIB:
|
||||
case BridgeType.TOMDigital:
|
||||
continue;
|
||||
}
|
||||
|
||||
var hasValidCal = false;
|
||||
if (_eqxSensorDatabase.ContainsCalibration(sd.UUID))
|
||||
{
|
||||
var cals = _eqxSensorDatabase.GetCalibrations(sd.UUID);
|
||||
foreach (var cal in cals)
|
||||
{
|
||||
if (!cal.IsProportional)
|
||||
{
|
||||
hasValidCal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sd.SupportedExcitation.Contains(cal.Records.Records.First().Excitation))
|
||||
{
|
||||
hasValidCal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var error = string.Format(
|
||||
StringResources.Error_SensorNoCalibrationExcitationNotSupported,
|
||||
sd.ToDisplayString(), cal.Records.Records.First().Excitation.ToString());
|
||||
if (!errors.Contains(error)) { errors.Add(error); }
|
||||
}
|
||||
|
||||
switch (cal.Records.Records.First().Excitation)
|
||||
{
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Undefined:
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt2_5:
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt3:
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt1:
|
||||
{
|
||||
var error = string.Format(StringResources.Error_SensorCalibrationNotSupported,
|
||||
sd.ToDisplayString(), cal.Records.Records.First().Excitation.ToString());
|
||||
if (errors.Contains(error)) { errors.Add(error); }
|
||||
}
|
||||
break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt2:
|
||||
break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt5:
|
||||
break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt10:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasValidCal)
|
||||
{
|
||||
var error = string.Format(StringResources.Error_SensorCalibrationNone, sd.ToDisplayString());
|
||||
if (!errors.Contains(error))
|
||||
{
|
||||
errors.Add(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseSensorModels : XMLParseBase
|
||||
{
|
||||
public XMLParseSensorModels(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AddSensorModels(ParseSensorModels(_root));
|
||||
}
|
||||
|
||||
private List<SensorModel> ParseSensorModels(XmlElement root)
|
||||
{
|
||||
List<SensorModel> list = new List<SensorModel>();
|
||||
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return list; }
|
||||
if (!(node is XmlElement)) continue;
|
||||
var sm = new SensorModel();
|
||||
sm.ReadXML(node as XmlElement);
|
||||
list.Add(sm);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class ParseProcessor
|
||||
{
|
||||
private readonly IEnumerable<string> _fileNames;
|
||||
private ImportObject _importObject;
|
||||
private readonly IEnumerable<IParseVariant> _parseVariants;
|
||||
|
||||
public ParseProcessor(ImportObject importObject, IEnumerable<string> fileNames, IEnumerable<IParseVariant> parseVariants)
|
||||
{
|
||||
_fileNames = fileNames;
|
||||
_importObject = importObject;
|
||||
_parseVariants = parseVariants;
|
||||
}
|
||||
public ImportObject Process()
|
||||
{
|
||||
foreach (var fileName in _fileNames)
|
||||
{
|
||||
foreach (var variant in _parseVariants)
|
||||
{
|
||||
variant.FileName = fileName;
|
||||
variant.Parse(ref _importObject);
|
||||
}
|
||||
}
|
||||
return _importObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveUsers : SaveVariantBase
|
||||
{
|
||||
public IUIItems[] UIItems { get; set; }
|
||||
public User CurrentUser { get; set; }
|
||||
public SaveUsers(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingUsers, PossibleStatus = PossibleStatus.Importing });
|
||||
foreach (var user in _importObject.Users())
|
||||
{
|
||||
if (IsCancelled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
System.Diagnostics.Trace.Assert(CurrentUser.IsAdmin, "importing users from a non admin user. [should have been prevented earlier up chain]");
|
||||
|
||||
UserCollection.UsersList.Commit(user,
|
||||
CurrentUser.UserName, UIItems);
|
||||
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseMMECustomPositions : XMLParseBase
|
||||
{
|
||||
public XMLParseMMECustomPositions(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AddCustomPositions(ParsePhysicalDimensions(_root));
|
||||
}
|
||||
|
||||
private IEnumerable<ISO.MMEPositions> ParsePhysicalDimensions(XmlElement root)
|
||||
{
|
||||
List<ISO.MMEPositions> list = new List<ISO.MMEPositions>();
|
||||
|
||||
foreach (var child in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return list; }
|
||||
if (child is XmlElement)
|
||||
{
|
||||
list.Add(ISO.MMEPositions.ReadXML(child as XmlElement));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public interface IParseImport
|
||||
{
|
||||
ImportObject Parse(IEnumerable<string> importFiles);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.Parsers
|
||||
{
|
||||
public abstract class ParseVariantBase : IParseVariant
|
||||
{
|
||||
public string FileName { get; set; }
|
||||
|
||||
public abstract void Parse(ref ImportObject importObject);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseGlobalSettings : XMLParseBase
|
||||
{
|
||||
public XMLParseGlobalSettings(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AssignGlobalSettings(ParseGlobalSettings(_root));
|
||||
}
|
||||
|
||||
private Dictionary<string, string> ParseGlobalSettings(XmlElement root)
|
||||
{
|
||||
Dictionary<string, string> settings = new Dictionary<string, string>();
|
||||
|
||||
foreach (var child in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return settings; }
|
||||
if (child is XmlElement)
|
||||
{
|
||||
GetGlobalSetting(child as XmlElement, ref settings);
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
private void GetGlobalSetting(XmlElement node, ref Dictionary<string, string> settings)
|
||||
{
|
||||
string sName = "", sValue = "";
|
||||
foreach (var child in node.ChildNodes)
|
||||
{
|
||||
if (child is XmlElement)
|
||||
{
|
||||
var childNode = child as XmlElement;
|
||||
switch (childNode.Name)
|
||||
{
|
||||
case "SettingName":
|
||||
sName = childNode.InnerText;
|
||||
break;
|
||||
case "SettingValue":
|
||||
sValue = childNode.InnerText;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(sName))
|
||||
{
|
||||
settings[sName] = sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using System;
|
||||
|
||||
namespace DTS.Common.Import.Parsers.CSV
|
||||
{
|
||||
public class Version3CSVSensorParser : AbstractCSVParser
|
||||
{
|
||||
public override int Version => 3;
|
||||
public override void ParseVersion(CSVImportTags.Tags field, string sVal, ParseParameters pp)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case CSVImportTags.Tags.GroupName:
|
||||
// check sval for empty
|
||||
if (string.IsNullOrEmpty(sVal) || string.IsNullOrWhiteSpace(sVal))
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.ImportSensorsPreviewControl_CSVImport_NoGroupNameFound, pp.SensorData.SerialNumber));
|
||||
return;
|
||||
}
|
||||
// check duplicate sd.serialnumber
|
||||
if (pp.SensorGroupNameLookup.ContainsKey(pp.SensorData.SerialNumber))
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.ImportSensorsPreviewControl_CSVImport_DuplicateSensorSN, pp.SensorData.SerialNumber));
|
||||
return;
|
||||
}
|
||||
pp.SensorGroupNameLookup.Add(pp.SensorData.SerialNumber, sVal);
|
||||
if (!pp.GroupNameToTestObjectLookup.ContainsKey(sVal))
|
||||
{
|
||||
pp.GroupNameToTestObjectLookup.Add(sVal, pp.SensorTestObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pp.GroupNameToTestObjectLookup[sVal] != pp.SensorTestObject && !ImportCreateDynamicGroups)
|
||||
{
|
||||
var errorMessage =
|
||||
string.Format(StringResources.CSVImportMultipleTestObjectsInGroup,
|
||||
sVal);
|
||||
if (!pp.Errors.Contains(errorMessage))
|
||||
{
|
||||
pp.Errors.Add(errorMessage);
|
||||
}
|
||||
throw new Exception("Parse error");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.GroupType:
|
||||
// check sval for empty
|
||||
if (string.IsNullOrEmpty(sVal) || string.IsNullOrWhiteSpace(sVal))
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.ImportSensorsPreviewControl_CSVImport_NoGroupTypeFound, pp.SensorData.SerialNumber));
|
||||
return;
|
||||
}
|
||||
// check duplicate sd.serialnumber
|
||||
if (pp.SensorGroupTypeLookup.ContainsKey(pp.SensorData.SerialNumber))
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.ImportSensorsPreviewControl_CSVImport_DuplicateSensorSN, pp.SensorData.SerialNumber));
|
||||
return;
|
||||
}
|
||||
pp.SensorGroupTypeLookup.Add(pp.SensorData.SerialNumber, sVal);
|
||||
break;
|
||||
case CSVImportTags.Tags.Unknown: break;
|
||||
default: throw new NotSupportedException("Unknown field: " + field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DataPROWin7.DataModel.Classes.Hardware;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
//FB 38039 Refactored the common methods for save test setup
|
||||
public static class SaveTestSetupHelper
|
||||
{
|
||||
|
||||
public static void AddHardwareFromEmbeddedGroups(TestTemplate t, SaveGroups saveGroups, List<int> hardwareRemoved, List<int> hardwareIncluded)
|
||||
{
|
||||
//finally add hardware from embedded groups
|
||||
foreach (var group in t.Groups)
|
||||
{
|
||||
//Set the StaticGroupId if this embedded Group came from a static Group
|
||||
if (group.StaticGroupId != null && saveGroups != null && saveGroups.OldGroupIdToNewGroupId.ContainsKey(group.StaticGroupId))
|
||||
{
|
||||
group.StaticGroupId = saveGroups?.OldGroupIdToNewGroupId[group.StaticGroupId];
|
||||
}
|
||||
foreach (var hid in group.IncludedHardware)
|
||||
{
|
||||
if (hardwareRemoved.Contains(hid)) { continue; }
|
||||
if (!hardwareIncluded.Contains(hid))
|
||||
{
|
||||
hardwareIncluded.Add(hid);
|
||||
}
|
||||
}
|
||||
}
|
||||
t.AddedHardware = hardwareIncluded.ToArray();
|
||||
t.RemovedHardware = hardwareRemoved.ToArray();
|
||||
}
|
||||
public static void FixDasAff(Dictionary<string, DASHardware> hardwareLookup, TestTemplate t)
|
||||
{
|
||||
//FB15759: If we had to skip setting DAS AAF on the file prep side (freq == 0), fix it now.
|
||||
for (int i = 0; i < t.DASAAFRateList.Count; i++)
|
||||
{
|
||||
var key = t.DASAAFRateList.ElementAt(i).Key;
|
||||
if (0 == t.DASAAFRateList[key] && hardwareLookup.ContainsKey(key))
|
||||
{
|
||||
t.DASAAFRateList[key] = TestTemplate.GetAAFForHardware(hardwareLookup[key], (int)t.DASSampleRateList[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, DASHardware> PopulateHarwareLookup()
|
||||
{
|
||||
var hardwareLookup = new Dictionary<string, DASHardware>();
|
||||
foreach (var h in DASHardwareList.GetAllHardware())
|
||||
{
|
||||
hardwareLookup[h.SerialNumber] = h;
|
||||
}
|
||||
|
||||
return hardwareLookup;
|
||||
}
|
||||
|
||||
public static void DeleteExistingTestSetups(IEnumerable<TestTemplate> testSetups, string userName)
|
||||
{
|
||||
var testArray = testSetups?.ToArray();
|
||||
var testNames = new List<string>(testArray?.Select(p => p.Name));
|
||||
TestTemplateList.TestTemplatesList.DeleteTestSetups(testNames, userName);
|
||||
}
|
||||
public static void UpdateLevelTriggers(ref Dictionary<string, string> oldIdToNewIdLookup, SaveCustomChannels saveCustomChannels, IEnumerable<TestTemplate> testSetups)
|
||||
{
|
||||
//now that all the groups are committed, see what now is, and update what once was in level triggers to what now is.
|
||||
//note we could do it with the channel remaps lookup above ...
|
||||
|
||||
foreach (var eChannelText in saveCustomChannels.CustomChannelTextIdToOldChannelId)
|
||||
{
|
||||
var isocode = eChannelText.Key;
|
||||
var oldId = eChannelText.Value;
|
||||
var newCustomChannel = CustomChannelList.List.GetChannelByISOCode(isocode, false);
|
||||
if (null == newCustomChannel) continue;
|
||||
var oldCH = saveCustomChannels.CustomChannelOldChannelIdToChannel[oldId];
|
||||
var newId = oldCH.GetIdWithSpecificChannelId(newCustomChannel.Channel.Id);
|
||||
oldIdToNewIdLookup[oldId] = newId;
|
||||
foreach (var t in testSetups)
|
||||
{
|
||||
t.ReplaceLevelTriggerChannel(oldId, newId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class DTSXMLParseImport : IParseImport
|
||||
{
|
||||
|
||||
private ImportObject _importObject;
|
||||
private readonly Func<bool> _isCancelled;
|
||||
private readonly IImportNotification _importNotification;
|
||||
public List<IUIItems> UIItems { get; set; }
|
||||
public DTSXMLParseImport(ImportObject importObject, IImportNotification importNotification, Func<bool> isCancelled = null)
|
||||
{
|
||||
_isCancelled = isCancelled;
|
||||
_importObject = importObject;
|
||||
_importNotification = importNotification;
|
||||
}
|
||||
public ImportObject Parse(IEnumerable<string> importFiles)
|
||||
{
|
||||
XMLParseProcessor parseProcesser = new XMLParseProcessor(_importObject, _importNotification, importFiles, _isCancelled);
|
||||
parseProcesser.UIItems = UIItems;
|
||||
_importObject = parseProcesser.Process();
|
||||
AssignLinkedDASSerials(ref _importObject);
|
||||
return _importObject;
|
||||
}
|
||||
|
||||
private void AssignLinkedDASSerials(ref ImportObject importObject)
|
||||
{
|
||||
foreach (var h in importObject.Hardware())
|
||||
{
|
||||
if (!h.IsPseudoRack()) continue;
|
||||
var matches = from hw in importObject.Hardware() where hw.ParentDAS == h.SerialNumber select hw.SerialNumber;
|
||||
var enumerable = matches as string[] ?? matches.ToArray();
|
||||
if (enumerable.Any())
|
||||
{
|
||||
h.LinkedDASSerials = enumerable.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
using DTS.Common.Import.Parsers;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.SensorDB;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class EQXTestSetupParser : ParseVariantBase
|
||||
{
|
||||
private readonly IImportNotification _importNotification;
|
||||
private readonly EqxImportOptions _eqxImportOptions;
|
||||
private readonly IGroupImport _groupImport;
|
||||
private readonly EquipmentExchange.EQXSensorDatabase _eqxSensorDatabase;
|
||||
private readonly bool _createDynamicGroups;
|
||||
public EQXTestSetupParser(IImportNotification importNotification, EqxImportOptions eqxImportOptions,
|
||||
IGroupImport groupImport, EquipmentExchange.EQXSensorDatabase eqxSensorDatabase, bool createDynamicGroups)
|
||||
{
|
||||
_eqxImportOptions = eqxImportOptions;
|
||||
_importNotification = importNotification;
|
||||
_groupImport = groupImport;
|
||||
_eqxSensorDatabase = eqxSensorDatabase;
|
||||
_createDynamicGroups = createDynamicGroups;
|
||||
}
|
||||
private void FixCalibrations(ImportObject importObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sensors = importObject.Sensors().ToArray();
|
||||
foreach (var sensor in sensors)
|
||||
{
|
||||
if (null == sensor) { continue; }
|
||||
var cals = importObject.CalibrationLookup(sensor.SerialNumber);
|
||||
if (null != cals && cals.Count > 0)
|
||||
{
|
||||
cals.Sort();
|
||||
sensor.Calibration = cals[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("EQXTestSetupParser.FixCalibrations failed to fix calibrations", ex);
|
||||
}
|
||||
}
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
if (string.IsNullOrEmpty(FileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (importObject == null)
|
||||
{
|
||||
throw new ArgumentNullException("importObject", "importObject can't be null or empty");
|
||||
}
|
||||
|
||||
var sensorImportData = _eqxSensorDatabase.GetImportData();
|
||||
//FB 40750 if there is not Group name test then the eqx file does not have any test setup
|
||||
if (sensorImportData.GroupNameTestObjectLookup == null || !sensorImportData.GroupNameTestObjectLookup.Any())
|
||||
{
|
||||
//abort the import process
|
||||
importObject.AddError(new ImportError { ContinueImportOnError = false, Message = StringResources.Import_EQXFileNotForTestSetup, Severity = ImportSeverityError.Critical });
|
||||
return;
|
||||
}
|
||||
|
||||
importObject.AssignGroupNameTestObjectLookup(sensorImportData.GroupNameTestObjectLookup);
|
||||
importObject.AssignGroupNameSensorsLookup(sensorImportData.GroupNameSensorListLookup);
|
||||
|
||||
var testTemplate = new TestTemplate();
|
||||
var setupName = ParseSetupName(FileName);
|
||||
testTemplate.Name = setupName == string.Empty ? Path.GetFileNameWithoutExtension(FileName) : setupName;
|
||||
|
||||
if (importObject.TestSetups().Any(p => p.Name == testTemplate.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FixCalibrations(importObject);
|
||||
|
||||
var res = AssignGroupsToTestSetup(testTemplate, importObject, sensorImportData.GroupNameSensorListLookup,
|
||||
_groupImport, _importNotification);
|
||||
|
||||
var sensors = res.Item3;
|
||||
var testSetup = res.Item1;
|
||||
var staticGroups = res.Item2;
|
||||
|
||||
if (staticGroups != null)
|
||||
{
|
||||
importObject.AddStaticGroups(staticGroups);
|
||||
}
|
||||
var cleanedSensors = GroupHelper.CleanUneededSensorDataPlaceHolder(importObject.CalibrationsLookup(), sensors);
|
||||
|
||||
importObject.ClearSensors();
|
||||
importObject.AddSensors(cleanedSensors);
|
||||
|
||||
importObject.AddTestSetup(testSetup);
|
||||
//FB 38039,40758 Identify single test setup in import file
|
||||
importObject.TestSetupImportFileFormat = importObject.GetImportFileFormat();
|
||||
}
|
||||
|
||||
//FB 36879 Single repsposibility principle , moved the method to this class
|
||||
private Tuple<TestTemplate, List<IGroup>, List<SensorData>> AssignGroupsToTestSetup(TestTemplate testTemplate, ImportObject importObject, Dictionary<string, List<string>> groupNameSensorListLookup,
|
||||
IGroupImport groupImport, IImportNotification importNotification)
|
||||
{
|
||||
var sensorGroupNameLookup = importObject.SensorGroupNamesLookup();
|
||||
var existingStaticGroups = importObject.StaticGroups().ToList();
|
||||
var sensors = importObject.Sensors().ToList();
|
||||
try
|
||||
{
|
||||
_ = GroupHelper.ReverseChannelOrder(testTemplate, sensorGroupNameLookup, sensors);
|
||||
|
||||
var groupSensorLookup = groupImport.GetGroupSensorLookup(sensors, sensorGroupNameLookup, groupNameSensorListLookup);
|
||||
|
||||
sensors = GroupHelper.NormalizeSensorIds(sensors);
|
||||
//http://manuscript.dts.local/f/cases/44105/EQX-Import-does-not-overwrite-zero-method-consistently-in-the-parameters-of-test-setup-but-consistently-for-sensor-database
|
||||
//normalizesensorids above can reset the calibrations for sensors - revert back to the calibration in the import ...
|
||||
FixCalibrations(importObject);
|
||||
//FB 36905
|
||||
var testAndGroups = groupImport.CreateGroups(sensors, groupSensorLookup, testTemplate, _createDynamicGroups, existingStaticGroups, importNotification.SetProgress);
|
||||
|
||||
if (testAndGroups == null)
|
||||
{
|
||||
TestTemplate noTestSetup = null;
|
||||
List<IGroup> noGroup = null;
|
||||
return Tuple.Create(noTestSetup, noGroup, sensors);
|
||||
}
|
||||
return Tuple.Create(testAndGroups.Item1, testAndGroups.Item2, sensors);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
importNotification.ReportErrors(new List<string> { ex.Message });
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//FB 39054 parse setup name from eqx
|
||||
private string ParseSetupName(string filename)
|
||||
{
|
||||
XDocument xDoc = null;
|
||||
try
|
||||
{
|
||||
xDoc = XDocument.Load(filename);
|
||||
var fields = xDoc.Elements("Sensors").Select(x => x.Elements("Fields")).FirstOrDefault();
|
||||
if (fields.Any())
|
||||
{
|
||||
var setupName = fields.Select(x => x.Element("SetupName").Value).FirstOrDefault();
|
||||
return setupName;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
class SaveServer : SaveVariantBase
|
||||
{
|
||||
|
||||
public SaveServer(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using CsvHelper;
|
||||
using DTS.Common.Classes;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Import.Parsers.CSV
|
||||
{
|
||||
public class Version0CSVTestParser : IParseCSVTest
|
||||
{
|
||||
public int Version => 0;
|
||||
public void ParseVersion(CsvReader csvReader, TestSetupImportData tsid)
|
||||
{
|
||||
var tokens = CsvUtil.ReadFields(csvReader);
|
||||
|
||||
if (null == tokens || tokens[0] != "Version")
|
||||
{
|
||||
return;
|
||||
}
|
||||
var tokens2 = CsvUtil.ReadFields(csvReader);
|
||||
|
||||
if (null == tokens2) { return; }
|
||||
|
||||
for (var i = 0; i < tokens.Count && i < tokens2.Count; i++)
|
||||
{
|
||||
GetValueForField(tsid, tokens, tokens2, i);
|
||||
}
|
||||
}
|
||||
|
||||
private static double ParseDoubleValue(string val)
|
||||
{
|
||||
return double.TryParse(val, out var iTemp) ? iTemp : default(double);
|
||||
}
|
||||
|
||||
private static void GetValueForField(TestSetupImportData testSetupImportData, List<string> tokens, List<string> tokens2, int index)
|
||||
{
|
||||
var field = CSVImportTags.GetTagForString(tokens[index]);
|
||||
var val = tokens2[index];
|
||||
switch (field)
|
||||
{
|
||||
case CSVImportTags.Tags.PostTriggerSec:
|
||||
testSetupImportData.PosttriggerSeconds = ParseDoubleValue(val);
|
||||
break;
|
||||
case CSVImportTags.Tags.PreTriggerSec:
|
||||
{
|
||||
testSetupImportData.PretriggerSeconds = ParseDoubleValue(val);
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.RecordingMode:
|
||||
{
|
||||
testSetupImportData.RecordingMode = Enum.TryParse(val, out RecordingModes mode) ? mode : default;
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.SampleRate:
|
||||
{
|
||||
testSetupImportData.SamplesPerSecond = ParseDoubleValue(val);
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.TestSetupDescription:
|
||||
testSetupImportData.Description = val;
|
||||
break;
|
||||
case CSVImportTags.Tags.TestSetupName:
|
||||
testSetupImportData.Name = val;
|
||||
break;
|
||||
case CSVImportTags.Tags.Version:
|
||||
{
|
||||
testSetupImportData.Version = int.TryParse(val, out var iTemp) ? iTemp : default;
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.Tags:
|
||||
testSetupImportData.Tags = val.Split(';').ToList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseMMECustomFineLoc3s : XMLParseBase
|
||||
{
|
||||
public XMLParseMMECustomFineLoc3s(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AddCustomFineLoc3s(ParseCustomFineLoc3s(_root));
|
||||
}
|
||||
|
||||
private IEnumerable<ISO.MMEFineLocations3> ParseCustomFineLoc3s(XmlElement root)
|
||||
{
|
||||
List<ISO.MMEFineLocations3> list = new List<ISO.MMEFineLocations3>();
|
||||
|
||||
foreach (var child in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return list; }
|
||||
if (child is XmlElement)
|
||||
{
|
||||
list.Add(ISO.MMEFineLocations3.ReadXML(child as XmlElement));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Import.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveTestEngineerDetails : SaveVariantBase
|
||||
{
|
||||
public SaveTestEngineerDetails(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingEngineerDetails, PossibleStatus = PossibleStatus.Importing });
|
||||
foreach (var t in _importObject.TestEngineerDetails())
|
||||
{
|
||||
if (IsCancelled()) { return; }
|
||||
|
||||
else { TestEngineerDetailsList.TestEngineerList.AddTestEngineer(new TestEngineerDetails(t)); }
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{C1BC06F4-8657-4892-BC4D-1064DA01C4C7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>DTS.Common.Import</RootNamespace>
|
||||
<AssemblyName>DTS.Common.Import</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CsvHelper, Version=33.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\DTS.Common\lib\CsvHelper33.0.1\CsvHelper.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CalibrationImport.cs" />
|
||||
<Compile Include="CsvUtil.cs" />
|
||||
<Compile Include="ImportError.cs" />
|
||||
<Compile Include="Parsers\CSV\CSVFile.cs" />
|
||||
<Compile Include="DatabaseLocks\LockImportGroups.cs" />
|
||||
<Compile Include="DatabaseLocks\LockImportSensors.cs" />
|
||||
<Compile Include="DatabaseLocks\LockImportTestSetups.cs" />
|
||||
<Compile Include="Parsers\EQX\EQXGroupImport.cs" />
|
||||
<Compile Include="Factories\CSVSensorParserFactory.cs" />
|
||||
<Compile Include="Factories\CSVTestParserFactory.cs" />
|
||||
<Compile Include="Factories\DatabaseLocksFactory.cs" />
|
||||
<Compile Include="Factories\SaveVariantFactory.cs" />
|
||||
<Compile Include="Factories\XmlParserFactory.cs" />
|
||||
<Compile Include="ImportOptions\EqxImportOptions.cs" />
|
||||
<Compile Include="Interfaces\ILockImport.cs" />
|
||||
<Compile Include="Interfaces\IParseCSVSensor.cs" />
|
||||
<Compile Include="Interfaces\IParseCSVTest.cs" />
|
||||
<Compile Include="Parsers\CSV\AbstractCSVParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version0CSVSensorParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version0CSVTestParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version2CSVSensorParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version3CSVSensorParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version4CSVSensorParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version5CSVTestParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version6CSVTestParser.cs" />
|
||||
<Compile Include="Parsers\CSV\DTSCSVSensorsParser.cs" />
|
||||
<Compile Include="Parsers\CSV\DTSCSVTestSetupParser.cs" />
|
||||
<Compile Include="Interfaces\ICalibrationImport.cs" />
|
||||
<Compile Include="ImportOptions\CsvImportOptions.cs" />
|
||||
<Compile Include="Interfaces\IGroupImport.cs" />
|
||||
<Compile Include="ImportNotification.cs" />
|
||||
<Compile Include="Interfaces\IParseVariant.cs" />
|
||||
<Compile Include="ParseProcessor.cs" />
|
||||
<Compile Include="Parsers\DTSXMLParseImport.cs" />
|
||||
<Compile Include="Parsers\CSV\CSVGroupImport.cs" />
|
||||
<Compile Include="ImportObject.cs" />
|
||||
<Compile Include="Interfaces\IParseImport.cs" />
|
||||
<Compile Include="Interfaces\IPersistImport.cs" />
|
||||
<Compile Include="Parsers\DefaultParseImport.cs" />
|
||||
<Compile Include="Parsers\EQX\EQXSensorsParser.cs" />
|
||||
<Compile Include="Parsers\EQX\EQXTestSetupParser.cs" />
|
||||
<Compile Include="Parsers\ParseVariantBase.cs" />
|
||||
<Compile Include="Persist\PersistCalculator.cs" />
|
||||
<Compile Include="Persist\SaveCheckoutTestSetup.cs" />
|
||||
<Compile Include="Persist\SaveCustomChannels.cs" />
|
||||
<Compile Include="Persist\SaveGlobalSettings.cs" />
|
||||
<Compile Include="Persist\SaveGroups.cs" />
|
||||
<Compile Include="Persist\SaveGroupTemplates.cs" />
|
||||
<Compile Include="Persist\SaveHardware.cs" />
|
||||
<Compile Include="Persist\SaveLabDetails.cs" />
|
||||
<Compile Include="Persist\SaveSensor.cs" />
|
||||
<Compile Include="Persist\SaveSensorModels.cs" />
|
||||
<Compile Include="Persist\SaveServer.cs" />
|
||||
<Compile Include="Persist\SaveTestEngineerDetails.cs" />
|
||||
<Compile Include="Persist\SaveTestSetup.cs" />
|
||||
<Compile Include="Persist\SaveTestSetupHelper.cs" />
|
||||
<Compile Include="Persist\SaveUsers.cs" />
|
||||
<Compile Include="Persist\SaveVariantBase.cs" />
|
||||
<Compile Include="Persist\SaveCustomerDetails.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="GroupHelper.cs" />
|
||||
<Compile Include="TsetSetupImportSensorInfo.cs" />
|
||||
<Compile Include="XMLParseProcessor.cs" />
|
||||
<Compile Include="XML\XMLParseCustomerDetails.cs" />
|
||||
<Compile Include="XML\XMLParseDASList.cs" />
|
||||
<Compile Include="XML\XMLParseGlobalSettings.cs" />
|
||||
<Compile Include="XML\XMLParseGroupTemplates.cs" />
|
||||
<Compile Include="XML\XMLParseLabDetails.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomChannels.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomDirections.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomFilterClasses.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomFineLoc1s.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomFineLoc2s.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomFineLoc3s.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomMainLocations.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomPhysicalDimensions.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomPositions.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomTestObjects.cs" />
|
||||
<Compile Include="XML\XMLParseSensorModels.cs" />
|
||||
<Compile Include="XML\XMLParseTestEngineerDetails.cs" />
|
||||
<Compile Include="XML\XMLParseUsers.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseDASList.cs" />
|
||||
<Compile Include="XML\XMLParseGroups.cs" />
|
||||
<Compile Include="XML\XMLParseSensors.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseCalibrations.cs" />
|
||||
<Compile Include="XML\XMLParseBase.cs" />
|
||||
<Compile Include="XML\XMLParseCalibrations.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseGroups.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseGroupTemplates.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseSensors.cs" />
|
||||
<Compile Include="XML\XMLParseTestSetups.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseTestSetups.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\DataPRO\EquipmentExchange\EquipmentExchange.csproj">
|
||||
<Project>{2513797d-ec82-48d5-969e-6b3b5e6002e3}</Project>
|
||||
<Name>EquipmentExchange</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\DataPRO\SensorDB\SensorDB.csproj">
|
||||
<Project>{444ef10c-046e-47ad-a9a5-17318d488723}</Project>
|
||||
<Name>SensorDB</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\DataPRO\Users\Users.csproj">
|
||||
<Project>{be8d217d-6da9-4bca-b62a-a82325b33979}</Project>
|
||||
<Name>Users</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.DAS.Concepts\DTS.Common.DAS.Concepts.csproj">
|
||||
<Project>{AE3987F7-C4C6-40FB-A353-1A2DADEF7A9A}</Project>
|
||||
<Name>DTS.Common.DAS.Concepts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.DataModel\DTS.Common.DataModel.csproj">
|
||||
<Project>{2a2f03a9-bf85-4360-a06a-cf3016d2633b}</Project>
|
||||
<Name>DTS.Common.DataModel</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.ISO\DTS.Common.ISO.csproj">
|
||||
<Project>{27d0c63b-9095-42da-95fd-f64444c80558}</Project>
|
||||
<Name>DTS.Common.ISO</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.Serialization\DTS.Common.Serialization.csproj">
|
||||
<Project>{0679d014-59c2-4327-b288-0e3bd1374710}</Project>
|
||||
<Name>DTS.Common.Serialization</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.SettingsDB\DTS.Common.Settings.csproj">
|
||||
<Project>{61017104-d8ee-41d1-b9ca-dad863ff78b2}</Project>
|
||||
<Name>DTS.Common.Settings</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.SharedResource\DTS.Common.SharedResource.csproj">
|
||||
<Project>{c01e723f-86e2-403a-864c-9f56bdb60b8d}</Project>
|
||||
<Name>DTS.Common.SharedResource</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.Storage\DTS.Common.Storage.csproj">
|
||||
<Project>{e3be457c-0ac7-4a9c-bc81-eafeb3217878}</Project>
|
||||
<Name>DTS.Common.Storage</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.Utilities\DTS.Common.Utilities.csproj">
|
||||
<Project>{D6DA1B74-C711-43C2-91B1-1908A8D04DBF}</Project>
|
||||
<Name>DTS.Common.Utilities</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common\DTS.Common.csproj">
|
||||
<Project>{f7a0804f-61a4-40ae-83d0-f1137622b592}</Project>
|
||||
<Name>DTS.Common</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseMMECustomTestObjects : XMLParseBase
|
||||
{
|
||||
public XMLParseMMECustomTestObjects(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AddTestObjects(ParseCustomTestObjects(_root));
|
||||
}
|
||||
|
||||
public IEnumerable<ISO.MMETestObjects> ParseCustomTestObjects(XmlElement root)
|
||||
{
|
||||
List<ISO.MMETestObjects> list = new List<ISO.MMETestObjects>();
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return list; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
list.Add(ISO.MMETestObjects.ReadXML(node as XmlElement));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLPre20ParseCalibrations : XMLParseBase
|
||||
{
|
||||
private readonly XMLParseCalibrations _xmlParseCalibrations;
|
||||
public XMLPre20ParseCalibrations(XmlElement root, double importedVersion, XMLParseCalibrations xmlParseCalibrations, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_xmlParseCalibrations = xmlParseCalibrations;
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
var calibrations = ParsePre20Calibrations(ref importObject);
|
||||
if (calibrations == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var newRoot = _xmlParseCalibrations.ConvertCalibrations(calibrations);
|
||||
if (newRoot == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
importObject.AddCalibrations(_xmlParseCalibrations.ParseCalibrations(newRoot));
|
||||
}
|
||||
|
||||
private void AddToSensor(SensorCalibration sc, ref ImportObject importObject)
|
||||
{
|
||||
if (sc == null) { return; }
|
||||
var sensor = importObject.Sensors().FirstOrDefault(s => s.SerialNumber == sc.SerialNumber);
|
||||
if (sensor != null)
|
||||
{
|
||||
sensor.Calibration = sc;
|
||||
}
|
||||
}
|
||||
private IEnumerable<SensorCalibration> ParsePre20Calibrations(ref ImportObject importObject)
|
||||
{
|
||||
List<SensorCalibration> scs = new List<SensorCalibration>();
|
||||
if (_importedVersion >= FileUtils.DataPROPre20XmlVersion)
|
||||
{
|
||||
foreach (var node in _root.ChildNodes)
|
||||
{
|
||||
if (node is XmlElement)
|
||||
{
|
||||
var sc = new SensorCalibration();
|
||||
sc.ReadXML(node as XmlElement);
|
||||
scs.Add(sc);
|
||||
AddToSensor(sc, ref importObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_importedVersion == 1.0D)
|
||||
{
|
||||
foreach (var node in _root.ChildNodes)
|
||||
{
|
||||
if (node is XmlElement)
|
||||
{
|
||||
var sc = new SensorCalibration();
|
||||
sc.ReadXML(node as XmlElement);
|
||||
|
||||
sc.Records.Records[0].AtCapacity = false;
|
||||
|
||||
if (sc.NonLinear)
|
||||
{
|
||||
sc.Records.Records[0].SensitivityUnits = SensorConstants.SensUnits.NONE;
|
||||
}
|
||||
else if (sc.IsProportional)
|
||||
{
|
||||
sc.Records.Records[0].SensitivityUnits = SensorConstants.SensUnits.mVperVperEU;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.Records.Records[0].SensitivityUnits = SensorConstants.SensUnits.mVperEU;
|
||||
}
|
||||
scs.Add(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
return scs;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class XMLParseProcessor
|
||||
{
|
||||
private readonly IEnumerable<string> _fileNames;
|
||||
private ImportObject _importObject;
|
||||
private readonly IImportNotification _importNotification;
|
||||
private readonly Func<bool> _isCancelled;
|
||||
public List<IUIItems> UIItems { get; set; }
|
||||
|
||||
public XMLParseProcessor(ImportObject importObject, IImportNotification importNotification, IEnumerable<string> fileNames, Func<bool> isCancelled)
|
||||
{
|
||||
_fileNames = fileNames;
|
||||
_importObject = importObject;
|
||||
_importNotification = importNotification;
|
||||
_isCancelled = isCancelled;
|
||||
}
|
||||
public ImportObject Process()
|
||||
{
|
||||
foreach (var fileName in _fileNames)
|
||||
{
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingXML, PossibleStatus = PossibleStatus.Working });
|
||||
XmlParserFactory.UIItems = UIItems;
|
||||
var parseVariants = XmlParserFactory.CreateXMLParsers(fileName, _importNotification, _isCancelled);
|
||||
//FB 36879 Prevent exception if there is no variants to parse
|
||||
double itemsToComplete = 0;
|
||||
if (parseVariants.Any())
|
||||
{
|
||||
itemsToComplete = XMLUtils.DTSXMLFile.GetItemsToCompleteCount(fileName);
|
||||
}
|
||||
|
||||
foreach (var variant in parseVariants)
|
||||
{
|
||||
variant.Parse(ref _importObject);
|
||||
NotifyProgress(itemsToComplete);
|
||||
|
||||
}
|
||||
}
|
||||
return _importObject;
|
||||
}
|
||||
|
||||
private void NotifyProgress(double itemsToComplete)
|
||||
{
|
||||
if (itemsToComplete <= 0) { return; }
|
||||
|
||||
var completed = _importObject.Calibrations().Count() + _importObject.Sensors().Count() + _importObject.CustomChannels().Count()
|
||||
+ _importObject.Groups().Count() + _importObject.GroupTemplates().Count() +
|
||||
_importObject.TestSetups().Count() + _importObject.Hardware().Count()
|
||||
+ _importObject.CustomerDetails().Count() + _importObject.TestEngineerDetails().Count() + _importObject.LabDetails().Count();
|
||||
|
||||
double progress = completed / itemsToComplete;
|
||||
if (progress >= 1)
|
||||
{
|
||||
progress = 1;
|
||||
}
|
||||
_importNotification.SetProgress(progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseMMECustomPhysicalDimensions : XMLParseBase
|
||||
{
|
||||
public XMLParseMMECustomPhysicalDimensions(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AddCustomPhysicalDimensions(ParsePhysicalDimensions(_root));
|
||||
}
|
||||
|
||||
private IEnumerable<ISO.MMEPhysicalDimensions> ParsePhysicalDimensions(XmlElement root)
|
||||
{
|
||||
List<ISO.MMEPhysicalDimensions> list = new List<ISO.MMEPhysicalDimensions>();
|
||||
|
||||
foreach (var child in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return list; }
|
||||
if (child is XmlElement)
|
||||
{
|
||||
list.Add(ISO.MMEPhysicalDimensions.ReadXML(child as XmlElement));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Classes;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.Common.Import.Factories;
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
using DTS.Common.Import.Parsers;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.Common.Storage;
|
||||
using DTS.SensorDB;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class DTSCSVTestSetupParser : ParseVariantBase
|
||||
{
|
||||
private readonly IImportNotification _importNotification;
|
||||
private readonly CsvImportOptions _csvImportOptions;
|
||||
private readonly TestSetupImportData _defaultsTestSetupImportData;
|
||||
private readonly IGroupImport _groupImport;
|
||||
//FB 36905
|
||||
private readonly bool _createDynamicGroups;
|
||||
public DTSCSVTestSetupParser(IImportNotification importNotification, CsvImportOptions csvImportOptions, TestSetupImportData testSetupImportData, IGroupImport groupImport, bool createDynamicGroups)
|
||||
{
|
||||
_csvImportOptions = csvImportOptions;
|
||||
_defaultsTestSetupImportData = testSetupImportData;
|
||||
_importNotification = importNotification;
|
||||
_groupImport = groupImport;
|
||||
_createDynamicGroups = createDynamicGroups;
|
||||
}
|
||||
|
||||
public static TestTemplate CreateTestSetup(TestSetupImportData tsid, DASHardware[] allDAS)
|
||||
{
|
||||
var t = new TestTemplate
|
||||
{
|
||||
Name = tsid.Name,
|
||||
Description = tsid.Description,
|
||||
SamplesPerSecondAggregate = tsid.SamplesPerSecond,
|
||||
PostTriggerSeconds = tsid.PosttriggerSeconds,
|
||||
PreTriggerSeconds = tsid.PretriggerSeconds,
|
||||
RecordingMode = tsid.RecordingMode,
|
||||
CalibrationBehavior = tsid.CalibrationBehavior
|
||||
};
|
||||
|
||||
AddHardwareToTestSetup(t, tsid, allDAS);
|
||||
|
||||
SetClockSyncs(t, tsid);
|
||||
if (RecordingModeExtensions.IsAStreamMode(tsid.RecordingMode))
|
||||
{
|
||||
t.DoStreaming = true;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
private static void SetClockSyncs(TestTemplate t, TestSetupImportData tsid)
|
||||
{
|
||||
if (tsid.ManageClocksOutsideOfDataPROMaster)
|
||||
{
|
||||
t.ClockSyncProfileMaster = ClockSyncProfile.Manual;
|
||||
}
|
||||
if (tsid.ManageClocksOutsideOfDataPROSlave)
|
||||
{
|
||||
t.ClockSyncProfileSlave = ClockSyncProfile.Manual;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void AddHardwareToTestSetup(TestTemplate t, TestSetupImportData tsid, DASHardware[] allDAS)
|
||||
{
|
||||
if (null != tsid.SampleRateForDAS && 0 != tsid.SampleRateForDAS.Count)
|
||||
{
|
||||
using (var e = tsid.SampleRateForDAS.GetEnumerator())
|
||||
{
|
||||
while (e.MoveNext())
|
||||
{
|
||||
var das = Array.Find(allDAS, d => d.SerialNumber.Equals(e.Current.Key));
|
||||
if (null == das) { continue; }
|
||||
t.AddHardware(das.DASId);
|
||||
if (tsid.IsClockMaster.ContainsKey(das.SerialNumber))
|
||||
{
|
||||
t.DASClockMasterList[das.SerialNumber] = tsid.IsClockMaster[das.SerialNumber];
|
||||
}
|
||||
if (tsid.DomainIdForDAS.ContainsKey(das.SerialNumber))
|
||||
{
|
||||
t.DASPTPDomainIDList[das.SerialNumber] = Convert.ToByte(t.DASPTPDomainIDList[das.SerialNumber]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void UpdateDASSampleRate(TestTemplate t, TestSetupImportData tsid, DASHardware[] allDAS)
|
||||
{
|
||||
if (null != tsid.SampleRateForDAS && 0 != tsid.SampleRateForDAS.Count)
|
||||
{
|
||||
using (var e = tsid.SampleRateForDAS.GetEnumerator())
|
||||
{
|
||||
while (e.MoveNext())
|
||||
{
|
||||
var das = Array.Find(allDAS, d => d.SerialNumber.Equals(e.Current.Key));
|
||||
if (null == das) { continue; }
|
||||
//why are there two places for this information?
|
||||
t.SetSampleRateForHardware(das, Convert.ToDouble(e.Current.Value));
|
||||
t.DASSampleRateList[das.SerialNumber] = Convert.ToDouble(e.Current.Value);
|
||||
}
|
||||
}
|
||||
if (tsid.SampleRateForDAS.Distinct().Count() > 1)
|
||||
{
|
||||
t.CommonStatusLine = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
if (string.IsNullOrEmpty(FileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (importObject == null)
|
||||
{
|
||||
throw new ArgumentNullException("importObject", "importObject can't be null or empty");
|
||||
}
|
||||
//FB 40598 Check if the file is supported for test setup import
|
||||
|
||||
if (!CSVFile.IsCSVFileForTestSetupImport(FileName, _csvImportOptions))
|
||||
{
|
||||
importObject.AddError(new ImportError { Message = StringResources.Import_CSVFileNotForTestSetup, ContinueImportOnError = false, Severity = ImportSeverityError.Critical });
|
||||
return;
|
||||
}
|
||||
|
||||
var tsid = ParseTestSetup(FileName);
|
||||
|
||||
if (tsid == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (importObject.TestSetups().Any(p => p.Name == tsid.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var allDAS = DataPROWin7.DataModel.Classes.Hardware.DASHardwareList.GetAllHardware();
|
||||
var t = CreateTestSetup(tsid, allDAS);
|
||||
//FB 36879 Add the hardware list for the test setup
|
||||
//FB 43815 if only the version is 6 which means we have hardware in the file otherwise it would nter a test setup with 0 hardware which would cause problems in
|
||||
//import summary and run test setup button in that wizard
|
||||
if (t != null && CSVFile.GetCsvVersion(FileName) >= 6)
|
||||
{
|
||||
importObject.AddHardwareList(t.GetHardware());
|
||||
}
|
||||
|
||||
if (tsid.Tags != null)
|
||||
{
|
||||
t?.SetTags(tsid.Tags.ToArray(), DbOperations.GetSQLCommand, DbOperations.TagsGet,
|
||||
DbOperations.TagsGetId, DbOperations.TagsInsert);
|
||||
}
|
||||
|
||||
//FB Assign the parse parameters
|
||||
_groupImport.ParseParameters = importObject.ParseParameters();
|
||||
|
||||
AssignCalibrations(ref importObject);
|
||||
|
||||
var res = AssignGroupsToTestSetup(t, importObject.SensorGroupNamesLookup(), null, importObject.StaticGroups().ToList(),
|
||||
importObject.Sensors().ToList(), _groupImport, _importNotification, tsid.Version);
|
||||
|
||||
var staticGroups = res?.Item2;
|
||||
var sensors = res?.Item3;
|
||||
var testSetup = res?.Item1;
|
||||
|
||||
if (staticGroups != null)
|
||||
{
|
||||
importObject.AddStaticGroups(staticGroups);
|
||||
}
|
||||
|
||||
var cleanedSensors = GroupHelper.CleanUneededSensorDataPlaceHolder(importObject.CalibrationsLookup(), sensors);
|
||||
if (cleanedSensors != null)
|
||||
{
|
||||
importObject.ClearSensors();
|
||||
|
||||
importObject.AddSensors(cleanedSensors);
|
||||
}
|
||||
|
||||
UpdateDASSampleRate(t, tsid, allDAS);
|
||||
|
||||
if (testSetup != null)
|
||||
{
|
||||
importObject.AddTestSetup(testSetup);
|
||||
//FB 38039, 40758 Identify type of import by number of test setups
|
||||
importObject.TestSetupImportFileFormat = importObject.GetImportFileFormat();
|
||||
}
|
||||
|
||||
importObject.SourceFormat = ImportFormats.DTS_CSV;
|
||||
}
|
||||
/// <summary>
|
||||
/// set the calibration for the sensor based on the most recent in the import
|
||||
/// this is necessary as it was coming in with the latest calibration from the database (which
|
||||
/// will be empty in a brand new import)
|
||||
/// http://manuscript.dts.local/f/cases/43722/When-Importing-Csv-test-setup-software-zero-method-in-test-setup-parameters-does-not-match-import
|
||||
/// </summary>
|
||||
private void AssignCalibrations(ref ImportObject importObject)
|
||||
{
|
||||
if (null == importObject) { return; }
|
||||
if (null == importObject.Sensors() || !importObject.Sensors().Any()) { return; }
|
||||
if (null == importObject.Calibrations() || !importObject.Calibrations().Any()) { return; }
|
||||
|
||||
foreach( var sensor in importObject.Sensors())
|
||||
{
|
||||
var cals = importObject.CalibrationLookup(sensor.SerialNumber);
|
||||
if (null == cals || 0 == cals.Count) { return; }
|
||||
cals.Sort();
|
||||
sensor.Calibration = cals[cals.Count - 1];
|
||||
}
|
||||
|
||||
}
|
||||
//FB 36879 Single Responsibility principle , moved the method to this class
|
||||
private Tuple<TestTemplate, List<IGroup>, List<SensorData>> AssignGroupsToTestSetup(TestTemplate testTemplate, Dictionary<string, string> sensorGroupNameLookup, Dictionary<string, List<string>> groupNameSensorListLookup,
|
||||
List<IGroup> existingStaticGroups, List<SensorData> sensors, IGroupImport groupImport, IImportNotification importNotification, int csvVersion)
|
||||
{
|
||||
try
|
||||
{
|
||||
_ = GroupHelper.ReverseChannelOrder(testTemplate, sensorGroupNameLookup, sensors);
|
||||
|
||||
var groupSensorLookup = groupImport.GetGroupSensorLookup(sensors, sensorGroupNameLookup, groupNameSensorListLookup);
|
||||
|
||||
sensors = GroupHelper.NormalizeSensorIds(sensors);
|
||||
//FB 36905
|
||||
var testAndGroups = groupImport.CreateGroups(sensors, groupSensorLookup, testTemplate, _createDynamicGroups, existingStaticGroups, importNotification.SetProgress);
|
||||
|
||||
if (testAndGroups == null)
|
||||
{
|
||||
TestTemplate noTestSetup = null;
|
||||
List<IGroup> noGroup = null;
|
||||
return Tuple.Create(noTestSetup, noGroup, sensors);
|
||||
}
|
||||
return Tuple.Create(testAndGroups.Item1, testAndGroups.Item2, sensors);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
importNotification.ReportErrors(new List<string> { ex.Message });
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private TestSetupImportData ParseTestSetup(string filename)
|
||||
{
|
||||
var tsid = new TestSetupImportData()
|
||||
{
|
||||
SamplesPerSecond = _defaultsTestSetupImportData.SamplesPerSecond,
|
||||
Tags = new List<string>(),
|
||||
Version = 0,
|
||||
RecordingMode = _defaultsTestSetupImportData.RecordingMode,
|
||||
PretriggerSeconds = _defaultsTestSetupImportData.PretriggerSeconds,
|
||||
PosttriggerSeconds = _defaultsTestSetupImportData.PosttriggerSeconds,
|
||||
CalibrationBehavior = _defaultsTestSetupImportData.CalibrationBehavior
|
||||
};
|
||||
|
||||
using (var parser = CsvUtil.CreateCsvReader(filename))
|
||||
{
|
||||
var parsers = CSVTestParserFactory.CreateCSVParsers();
|
||||
|
||||
parsers[0].ParseVersion(parser, tsid);
|
||||
|
||||
if (tsid.Version == 6)
|
||||
{
|
||||
for (var i = 1; i < parsers.Length; i++)
|
||||
{
|
||||
parsers[i].ParseVersion(parser, tsid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tsid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseSensors : XMLParseBase
|
||||
{
|
||||
public XMLParseSensors(XmlElement root, double importedVersion, Func<bool> isCancelled = null,bool skipNormalizing=false) : base(root, importedVersion, isCancelled, skipNormalizing) { }
|
||||
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingSensors });
|
||||
var sensors = ParseSensors(_root);
|
||||
if (!_skipNormalizing)
|
||||
{
|
||||
var newRoot = ConvertSensors(sensors);
|
||||
sensors = ParseSensors(newRoot);
|
||||
}
|
||||
importObject.AddSensors(sensors);
|
||||
}
|
||||
public XmlElement ConvertSensors(IEnumerable<SensorData> sensors)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.Sensors.ToString());
|
||||
//normalize to -2 ... -n (preserve -1 for invalid)
|
||||
var count = -2;
|
||||
foreach (var sd in sensors)
|
||||
{
|
||||
_sensorIdMapping[sd.DatabaseId] = count;
|
||||
sd.DatabaseId = count;
|
||||
count--;
|
||||
_writer.Flush();
|
||||
sd.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
|
||||
return GetXmlElement();
|
||||
}
|
||||
|
||||
public IEnumerable<SensorData> ParseSensors(XmlElement root)
|
||||
{
|
||||
List<SensorData> sensors = new List<SensorData>();
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled())
|
||||
{
|
||||
return sensors;
|
||||
}
|
||||
|
||||
if (!(node is XmlElement)) continue;
|
||||
var sd = new SensorData();
|
||||
sd.ReadXML(node as XmlElement);
|
||||
|
||||
sensors.Add(sd);
|
||||
}
|
||||
return sensors;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using DTS.Common.Classes.Locking;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.Common.Storage;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Slice.Users;
|
||||
|
||||
//FB 36740
|
||||
namespace DTS.Common.Import.DatabaseLocks
|
||||
{
|
||||
public class LockImportGroups : ILockImport
|
||||
{
|
||||
private readonly User _currentUser;
|
||||
private readonly double _strandedLockTimeoutMinutes;
|
||||
|
||||
/// <summary>
|
||||
/// this is a list of all groups locked by the user
|
||||
/// </summary>
|
||||
private readonly List<LockRecord> _lockedGroups = new List<LockRecord>();
|
||||
/// <summary>
|
||||
/// this is a list of all groups the user attempted to lock but another user has the lock
|
||||
/// </summary>
|
||||
private readonly List<LockRecord> _contendedGroups = new List<LockRecord>();
|
||||
public bool Contended { get => _contendedGroups.Any(); }
|
||||
|
||||
public LockImportGroups(User currentUser, double strandedLockTimeoutMinutes)
|
||||
{
|
||||
_currentUser = currentUser;
|
||||
_strandedLockTimeoutMinutes = strandedLockTimeoutMinutes;
|
||||
}
|
||||
|
||||
public void FreeLock(ref ImportObject importObject)
|
||||
{
|
||||
if (!_lockedGroups.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var record in _lockedGroups)
|
||||
{
|
||||
LockManager.FreeLock(record.ItemId, _currentUser.UserName, _currentUser.Id, out var lockError, record.ItemCategory);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetLock(ref ImportObject importObject, ref StringBuilder message)
|
||||
{
|
||||
_lockedGroups.Clear();
|
||||
_contendedGroups.Clear();
|
||||
foreach (var group in importObject.StaticGroups())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!LockManager.LockItem(group.Name, group.Id, LockManager.ItemCategories.Group, _currentUser.UserName,
|
||||
_currentUser.Id, out var existingLock, out var lockError))
|
||||
{
|
||||
if (lockError.ErrorCode == LockError.ITEM_NOT_FOUND)
|
||||
{
|
||||
continue; //lock not needed, doesn't exist in db
|
||||
}
|
||||
var lockOutOfDate = existingLock.LastUpdated.AddMinutes(_strandedLockTimeoutMinutes) < DateTime.Now;
|
||||
var IHaveTheLock = existingLock.LockingUserName == _currentUser.UserName && existingLock.LockingMachineName == Environment.MachineName;
|
||||
if (lockOutOfDate || IHaveTheLock)
|
||||
{
|
||||
//lock is expired (or already belongs to us), either way we can claim it
|
||||
LockManager.FreeLock(existingLock.ItemId, _currentUser.UserName, _currentUser.Id, out lockError, existingLock.ItemCategory);
|
||||
LockManager.LockItem(existingLock.ItemKey, existingLock.ItemId, LockManager.ItemCategories.Group, _currentUser.UserName,
|
||||
_currentUser.Id, out existingLock, out lockError);
|
||||
_lockedGroups.Add(existingLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
//could not lock, we need Admin + confirmation to lock
|
||||
_contendedGroups.Add(existingLock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//successfully locked
|
||||
_lockedGroups.Add(existingLock);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
}
|
||||
if (!_contendedGroups.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
message.AppendLine(StringResources.ImportTestSetup_GroupsLocked);
|
||||
foreach (var contended in _contendedGroups)
|
||||
{
|
||||
message.AppendLine($"{contended.ItemKey} by {contended.LockingUserName} on {contended.LockingMachineName}");
|
||||
}
|
||||
}
|
||||
|
||||
public bool StealLock(bool proceed)
|
||||
{
|
||||
if (!_contendedGroups.Any())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!_currentUser.IsAdmin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//steal locks if user oks it
|
||||
if (!proceed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var contendedGroup in _contendedGroups)
|
||||
{
|
||||
LockManager.FreeLock(contendedGroup.ItemId, _currentUser.UserName, _currentUser.Id, out var lockError, contendedGroup.ItemCategory);
|
||||
LockManager.LockItem(contendedGroup.ItemKey, contendedGroup.ItemId, LockManager.ItemCategories.Sensor, _currentUser.UserName, _currentUser.Id, out var newLockRecord, out lockError);
|
||||
_lockedGroups.Add(newLockRecord);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseMMECustomFineLoc1s : XMLParseBase
|
||||
{
|
||||
public XMLParseMMECustomFineLoc1s(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AddCustomFineLoc1s(ParseCustomFineLoc1s(_root));
|
||||
}
|
||||
|
||||
private IEnumerable<ISO.MMEFineLocations1> ParseCustomFineLoc1s(XmlElement root)
|
||||
{
|
||||
List<ISO.MMEFineLocations1> list = new List<ISO.MMEFineLocations1>();
|
||||
|
||||
foreach (var child in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return list; }
|
||||
if (child is XmlElement)
|
||||
{
|
||||
list.Add(ISO.MMEFineLocations1.ReadXML(child as XmlElement));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseGroups : XMLParseBase
|
||||
{
|
||||
|
||||
public XMLParseGroups(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_groupIdMapping.Clear();
|
||||
}
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingGroups });
|
||||
var staticGroups = ParseGroups(_root, ref importObject);
|
||||
if (!staticGroups.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var newRoot = ConvertGroups(staticGroups);
|
||||
if (newRoot == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
staticGroups = ParseGroups(newRoot, ref importObject);
|
||||
importObject.AddStaticGroups(staticGroups);
|
||||
|
||||
}
|
||||
private XmlElement ConvertGroups(List<IGroup> staticGroups)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.Groups.ToString());
|
||||
var count = -2; //Start the normalization at -2, to be consistent with channel mapping(?)
|
||||
foreach (var g in staticGroups)
|
||||
{
|
||||
if (_importedVersion >= FileUtils.DataPRO21XmlVersion)
|
||||
{
|
||||
_groupIdMapping[g.Id.ToString()] = count;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Must be an export from 2.0 or earlier
|
||||
_groupIdMapping[g.Name] = count;
|
||||
}
|
||||
g.Id = count;
|
||||
count--;
|
||||
foreach (var channel in g.GroupChannelList)
|
||||
{
|
||||
if (_dasIdMapping.ContainsKey(channel.DASId))
|
||||
{
|
||||
channel.DASId = _dasIdMapping[channel.DASId];
|
||||
}
|
||||
if (_sensorIdMapping.ContainsKey(channel.SensorId))
|
||||
{
|
||||
channel.SensorId = _sensorIdMapping[channel.SensorId];
|
||||
}
|
||||
else
|
||||
{
|
||||
//FB 14308 - Don't fail Group import if it was
|
||||
//exported with a deleted sensor.
|
||||
channel.SensorId = 0;
|
||||
}
|
||||
}
|
||||
_writer.Flush();
|
||||
g.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
|
||||
}
|
||||
|
||||
public List<IGroup> ParseGroups(XmlElement root, ref ImportObject importObject)
|
||||
{
|
||||
List<IGroup> staticGroups = new List<IGroup>();
|
||||
var importedHardware = new Dictionary<string, DataPROWin7.DataModel.DASHardware>();
|
||||
foreach (var h in importObject.Hardware())
|
||||
{
|
||||
importedHardware[h.GetHardware().GetId()] = h;
|
||||
}
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return staticGroups; }
|
||||
if (!(node is XmlElement)) continue;
|
||||
|
||||
IGroup groupInstance = GroupHelper.CreateEmptyGroup();
|
||||
if (groupInstance != null)
|
||||
{
|
||||
var channelLookup = new Dictionary<long, Interface.Channels.IGroupChannel>();
|
||||
var iSensors = new List<Interface.Sensors.ISensorData>();
|
||||
foreach (var sensor in importObject.Sensors())
|
||||
{
|
||||
iSensors.Add(sensor);
|
||||
}
|
||||
var g = groupInstance.ReadXML(node as XmlElement, channelLookup, iSensors);
|
||||
if (!string.IsNullOrWhiteSpace(g.Name))
|
||||
{
|
||||
var groupCopy = GroupHelper.CreateEmptyGroup();
|
||||
groupCopy.Name = g.Name;
|
||||
//FB 44143 assign description
|
||||
groupCopy.Description = g.Description;
|
||||
groupCopy.DisplayName = g.Name;
|
||||
groupCopy.LastModified = g.LastModified;
|
||||
groupCopy.Embedded = g.Embedded;
|
||||
groupCopy.IncludedHardwareStringList = g.IncludedHardwareStringList;
|
||||
groupCopy.Id = g.Id;
|
||||
groupCopy.Tags = g.Tags;
|
||||
staticGroups.Add(groupCopy);
|
||||
|
||||
foreach (var channel in channelLookup.Select(p => p.Value))
|
||||
{
|
||||
channel.Group = groupCopy;
|
||||
groupCopy.GroupChannelList.Add(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return staticGroups;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using DTS.Common.Classes;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using Microsoft.VisualBasic.FileIO;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Import.Parsers.CSV
|
||||
{
|
||||
public class Version0CSVTestParser : IParseCSVTest
|
||||
{
|
||||
public int Version => 0;
|
||||
public void ParseVersion(TextFieldParser parser, TestSetupImportData tsid)
|
||||
{
|
||||
var tokens = parser.ReadFields();
|
||||
|
||||
if (null != tokens && tokens[0] == "Version")
|
||||
{
|
||||
var tokens2 = parser.ReadFields();
|
||||
|
||||
for (var i = 0; null != tokens2 && i < tokens.Length && i < tokens2.Length; i++)
|
||||
{
|
||||
var field = CSVImportTags.GetTagForString(tokens[i]);
|
||||
var val = tokens2[i];
|
||||
switch (field)
|
||||
{
|
||||
case CSVImportTags.Tags.PostTriggerSec:
|
||||
{
|
||||
if (double.TryParse(val, out var dTemp))
|
||||
{
|
||||
tsid.PosttriggerSeconds = dTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.PreTriggerSec:
|
||||
{
|
||||
if (double.TryParse(val, out var dTemp))
|
||||
{
|
||||
tsid.PretriggerSeconds = dTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.RecordingMode:
|
||||
{
|
||||
if (Enum.TryParse(val, out RecordingModes mode))
|
||||
{
|
||||
tsid.RecordingMode = mode;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.SampleRate:
|
||||
{
|
||||
if (double.TryParse(val, out var dTemp))
|
||||
{
|
||||
tsid.SamplesPerSecond = dTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.TestSetupDescription:
|
||||
tsid.Description = val;
|
||||
break;
|
||||
case CSVImportTags.Tags.TestSetupName:
|
||||
tsid.Name = val;
|
||||
break;
|
||||
case CSVImportTags.Tags.Version:
|
||||
{
|
||||
if (int.TryParse(val, out var iTemp))
|
||||
{
|
||||
tsid.Version = iTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.Tags:
|
||||
tsid.Tags = val.Split(';').ToList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class PersistCalculator : IPersistCalculator
|
||||
{
|
||||
|
||||
private double _done;
|
||||
private double _total;
|
||||
|
||||
public double ProgressValue { get => _done / _total; }
|
||||
|
||||
public void AddDone(double value)
|
||||
{
|
||||
_done += value;
|
||||
}
|
||||
|
||||
public void AddDone()
|
||||
{
|
||||
_done++;
|
||||
}
|
||||
|
||||
public void AddToTotal(double value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("value", "value should not be less or equal to zero.");
|
||||
}
|
||||
_total += value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface IPersistCalculator
|
||||
{
|
||||
void AddDone();
|
||||
void AddDone(double value);
|
||||
double ProgressValue { get; }
|
||||
void AddToTotal(double value);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using DTS.Common.Settings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveGlobalSettings : SaveVariantBase
|
||||
{
|
||||
public SaveGlobalSettings(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
foreach (var g in _importObject.GlobalSettings())
|
||||
{
|
||||
if (IsCancelled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SettingsDB.SetGlobalValue(g.Key, g.Value);
|
||||
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Utils;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class XMLParseProcessor
|
||||
{
|
||||
private readonly IEnumerable<string> _fileNames;
|
||||
private ImportObject _importObject;
|
||||
private readonly IImportNotification _importNotification;
|
||||
private readonly Func<bool> _isCancelled;
|
||||
private readonly bool _skipNormalizing;
|
||||
public List<IUIItems> UIItems { get; set; }
|
||||
|
||||
public XMLParseProcessor(ImportObject importObject, IImportNotification importNotification, IEnumerable<string> fileNames, Func<bool> isCancelled, bool skipNormalizing)
|
||||
{
|
||||
_fileNames = fileNames;
|
||||
_importObject = importObject;
|
||||
_importNotification = importNotification;
|
||||
_isCancelled = isCancelled;
|
||||
_skipNormalizing = skipNormalizing;
|
||||
}
|
||||
public ImportObject Process()
|
||||
{
|
||||
foreach (var fileName in _fileNames)
|
||||
{
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingXML, PossibleStatus = PossibleStatus.Working });
|
||||
XmlParserFactory.UIItems = UIItems;
|
||||
var parseVariants = XmlParserFactory.CreateXMLParsers(fileName, _importNotification, _isCancelled, _skipNormalizing);
|
||||
//FB 36879 Prevent exception if there is no variants to parse
|
||||
double itemsToComplete = 0;
|
||||
if (parseVariants.Any())
|
||||
{
|
||||
itemsToComplete = XMLUtils.DTSXMLFile.GetItemsToCompleteCount(fileName);
|
||||
}
|
||||
|
||||
foreach (var variant in parseVariants)
|
||||
{
|
||||
variant.Parse(ref _importObject);
|
||||
NotifyProgress(itemsToComplete);
|
||||
|
||||
}
|
||||
}
|
||||
return _importObject;
|
||||
}
|
||||
|
||||
private void NotifyProgress(double itemsToComplete)
|
||||
{
|
||||
if (itemsToComplete <= 0) { return; }
|
||||
|
||||
var completed = _importObject.Calibrations().Count() + _importObject.Sensors().Count() + _importObject.CustomChannels().Count()
|
||||
+ _importObject.Groups().Count() + _importObject.GroupTemplates().Count() +
|
||||
_importObject.TestSetups().Count() + _importObject.Hardware().Count()
|
||||
+ _importObject.CustomerDetails().Count() + _importObject.TestEngineerDetails().Count() + _importObject.LabDetails().Count();
|
||||
|
||||
double progress = completed / itemsToComplete;
|
||||
if (progress >= 1)
|
||||
{
|
||||
progress = 1;
|
||||
}
|
||||
_importNotification.SetProgress(progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using DTS.Common.Classes.Locking;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.Common.Storage;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Slice.Users;
|
||||
|
||||
namespace DTS.Common.Import.DatabaseLocks
|
||||
{
|
||||
//FB 36740
|
||||
public class LockImportTestSetups : ILockImport
|
||||
{
|
||||
private readonly User _currentUser;
|
||||
private readonly double _strandedLockTimeoutMinutes;
|
||||
|
||||
/// <summary>
|
||||
/// this is a list of all tests locked by user
|
||||
/// </summary>
|
||||
private readonly List<LockRecord> _lockedTests = new List<LockRecord>();
|
||||
/// <summary>
|
||||
/// this is a list of tests locking was attempted but another user has the lock
|
||||
/// </summary>
|
||||
private readonly List<LockRecord> _contendedTests = new List<LockRecord>();
|
||||
public LockImportTestSetups(User currentUser, double strandedLockTimeoutMinutes)
|
||||
{
|
||||
_currentUser = currentUser;
|
||||
_strandedLockTimeoutMinutes = strandedLockTimeoutMinutes;
|
||||
}
|
||||
|
||||
public bool Contended { get => _contendedTests.Any(); }
|
||||
|
||||
public void FreeLock(ref ImportObject importObject)
|
||||
{
|
||||
if (!_lockedTests.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var record in _lockedTests)
|
||||
{
|
||||
LockManager.FreeLock(record.ItemId, _currentUser.UserName, _currentUser.Id, out var lockError, record.ItemCategory);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetLock(ref ImportObject importObject, ref StringBuilder message)
|
||||
{
|
||||
_lockedTests.Clear();
|
||||
_contendedTests.Clear();
|
||||
foreach (var test in importObject.TestSetups())
|
||||
{
|
||||
try
|
||||
{
|
||||
var gotLock = LockManager.LockItem(test.Name, test.Id, LockManager.ItemCategories.TestSetup, _currentUser.UserName,
|
||||
_currentUser.Id, out var existingLock, out var lockError);
|
||||
if (!gotLock)
|
||||
{
|
||||
if (lockError.ErrorCode == LockError.ITEM_NOT_FOUND)
|
||||
{
|
||||
continue; //lock not needed, doesn't exist in db
|
||||
}
|
||||
var lockOutOfDate = existingLock.LastUpdated.AddMinutes(_strandedLockTimeoutMinutes) < DateTime.Now;
|
||||
var IHaveTheLock = existingLock.LockingUserName == _currentUser.UserName && existingLock.LockingMachineName == Environment.MachineName;
|
||||
if (lockOutOfDate || IHaveTheLock)
|
||||
{
|
||||
//lock is expired (or already belongs to us), either way we can claim it
|
||||
_ = LockManager.FreeLock(existingLock.ItemId, _currentUser.UserName, _currentUser.Id, out lockError, existingLock.ItemCategory);
|
||||
_ = LockManager.LockItem(existingLock.ItemKey, existingLock.ItemId, LockManager.ItemCategories.TestSetup, _currentUser.UserName,
|
||||
_currentUser.Id, out existingLock, out lockError);
|
||||
_lockedTests.Add(existingLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
//couldn't be locked, we need Admin + confirmation to steal lock
|
||||
_contendedTests.Add(existingLock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//successfully locked
|
||||
_lockedTests.Add(existingLock);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { APILogger.Log(ex); }
|
||||
}
|
||||
|
||||
if (!_contendedTests.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
message.AppendLine(StringResources.ImportTestSetup_TestsLocked);
|
||||
foreach (var contended in _contendedTests)
|
||||
{
|
||||
message.AppendLine($"{contended.ItemKey} by {contended.LockingUserName} on {contended.LockingMachineName}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool StealLock(bool proceed)
|
||||
{
|
||||
|
||||
if (!_contendedTests.Any())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!_currentUser.IsAdmin)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//steal locks if user oks it
|
||||
|
||||
if (!proceed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var contendedTest in _contendedTests)
|
||||
{
|
||||
LockManager.FreeLock(contendedTest.ItemId, _currentUser.UserName, _currentUser.Id, out var lockError, contendedTest.ItemCategory);
|
||||
LockManager.LockItem(contendedTest.ItemKey, contendedTest.ItemId, LockManager.ItemCategories.Sensor, _currentUser.UserName, _currentUser.Id, out var newLockRecord, out lockError);
|
||||
_lockedTests.Add(newLockRecord);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseUsers : XMLParseBase
|
||||
{
|
||||
private readonly IEnumerable<IUIItems> _uiItems;
|
||||
public XMLParseUsers(XmlElement root, double importedVersion, IEnumerable<IUIItems> uiItems, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_uiItems = uiItems;
|
||||
}
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingUsers });
|
||||
importObject.AddUsers(ParseUsers(_root, _uiItems));
|
||||
}
|
||||
|
||||
private IEnumerable<User> ParseUsers(XmlElement root, IEnumerable<IUIItems> iUItems)
|
||||
{
|
||||
List<User> users = new List<User>();
|
||||
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return users; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
users.Add(User.ReadXML(node as XmlElement, iUItems?.ToArray()));
|
||||
}
|
||||
}
|
||||
return users;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.Common.ISO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveCustomChannels : SaveVariantBase
|
||||
{
|
||||
|
||||
public ISO13499FileDb IsoDb { get; set; }
|
||||
public Dictionary<string, string> CustomChannelTextIdToOldChannelId { get; set; } = new Dictionary<string, string>();
|
||||
public Dictionary<string, TestObjectChannel> CustomChannelOldChannelIdToChannel { get; set; } = new Dictionary<string, TestObjectChannel>();
|
||||
|
||||
public SaveCustomChannels(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
//there's a bit of a dance here
|
||||
//when we commit embedded non iso groups for a non iso test setup for instance, the custom channels for that test setup are destroyed and
|
||||
//recreated new, and as they were before they shall be again, but we'd like to link our level triggers we are importing that have the old ids
|
||||
//to the new ids that will exist
|
||||
//since we will go through all the custom channels in the code below, it's a good point to make a note of what once was
|
||||
//then later on after we commit the groups in question, we'll make a note of what now is, and then correct it in all test setups.
|
||||
|
||||
|
||||
|
||||
//custom channels have an autoincrement id, because of this we have to do a two step dance with them
|
||||
//#1, look for existing custom channel if possible and just use it's id
|
||||
//#2, or insert a new custom channel, get it's id, then update all templates and channels with that custom channel
|
||||
// with th enew id
|
||||
|
||||
var customChannels = _importObject.CustomChannels().ToList();
|
||||
if (customChannels == null || !customChannels.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int currentCCIdx = customChannels.Count - 1; currentCCIdx >= 0; currentCCIdx--)
|
||||
{
|
||||
var cc = customChannels[currentCCIdx];
|
||||
customChannels.RemoveAt(currentCCIdx);
|
||||
if (IsCancelled()) { return; }
|
||||
var oldid = cc.Id; //this is the id from the import file
|
||||
long newid;
|
||||
|
||||
var existing = CustomChannelList.List.GetChannelByISOCode(IsoCodeStatics.GetString(cc, false), false);
|
||||
if (null != existing)
|
||||
{
|
||||
//custom channel already exists, just use it's id
|
||||
newid = existing.Channel.Id;
|
||||
cc.SetId(newid);
|
||||
}
|
||||
else
|
||||
{
|
||||
//custom channel doesn't exist, we need to insert it, but we have to clear the id first so we can insert it
|
||||
//we've already held onto the old id, so we're good.
|
||||
cc.ClearId();
|
||||
}
|
||||
//update or insert the custom channel
|
||||
var customchannel = new CustomChannel(cc);
|
||||
|
||||
CustomChannelList.List.Commit(customchannel, true, false);
|
||||
|
||||
newid = customchannel.Channel.Id; //this is now the official id of the custom channel,
|
||||
//go through all the channels, updating the ids if needed
|
||||
|
||||
var groupTemplates = _importObject.GroupTemplates().ToList();
|
||||
for (var i = groupTemplates.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var gt = groupTemplates[i];
|
||||
var isoGT = gt.ToISOTestObjectTemplate();
|
||||
var bUpdated = false;
|
||||
foreach (var ch in isoGT.Channels)
|
||||
{
|
||||
if (ch.Channel.Text_L1 != cc.Text_L1 ||
|
||||
ch.Channel.MMEChannelType != (int)MMEPossibleChannels.MMEChannelTypes.SQL)
|
||||
continue;
|
||||
ch.SetID(newid);
|
||||
bUpdated = true;
|
||||
}
|
||||
//if the group template wasn't updated, then we are done with that group template, if however it was updated
|
||||
//we then have to go through all groups and update the sensor assignments
|
||||
if (!bUpdated) continue;
|
||||
var db = IsoDb;
|
||||
groupTemplates[i] = new DataPROWin7.DataModel.TestObjectTemplate(isoGT, ref db);
|
||||
|
||||
var templateName = isoGT.TemplateName;
|
||||
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingGroups, PossibleStatus = PossibleStatus.Importing });
|
||||
var groups = new List<DataPROWin7.DataModel.TestObject>(_importObject.Groups());
|
||||
foreach (var t in _importObject.TestSetups().Where(t => t.AddedGroups.Any()))
|
||||
{
|
||||
groups.AddRange(t.AddedGroups.ToArray());
|
||||
}
|
||||
|
||||
foreach (var g in groups)
|
||||
{
|
||||
if (g.Template.TemplateName != templateName) continue;
|
||||
var oldISOTO = g.GetISOTestObject();
|
||||
//because of the changing custom channel ids, we have to hold onto some of the properties
|
||||
//of the import group before we repopulate it with the new template
|
||||
var isoCodeToSensorSerialNumberLookup = new Dictionary<string, string>();
|
||||
var isoCodeToHardwareChannelIdLookup = new Dictionary<string, string>();
|
||||
|
||||
foreach (var ch in oldISOTO.AllChannels)
|
||||
{
|
||||
if (ch.Channel.Text_L1 != cc.Text_L1) continue;
|
||||
if (string.IsNullOrWhiteSpace(ch.SensorSerialNumber)) continue;
|
||||
isoCodeToSensorSerialNumberLookup[IsoCodeStatics.GetString(ch.Channel, false)] = ch.SensorSerialNumber;
|
||||
isoCodeToHardwareChannelIdLookup[IsoCodeStatics.GetString(ch.Channel, false)] = ch.HardwareId;
|
||||
}
|
||||
//assign the new template, and then update the channels in the template with a sensor/hardware id if necessary
|
||||
g.SetTemplateDontResetISOObject(groupTemplates[i]);
|
||||
var newISOTO = g.GetISOTestObject();
|
||||
foreach (var ch in newISOTO.AllChannels)
|
||||
{
|
||||
if (ch.Channel.MMEChannelType == (int)MMEPossibleChannels.MMEChannelTypes.ISO13499_106) { continue; }
|
||||
var ccIso = IsoCodeStatics.GetString(cc, false);
|
||||
if (ch.Channel.Text_L1 != cc.Text_L1 || !isoCodeToSensorSerialNumberLookup.ContainsKey(ccIso))
|
||||
continue;
|
||||
//keep a track of what once was
|
||||
var oldChannelId = ch.GetIdWithSpecificChannelId(oldid);
|
||||
CustomChannelTextIdToOldChannelId[ccIso] = oldChannelId;
|
||||
CustomChannelOldChannelIdToChannel[oldChannelId] = ch;
|
||||
ch.Channel.SetId(customchannel.Channel.Id);
|
||||
ch.SensorSerialNumber = isoCodeToSensorSerialNumberLookup[ccIso];
|
||||
ch.HardwareId = isoCodeToHardwareChannelIdLookup[ccIso];
|
||||
}
|
||||
}
|
||||
}
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
//speed up memory collection by forcing GC
|
||||
//11287 Out of memory exception when importing large CSV Test Setup files
|
||||
//This is a critical code smell- moved from existing code base find a better way to handle this in future
|
||||
//https://rules.sonarsource.com/csharp/RSPEC-1215/
|
||||
// GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
|
||||
}
|
||||
|
||||
CustomChannelList.List.UpdateAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
using DTS.Common.Import.Parsers;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.Common.Storage;
|
||||
using DTS.SensorDB;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using static DTS.Common.Enums.Sensors.SensorConstants;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class EQXSensorsParser : ParseVariantBase
|
||||
{
|
||||
private readonly User _currentUser;
|
||||
private readonly IImportNotification _importNotification;
|
||||
private readonly EquipmentExchange.EQXSensorDatabase _eqxSensorDatabase;
|
||||
private readonly EqxImportOptions _eqxImportOptions;
|
||||
public EQXSensorsParser(IImportNotification importNotification, User user, EqxImportOptions eqxImportOptions,
|
||||
EquipmentExchange.EQXSensorDatabase eqxSensorDatabase)
|
||||
{
|
||||
_currentUser = user;
|
||||
_importNotification = importNotification;
|
||||
_eqxSensorDatabase = eqxSensorDatabase;
|
||||
_eqxImportOptions = eqxImportOptions;
|
||||
}
|
||||
|
||||
const float MAX_EQX_VERSION_SUPPORT = 1.5F;
|
||||
public bool ImportCreateDynamicGroups { get; set; }
|
||||
public bool EQXUseSerialNumberFieldForSN { get; set; }
|
||||
public bool UseZeroForUnfiltered { get; set; }
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
if (string.IsNullOrEmpty(FileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (importObject == null)
|
||||
{
|
||||
throw new ArgumentNullException("importObject", "importObject can't be null or empty");
|
||||
}
|
||||
importObject = ParseSensor(importObject, FileName);
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Adjusts squibs measurement type if appropriate
|
||||
/// http://manuscript.dts.local/f/cases/44393/GM-SQUIB-imports-require-initiator-signal-not-voltage
|
||||
/// </summary>
|
||||
private static void SetSquibMeasurementType(ISensorData sd)
|
||||
{
|
||||
if (sd.IsSquib() && UseInitSignalTOM)
|
||||
{
|
||||
sd.SquibMeasurementType = SquibMeasurementType.INIT_SIGNAL;
|
||||
}
|
||||
}
|
||||
//FB 44299
|
||||
private static void SetSensorTypeInSensorDataTags(SensorData sensorData, string tag)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tag)) { return; }
|
||||
|
||||
var allTags = new List<string>();
|
||||
//FB copied the code from DataPRO sensor, I am not sure why it created a copy of SensorData
|
||||
var sensorDataCopy = new SensorData(sensorData);
|
||||
var currentTags = sensorDataCopy.GetTagsArray(DbOperations.TagsGet);
|
||||
if (currentTags != null && currentTags.Any())
|
||||
{
|
||||
allTags.AddRange(currentTags);
|
||||
}
|
||||
|
||||
if (!allTags.Contains(tag))
|
||||
{
|
||||
allTags.Add(tag);
|
||||
}
|
||||
// Set the tags
|
||||
sensorData.SetTags(allTags.ToArray(), DbOperations.GetSQLCommand, DbOperations.TagsGet, DbOperations.TagsGetId, DbOperations.TagsInsert);
|
||||
}
|
||||
private ImportObject ParseSensor(ImportObject importObject, string filename)
|
||||
{
|
||||
|
||||
int currentDone = 0;
|
||||
var lines = File.ReadAllLines(filename);
|
||||
|
||||
int totalCount = lines.Count();
|
||||
XDocument xDoc = null;
|
||||
try
|
||||
{
|
||||
xDoc = XDocument.Load(filename);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_importNotification.ReportErrors(new List<string>(new[] { StringResources.ImportSensorsPreviewControl_EQXFileXMLError, ex.Message }));
|
||||
|
||||
return importObject;
|
||||
}
|
||||
|
||||
float eQXEdition = MAX_EQX_VERSION_SUPPORT;
|
||||
var fileInfo = xDoc.Elements("Sensors").Select(x => x.Elements("FileInfo")).FirstOrDefault();
|
||||
if (fileInfo.Any())
|
||||
{
|
||||
var eQXEditionString = fileInfo.Select(x => x.Attribute("DataFormatEdition").Value).FirstOrDefault();
|
||||
|
||||
try
|
||||
{
|
||||
eQXEdition = Convert.ToSingle(eQXEditionString, CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_importNotification.ReportErrors(new List<string>(new[] { StringResources.ImportSensorsPreviewControl_EQXVersionReadError }));
|
||||
return importObject;
|
||||
}
|
||||
}
|
||||
if (eQXEdition > MAX_EQX_VERSION_SUPPORT)
|
||||
{
|
||||
_importNotification.ReportErrors(new List<string>(new[] { string.Format(StringResources.ImportSensorsPreviewControl_EQXVersionError, eQXEdition, MAX_EQX_VERSION_SUPPORT) }));
|
||||
return importObject;
|
||||
}
|
||||
|
||||
_eqxSensorDatabase.Read(filename, (List<string> readErrors) => { _importNotification.ReportErrors(readErrors); }, EQXUseSerialNumberFieldForSN, UseZeroForUnfiltered, ImportCreateDynamicGroups);
|
||||
|
||||
var sensors = _eqxSensorDatabase.GetSensors();
|
||||
var lookup = new Dictionary<string, bool>();
|
||||
var increment = Convert.ToInt32(lines.Length / (double)sensors.Length);
|
||||
foreach (var sd in sensors)
|
||||
{
|
||||
var sc = _eqxSensorDatabase.GetCalibrations(sd.UUID);
|
||||
if (0 == currentDone % 10)
|
||||
{
|
||||
_importNotification.SetProgress(100D * currentDone / totalCount);
|
||||
}
|
||||
//check to see if the sensor had a NULL IDModuleString, if so
|
||||
//check for an existing EID and use that rather than wiping out the EID
|
||||
//18467 Missing IDModuleString in e2x file import is clearing the EID on sensor import
|
||||
if (_eqxSensorDatabase.SensorHasNullIDModule(sd.UUID) && _eqxSensorDatabase.GetSensorNullIdModuleValue(sd.UUID))
|
||||
{
|
||||
var existing = SensorsCollection.SensorsList.GetSensorBySerialNumber(sd.SerialNumber);
|
||||
if (null != existing)
|
||||
{
|
||||
sd.EID = existing.EID;
|
||||
}
|
||||
}
|
||||
var sensorType = ChannelTypeUtility.ParseSensorKnownChannelType(sd.SerialNumber);
|
||||
SetSensorTypeInSensorDataTags(sd, sensorType);
|
||||
SetSquibMeasurementType(sd);
|
||||
currentDone += increment;
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(sd.SerialNumber))
|
||||
{
|
||||
importObject.AddSensorLookup(sd.SerialNumber, sd);
|
||||
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(sd.SerialNumber))
|
||||
{
|
||||
importObject.AddCalibrationLookup(sd.SerialNumber, sc);
|
||||
}
|
||||
|
||||
|
||||
// this is for compatability for import test setups
|
||||
if (importObject.Sensors().FirstOrDefault(s => s.SerialNumber == sd.SerialNumber) == null)
|
||||
{
|
||||
importObject.AddSensor(sd);
|
||||
}
|
||||
importObject.AddSensorChannelCodeLookup(sd.SettingName, sd.SerialNumber);
|
||||
// this is for compatability for import test setups
|
||||
importObject.AddCalibrations(sc);
|
||||
|
||||
var key = $"{sd.Manufacturer}_{sd.Model}";
|
||||
sc.Sort();
|
||||
|
||||
if (!lookup.ContainsKey(key) && sc.Any())
|
||||
{
|
||||
var model = FactorySensorModel.CreateModelFromSensor(sd, sc[0], _currentUser);
|
||||
importObject.AddSensorModelLookup(key, model);
|
||||
lookup[key] = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//15609 Sensors not usable after EQX import
|
||||
//warn on invalid excitation problems
|
||||
var errors = GetExcitationErrors();
|
||||
|
||||
//TODO Report the errors
|
||||
|
||||
return importObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns a list of any excitation errors for sensors in the import file
|
||||
/// created for EQX processing
|
||||
/// 15609 Sensors not usable after EQX import
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private List<string> GetExcitationErrors()
|
||||
{
|
||||
if (null == _eqxSensorDatabase) { return new List<string>(); }
|
||||
var errors = new List<string>();
|
||||
var sensors = _eqxSensorDatabase.GetSensors();
|
||||
foreach (var sd in sensors)
|
||||
{
|
||||
switch (sd.Bridge)
|
||||
{
|
||||
case BridgeType.DigitalInput:
|
||||
case BridgeType.SQUIB:
|
||||
case BridgeType.TOMDigital:
|
||||
continue;
|
||||
}
|
||||
|
||||
var hasValidCal = false;
|
||||
if (_eqxSensorDatabase.ContainsCalibration(sd.UUID))
|
||||
{
|
||||
var cals = _eqxSensorDatabase.GetCalibrations(sd.UUID);
|
||||
foreach (var cal in cals)
|
||||
{
|
||||
if (!cal.IsProportional)
|
||||
{
|
||||
hasValidCal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sd.SupportedExcitation.Contains(cal.Records.Records.First().Excitation))
|
||||
{
|
||||
hasValidCal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var error = string.Format(
|
||||
StringResources.Error_SensorNoCalibrationExcitationNotSupported,
|
||||
sd.ToDisplayString(), cal.Records.Records.First().Excitation.ToString());
|
||||
if (!errors.Contains(error)) { errors.Add(error); }
|
||||
}
|
||||
|
||||
switch (cal.Records.Records.First().Excitation)
|
||||
{
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Undefined:
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt2_5:
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt3:
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt1:
|
||||
{
|
||||
var error = string.Format(StringResources.Error_SensorCalibrationNotSupported,
|
||||
sd.ToDisplayString(), cal.Records.Records.First().Excitation.ToString());
|
||||
if (errors.Contains(error)) { errors.Add(error); }
|
||||
}
|
||||
break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt2:
|
||||
break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt5:
|
||||
break;
|
||||
case ExcitationVoltageOptions.ExcitationVoltageOption.Volt10:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasValidCal)
|
||||
{
|
||||
var error = string.Format(StringResources.Error_SensorCalibrationNone, sd.ToDisplayString());
|
||||
if (!errors.Contains(error))
|
||||
{
|
||||
errors.Add(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseGroupTemplates : XMLParseBase
|
||||
{
|
||||
private ISO.ISO13499FileDb _iSO13499FileDb;
|
||||
public XMLParseGroupTemplates(XmlElement root, double importedVersion, ISO.ISO13499FileDb iSO13499FileDb,
|
||||
Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_iSO13499FileDb = iSO13499FileDb;
|
||||
}
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
var groupTemplates = ParseGroupTemplates(ref importObject, _root);
|
||||
importObject.AddGroupTemplates(groupTemplates);
|
||||
}
|
||||
public IEnumerable<DataPROWin7.DataModel.TestObjectTemplate> ParseGroupTemplates(ref ImportObject importObject, XmlElement root)
|
||||
{
|
||||
List<DataPROWin7.DataModel.TestObjectTemplate> groupTemplates = new List<DataPROWin7.DataModel.TestObjectTemplate>();
|
||||
|
||||
var importChannels = new Dictionary<long, ISO.MMEPossibleChannels>();
|
||||
foreach (var channel in importObject.CustomChannels())
|
||||
{
|
||||
if (IsCancelled())
|
||||
{
|
||||
return groupTemplates;
|
||||
}
|
||||
importChannels[channel.Id] = channel;
|
||||
}
|
||||
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled())
|
||||
{
|
||||
return groupTemplates;
|
||||
}
|
||||
if (!(node is XmlElement)) continue;
|
||||
var template = DataPROWin7.DataModel.TestObjectTemplate.ReadXML(node as XmlElement, importChannels);
|
||||
template.Embedded = template.SysBuilt || template.Embedded; // If this is an old Dynamic Group or a new Added Group, by definition it's embedded.
|
||||
if (template.SysBuilt)
|
||||
{
|
||||
template.OriginalTemplateName = template.TemplateName;
|
||||
}
|
||||
groupTemplates.Add(new DataPROWin7.DataModel.TestObjectTemplate(template, ref _iSO13499FileDb, importObject.TestObjects()?.ToList()));
|
||||
if (null == groupTemplates.Last().TestObject)
|
||||
{
|
||||
//FB8790 - TestSetup with a custom ISO testobject that is not available in the export file has an ambiguous error message.
|
||||
throw new NotSupportedException(string.Format(StringResources.ImportTestSetup_ISOTestObjectNotFoundInImportFile, template.TemplateNameOrOriginalTemplateName, template.TestObject));
|
||||
}
|
||||
}
|
||||
return groupTemplates;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Classes;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public static class GroupHelper
|
||||
{
|
||||
//FB 36879 Single responsibility principle , moved group realted utility methods to this class
|
||||
public static IGroup CreateEmptyGroup()
|
||||
{
|
||||
return new GroupList.Model.Group(true);
|
||||
}
|
||||
|
||||
public static void GetTestSensorParameters(out string isoCode, out string isoChannelName, out string userCode, out string userChannelName,
|
||||
ParseParameters pp, SensorData sd, out string dasSerialNumber, out int dasChannelIdx)
|
||||
{
|
||||
isoCode = sd.ISOCode;
|
||||
if (pp.SensorISOCode.ContainsKey(sd.SerialNumber)) { isoCode = pp.SensorISOCode[sd.SerialNumber]; }
|
||||
|
||||
isoChannelName = sd.ISOChannelName;
|
||||
if (pp.SensorISOChannelName.ContainsKey(sd.SerialNumber)) { isoChannelName = pp.SensorISOChannelName[sd.SerialNumber]; }
|
||||
|
||||
userCode = sd.UserCode;
|
||||
if (pp.SensorUserCode.ContainsKey(sd.SerialNumber)) { userCode = pp.SensorUserCode[sd.SerialNumber]; }
|
||||
|
||||
userChannelName = sd.UserChannelName;
|
||||
if (pp.SensorUserChannelName.ContainsKey(sd.SerialNumber)) { userChannelName = pp.SensorUserChannelName[sd.SerialNumber]; }
|
||||
|
||||
dasSerialNumber = string.Empty;
|
||||
if (pp.SensorDASSerialNumber.ContainsKey(sd.SerialNumber)) { dasSerialNumber = pp.SensorDASSerialNumber[sd.SerialNumber]; }
|
||||
|
||||
dasChannelIdx = -1;
|
||||
if (pp.SensorDASChannelIndex.ContainsKey(sd.SerialNumber)) { dasChannelIdx = pp.SensorDASChannelIndex[sd.SerialNumber]; }
|
||||
}
|
||||
public static IReadOnlyDictionary<string, int> GetDAS(Dictionary<string, List<TsetSetupImportSensorInfo>> groupSensorLookupgroupSensorLookup,
|
||||
DASHardware[] allDAS)
|
||||
{
|
||||
var lookup = new Dictionary<string, int>();
|
||||
using (var e = groupSensorLookupgroupSensorLookup.GetEnumerator())
|
||||
{
|
||||
while (e.MoveNext())
|
||||
{
|
||||
var list = e.Current.Value;
|
||||
foreach (var sensorDASSerialNumber in list.Select(s => s.DASSerialNumber))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(sensorDASSerialNumber))
|
||||
{
|
||||
if (lookup.ContainsKey(sensorDASSerialNumber)) { continue; }
|
||||
var das = Array.Find(allDAS, d => d.SerialNumber.Equals(sensorDASSerialNumber));
|
||||
if (null == das) { continue; }
|
||||
lookup[sensorDASSerialNumber] = das.DASId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return lookup;
|
||||
}
|
||||
|
||||
public static int? GetGroupId(TestTestObject testObject, Dictionary<string, int> groupIdMapping, List<TestObject> groupList)
|
||||
{
|
||||
foreach (var group in groupList)
|
||||
{
|
||||
if (group.SerialNumber == testObject.SerialNumber)
|
||||
{
|
||||
//Found the embedded Group, now find the static Group
|
||||
foreach (var serialNumber in groupList.Select(p => p.SerialNumber))
|
||||
{
|
||||
if (serialNumber == group.GetISOTestObject().OriginalSerialNumber)
|
||||
{
|
||||
if (groupIdMapping.ContainsKey(serialNumber))
|
||||
{
|
||||
return groupIdMapping[serialNumber];
|
||||
}
|
||||
else
|
||||
{
|
||||
//Must not be from a static Group
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<string> ReverseChannelOrder(TestTemplate testTemplate, Dictionary<string, string> sensorGroupNameLookup, List<SensorData> sensors)
|
||||
{
|
||||
var orders = new List<string>();
|
||||
//store the original channel order
|
||||
//note that for some reason the channels are reversed
|
||||
//I don't change that, I just make sure that when I set the channel order
|
||||
//it's not reversed ...
|
||||
if (sensors == null) { return orders; }
|
||||
|
||||
if (testTemplate == null) { return orders; }
|
||||
|
||||
if (sensorGroupNameLookup != null && sensorGroupNameLookup.Any())
|
||||
{
|
||||
foreach (var ch in sensors)
|
||||
{
|
||||
orders.Add($"{testTemplate.Name}_{sensorGroupNameLookup[ch.SerialNumber]}_{ch.Comment}");
|
||||
}
|
||||
orders.Reverse();
|
||||
}
|
||||
return orders;
|
||||
}
|
||||
|
||||
public static List<SensorData> CleanUneededSensorDataPlaceHolder(Dictionary<string, List<SensorCalibration>> calibrationLookup, List<SensorData> sensorList)
|
||||
{
|
||||
|
||||
// Cleanup unneeded sensor data place holders
|
||||
for (int i = sensorList.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (sensorList[i].SerialNumber.StartsWith(Constants.ISO_CH_ONLY_PREFIX))
|
||||
{
|
||||
// Only an ISO channel
|
||||
sensorList.RemoveAt(i);
|
||||
}
|
||||
else if (sensorList[i].IsSquib() || sensorList[i].IsStreamOutput() || sensorList[i].IsUart() || sensorList[i].IsStreamInput()
|
||||
|| sensorList[i].IsDigitalInput())
|
||||
{
|
||||
//DON'T REMOVE, doesn't have a calibration.
|
||||
}
|
||||
else if (calibrationLookup[sensorList[i].SerialNumber].Exists(sc => sc.CalibrationDate == DateTime.MinValue))
|
||||
{
|
||||
// invalid default cal
|
||||
// likely incomplete sensor reference
|
||||
// Don't try to import this
|
||||
sensorList.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
return sensorList;
|
||||
}
|
||||
|
||||
public static List<SensorData> NormalizeSensorIds(List<SensorData> sensorList)
|
||||
{
|
||||
if(sensorList == null) { return new List<SensorData>(); }
|
||||
|
||||
//normalize sensor ids
|
||||
for (int i = 0; i < sensorList.Count; i++)
|
||||
{
|
||||
var existing = SensorsCollection.SensorsList.GetSensorBySerialNumber(sensorList[i].SerialNumber);
|
||||
|
||||
if (null != existing && existing.IsAnalog())
|
||||
{
|
||||
//FB 41866 If the calibration is null use the one from parsed file
|
||||
existing.Calibration = SensorCalibrationList.GetLatestCalibrationBySerialNumber(existing) ?? existing.Calibration;
|
||||
}
|
||||
|
||||
if (existing != null)
|
||||
{
|
||||
sensorList[i].DatabaseId = existing.DatabaseId;
|
||||
sensorList[i].Calibration = existing.Calibration;
|
||||
}
|
||||
else
|
||||
{
|
||||
//normalize to -2 ... -n (-1 preserved for no sensor)
|
||||
sensorList[i].DatabaseId = -1 * (2 + i);
|
||||
}
|
||||
|
||||
}
|
||||
return sensorList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using static DTS.Common.Enums.Sensors.SensorConstants;
|
||||
using System.IO;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Slice.Users;
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Import.Parsers;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.Import.Factories;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class DTSCSVSensorsParser : ParseVariantBase
|
||||
{
|
||||
private readonly List<string> Errors = new List<string>();
|
||||
private readonly User _currentUser;
|
||||
private readonly CsvImportOptions _csvImportOptions;
|
||||
private readonly ICalibrationImport _calibrationImport;
|
||||
private readonly ZeroMethodOptions _zeroMethodOptions;
|
||||
private readonly IImportNotification _importNotification;
|
||||
public DTSCSVSensorsParser(IImportNotification importNotification, User user, CsvImportOptions csvImportOptions,
|
||||
ICalibrationImport calibrationImport, ZeroMethodOptions zeroMethodOptions)
|
||||
{
|
||||
_currentUser = user;
|
||||
_csvImportOptions = csvImportOptions;
|
||||
_calibrationImport = calibrationImport;
|
||||
_zeroMethodOptions = zeroMethodOptions;
|
||||
_importNotification = importNotification;
|
||||
}
|
||||
|
||||
public bool ImportCreateDynamicGroups { get; set; }
|
||||
public bool UseISOCodeFilterMapping { get; set; }
|
||||
public bool UseZeroForUnfiltered { get; set; }
|
||||
|
||||
|
||||
private ISquibSettingDefaults GetSquibDefaults()
|
||||
{
|
||||
return SquibSettingDefaults.GetSquibSettingsDefault(_currentUser.UserName);
|
||||
}
|
||||
private IDigitalOutDefaults GetDigitalOutDefaults()
|
||||
{
|
||||
return DigitalOutputDefaults.GetDigitalOutDefault(_currentUser.UserName);
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
|
||||
if (string.IsNullOrEmpty(FileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (importObject == null)
|
||||
{
|
||||
throw new ArgumentNullException("importObject", "importObject can't be null or empty");
|
||||
}
|
||||
|
||||
importObject = ParseSensor(importObject, FileName);
|
||||
AssignErrorsToImportObject(ref importObject);
|
||||
}
|
||||
|
||||
private void AssignErrorsToImportObject(ref ImportObject importObject)
|
||||
{
|
||||
//FB 42971 Assign errors in this parser to the import object errors property to be reported to user
|
||||
foreach (var error in Errors)
|
||||
{
|
||||
importObject.AddError(new ImportError { ContinueImportOnError = true, Message = error, Severity = ImportSeverityError.Error });
|
||||
}
|
||||
}
|
||||
|
||||
private ImportObject ParseSensor(ImportObject importObject, string filename)
|
||||
{
|
||||
var columns = new List<CSVImportTags.Tags>();
|
||||
var line = 2;
|
||||
var version = 0;
|
||||
var sensorGroupNameLookup = new Dictionary<string, string>();
|
||||
var sensorGroupTypeLookup = new Dictionary<string, string>();
|
||||
var groupNameTestObjectLookup = new Dictionary<string, string>();
|
||||
var sensorISOCode = new Dictionary<string, string>();
|
||||
var sensorISOChannelName = new Dictionary<string, string>();
|
||||
var sensorUserCode = new Dictionary<string, string>();
|
||||
var sensorUserChannelName = new Dictionary<string, string>();
|
||||
var sensorDASSerialNumber = new Dictionary<string, string>();
|
||||
var sensorDASChannelIdx = new Dictionary<string, int>();
|
||||
var pp = new ParseParameters()
|
||||
{
|
||||
ImportCulture = _csvImportOptions.ImportCulture,
|
||||
StripBackslash = _csvImportOptions.StripBackSlash,
|
||||
SensorGroupNameLookup = sensorGroupNameLookup,
|
||||
SensorGroupTypeLookup = sensorGroupTypeLookup,
|
||||
GroupNameToTestObjectLookup = groupNameTestObjectLookup,
|
||||
UseISOCodeFilterMapping = UseISOCodeFilterMapping,
|
||||
UseZeroForUnfiltered = UseZeroForUnfiltered,
|
||||
SensorISOCode = sensorISOCode,
|
||||
SensorISOChannelName = sensorISOChannelName,
|
||||
SensorUserCode = sensorUserCode,
|
||||
SensorUserChannelName = sensorUserChannelName,
|
||||
SensorDASSerialNumber = sensorDASSerialNumber,
|
||||
SensorDASChannelIndex = sensorDASChannelIdx
|
||||
};
|
||||
|
||||
using (var parser = CsvUtil.CreateCsvReader(filename))
|
||||
{
|
||||
var tokens = CsvUtil.ReadFields(parser);
|
||||
|
||||
if (tokens != null && tokens[0] == "Version")
|
||||
{
|
||||
var tokens2 = CsvUtil.ReadFields(parser);
|
||||
|
||||
if (tokens2 != null)
|
||||
{
|
||||
int.TryParse(tokens2[0], out version);
|
||||
}
|
||||
if (version == 6)
|
||||
{
|
||||
//read until you have no empty start and the tag is < 5
|
||||
while (parser.Read())
|
||||
{
|
||||
tokens = CsvUtil.ReadFields(parser, false);
|
||||
if (null == tokens || string.IsNullOrWhiteSpace(tokens[0])) { continue; }
|
||||
var tag = CSVImportTags.GetTagForString(tokens[0]);
|
||||
if (tag == CSVImportTags.Tags.Unknown) { continue; }
|
||||
var tagVersion = CSVImportTags.GetVersionForTag(tag);
|
||||
if (tagVersion > 4) { continue; }
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parser.Read();//read an empty line
|
||||
tokens = CsvUtil.ReadFields(parser);
|
||||
}
|
||||
}
|
||||
|
||||
if (tokens == null)
|
||||
{
|
||||
Errors.Clear();
|
||||
Errors.Add("No tokens to parse");
|
||||
return importObject;
|
||||
}
|
||||
|
||||
foreach (var token in tokens)
|
||||
{
|
||||
columns.Add(CSVImportTags.GetTagForString(token));
|
||||
}
|
||||
|
||||
if (0 == columns.Count)
|
||||
{
|
||||
//NONE of the columns row was recognized, PopulateSensor below will fail as it uses this to populate the sensor
|
||||
//this will not import any further, so shortcut to an error to the user
|
||||
//14745 Vague error message when Test Setup import is attempted
|
||||
|
||||
Errors.Clear();
|
||||
Errors.Add(StringResources.ImportSensorsPreviewControl_NoColumnsInTDCCSV);
|
||||
return importObject;
|
||||
}
|
||||
|
||||
var squibDefaults = GetSquibDefaults();
|
||||
var digitalOutDefaults = GetDigitalOutDefaults();
|
||||
|
||||
//18259 DataPRO XML and CSV imports let you import inconsistent SensitvityUnits
|
||||
var sensorsWithUpdatedSensitivityUnits = new List<string>();
|
||||
while (parser.Read())
|
||||
{
|
||||
tokens = CsvUtil.ReadFields(parser, false);
|
||||
if (null == tokens) { break; }
|
||||
var sd = new SensorData();
|
||||
var sc = new SensorCalibration();
|
||||
pp.SensorData = sd;
|
||||
pp.SensorCal = sc;
|
||||
pp.SquibDefaults = squibDefaults;
|
||||
pp.DigitalOutDefaults = digitalOutDefaults;
|
||||
if (!PopulateSensor(columns, tokens.ToArray(), File.GetLastWriteTime(filename), pp))
|
||||
{
|
||||
//pp.Errors contains all the errors related to this sensor which is parsed
|
||||
var errorMessage = $"Line {line}: {string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator, pp.Errors)}";
|
||||
Errors.Add(errorMessage);
|
||||
line++;
|
||||
continue;
|
||||
}
|
||||
if (!sc.IsProportional && sc.Records.Records[0].SensitivityUnits == SensUnits.mVperVperEU)
|
||||
{
|
||||
sc.Records.Records[0].SensitivityUnits = SensUnits.mVperEU;
|
||||
if (!sensorsWithUpdatedSensitivityUnits.Contains(sd.SerialNumber))
|
||||
{
|
||||
sensorsWithUpdatedSensitivityUnits.Add(sd.SerialNumber);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sd.SerialNumber.StartsWith(Constants.ISO_CH_ONLY_PREFIX))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(sd.SerialNumber))
|
||||
{
|
||||
importObject.AddSensorLookup(sd.SerialNumber, sd);
|
||||
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(sd.SerialNumber))
|
||||
{
|
||||
importObject.AddCalibrationLookup(sd.SerialNumber, new List<SensorCalibration>(new[] { sc }));
|
||||
}
|
||||
}
|
||||
|
||||
// this is for compatability for import test setups
|
||||
importObject.AddSensor(sd);
|
||||
importObject.AddSensorChannelCodeLookup(sd.SettingName, sd.SerialNumber);
|
||||
// this is for compatability for import test setups
|
||||
importObject.AddCalibration(sc);
|
||||
line++;
|
||||
}
|
||||
|
||||
if (sensorsWithUpdatedSensitivityUnits.Any())
|
||||
{
|
||||
var msg = $"{StringResources.SensorsUpdatedSensitivityUnits} {string.Join(", ", sensorsWithUpdatedSensitivityUnits.ToArray())}";
|
||||
_importNotification.ReportErrors(new List<string>(new[] { msg }));
|
||||
}
|
||||
}
|
||||
importObject.AssignSensorGroupNameLookup(sensorGroupNameLookup);
|
||||
importObject.AssignSensorGroupTypeLookup(sensorGroupTypeLookup);
|
||||
importObject.AssignGroupNameTestObjectLookup(groupNameTestObjectLookup);
|
||||
importObject.AssignParseParameters(pp);
|
||||
return importObject;
|
||||
}
|
||||
|
||||
private void Preparse(ParseParameters pp)
|
||||
{
|
||||
var sd = (SensorData)pp.SensorData;
|
||||
sd.Initialize(pp.SquibDefaults);
|
||||
sd.Initialize(pp.DigitalOutDefaults);
|
||||
}
|
||||
private void PostParse(ParseParameters pp)
|
||||
{
|
||||
var sd = (SensorData)pp.SensorData;
|
||||
var sc = (SensorCalibration)pp.SensorCal;
|
||||
sd.InitializeTag(sd.Bridge);
|
||||
|
||||
pp.SensorCal.SerialNumber = pp.SensorData.SerialNumber;
|
||||
if (!double.IsNaN(pp.IrtraccExponent) && pp.SensorData.SensorCategory == (int)SensorInformationFile.TDCSensorCategory.IRTracc)
|
||||
{
|
||||
pp.SensorCal.IsProportional = false;
|
||||
pp.SensorCal.NonLinear = true;
|
||||
if (pp.SensorCal.Records.Records[0].Poly.NonLinearStyle == NonLinearStyles.IRTraccAverageOverTime)
|
||||
{
|
||||
pp.SensorCal.Records.Records[0].Poly.MMPerV = 1000D / pp.Sensitivity;
|
||||
pp.SensorCal.Records.Records[0].Poly.LinearizationExponent = pp.IrtraccExponent;
|
||||
pp.SensorCal.Records.Records[0].Poly.NonLinearStyle = NonLinearStyles.IRTraccAverageOverTime;
|
||||
}
|
||||
pp.SensorCal.Records.Records[0].Poly.MarkValid(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
pp.SensorCal.Records.Records[0].Sensitivity = pp.Sensitivity;
|
||||
if (pp.SensorCal.IsProportional) { pp.SensorCal.Records.Records[0].Excitation = pp.SensorData.SupportedExcitation.First(); }
|
||||
}
|
||||
if (!double.IsNaN(pp.OriginalOffset))
|
||||
{
|
||||
pp.SensorCal.InitialOffsets.Offsets[0].EU = pp.OriginalOffset;
|
||||
pp.SensorCal.InitialOffsets.Offsets[0].Form = InitialOffsetTypes.EU;
|
||||
}
|
||||
pp.SensorCal.ZeroMethods = new ZeroMethods(new[] { new ZeroMethod(pp.ZeroType, pp.ZeroStart, pp.ZeroEnd) });
|
||||
if (sd.SerialNumber.StartsWith(Constants.ISO_CH_ONLY_PREFIX) && !string.IsNullOrEmpty(sd.ISOCode)) { pp.Errors = new List<string>(); }
|
||||
|
||||
//warn if we are analog and have 0 sensitivity ...
|
||||
if (pp.SensorCal.Records.Records[0].Sensitivity == 0D && !sd.IsDigitalOutput() && !sd.IsDigitalInput() && !sd.IsSquib()
|
||||
&& !sd.IsUart() && !sd.IsStreamInput() && !sd.IsStreamOutput() && !sd.IsCan())
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.InvalidEmptySensitivity, sd.SerialNumber));
|
||||
}
|
||||
//warn if we are analog and have invalid capacity
|
||||
if (sd.Capacity < 1 && !sd.IsDigitalInput() && !sd.IsDigitalOutput() && !sd.IsSquib()
|
||||
&& !sd.IsUart() && !sd.IsStreamOutput() && !sd.IsStreamInput() && !sd.IsCan())
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.ImportSensor_InvalidCapacity, sd.SerialNumber,
|
||||
sd.Capacity));
|
||||
}
|
||||
//warn if we are analog and have invalid excitation
|
||||
if (IsAnalogWithInvalidExcitation(sd, sc))
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.InvalidExcitation,
|
||||
pp.SensorCal.Records.Records[0].Excitation));
|
||||
}
|
||||
if (IsAnalogWithInvalidSensitivity(sd, sc))
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.InvalidEmptySensitivity,
|
||||
sd.SerialNumber));
|
||||
}
|
||||
}
|
||||
private void Parse(CSVImportTags.Tags tag, string sValue, ParseParameters pp,
|
||||
IReadOnlyDictionary<int, IParseCSVSensor> parsers)
|
||||
{
|
||||
var version = CSVImportTags.GetVersionForTag(tag);
|
||||
if (parsers.ContainsKey(version))
|
||||
{
|
||||
parsers[version].ParseVersion(tag, sValue, pp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// scans throw a line of tokens in an expected column order and populates a sensor and a sensor calibration with data from that line
|
||||
/// errors is populated with any errors encountered during the import
|
||||
/// returns true if any errors were detected.
|
||||
/// </summary>
|
||||
/// <param name="columns"></param>
|
||||
/// <param name="tokens"></param>
|
||||
/// <param name="sd"></param>
|
||||
/// <param name="errors"></param>
|
||||
/// <param name="sc"></param>
|
||||
/// <param name="fileDateTime"></param>
|
||||
/// <param name="importCulture"></param>
|
||||
/// <param name="sensorGroupNameLookup"></param>
|
||||
/// <param name="sensorGroupTypeLookup"></param>
|
||||
/// <param name="squibDefaults"></param>
|
||||
/// <param name="digitalOutDefaults"></param>
|
||||
/// <param name="groupNameToTestObjectLookup"></param>
|
||||
/// <param name="stripBackslash"></param>
|
||||
/// <param name="useISOCodeFilterMapping"></param>
|
||||
/// <param name="useZeroForUnfiltered"></param>
|
||||
/// <returns></returns>
|
||||
private bool PopulateSensor(IReadOnlyList<CSVImportTags.Tags> columns,
|
||||
string[] tokens,
|
||||
DateTime fileDateTime,
|
||||
ParseParameters pp
|
||||
)
|
||||
{
|
||||
pp.SensorData.LastModified = fileDateTime;
|
||||
pp.IrtraccExponent = double.NaN;
|
||||
pp.Sensitivity = double.NaN;
|
||||
pp.SensorCal.ModifyDate = DateTime.Now;
|
||||
pp.ZeroType = pp.SensorCal.ZeroMethods.Methods.First().Method;
|
||||
pp.ZeroEnd = pp.SensorCal.ZeroMethods.Methods.First().End;
|
||||
pp.ZeroStart = pp.SensorCal.ZeroMethods.Methods.First().Start;
|
||||
pp.SavedIsProportional = false;
|
||||
pp.SavedRemoveOffset = false;
|
||||
//FB 42971 for each senosr starts with no errors
|
||||
pp.Errors = new List<string>();
|
||||
Preparse(pp);
|
||||
|
||||
var parsers = CSVSensorParserFactory.CreateCSVParsers(_calibrationImport, _zeroMethodOptions,
|
||||
_importNotification, ImportCreateDynamicGroups, UseISOCodeFilterMapping,
|
||||
UseZeroForUnfiltered);
|
||||
|
||||
for (var i = 0; i < columns.Count; i++)
|
||||
{
|
||||
var field = columns[i];
|
||||
var val = tokens[i];
|
||||
if (val.StartsWith("'") && !val.StartsWith("''")) { val = val.Substring(1); }
|
||||
try
|
||||
{
|
||||
Parse(field, val, pp, parsers);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log($"Failed to parse tags version {i}", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PostParse(pp);
|
||||
|
||||
return !pp.Errors.Any();
|
||||
}
|
||||
|
||||
private static bool IsAnalogWithInvalidExcitation(SensorData sd, SensorCalibration sc)
|
||||
{
|
||||
return sc.Records.Records[0].Excitation ==
|
||||
ExcitationVoltageOptions.ExcitationVoltageOption.Undefined &&
|
||||
(sd.Bridge == BridgeType.FullBridge ||
|
||||
sd.Bridge == BridgeType.HalfBridge ||
|
||||
sd.Bridge == BridgeType.QuarterBridge);
|
||||
}
|
||||
private static bool IsAnalogWithInvalidSensitivity(SensorData sd, SensorCalibration sc)
|
||||
{
|
||||
if (sd == null || sc == null || null == sc.Records || null == sc.Records.Records || 0 == sc.Records.Records.Length) { return true; }
|
||||
return sd.IsAnalog() && Math.Abs(sc.Records.Records[0].Sensitivity) < .0000001;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseDASList : XMLParseBase
|
||||
{
|
||||
public XMLParseDASList(XmlElement root, double importedVersion, Func<bool> isCancelled = null, bool skipNormalizing=false) : base(root, importedVersion, isCancelled, skipNormalizing)
|
||||
{
|
||||
_dasIdMapping.Clear();
|
||||
}
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public List<DASHardware> ParseDASList(XmlElement root)
|
||||
{
|
||||
List<DASHardware> dasList = new List<DASHardware>();
|
||||
var invalidDAS = new List<string>();
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return dasList; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
var isoHardware = DASHardware.ReadXML(node as XmlElement);
|
||||
if (Enum.IsDefined(typeof(DTS.Common.Enums.Hardware.HardwareTypes), isoHardware.DASType))
|
||||
{
|
||||
dasList.Add(new DASHardware(isoHardware));
|
||||
}
|
||||
else
|
||||
{
|
||||
invalidDAS.Add(isoHardware.SerialNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (invalidDAS.Any())
|
||||
{
|
||||
//???
|
||||
}
|
||||
return dasList;
|
||||
}
|
||||
|
||||
private XmlElement ConvertDASList(List<DASHardware> dasList)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.DASList.ToString());
|
||||
var count = -2; //Start the normalization at -2, since channels have a DASId of -1 if unassigned (FB 13544)
|
||||
foreach (var h in dasList)
|
||||
{
|
||||
_dasIdMapping[h.DASId] = count;
|
||||
h.SetDASId(count);
|
||||
count--;
|
||||
|
||||
_writer.Flush();
|
||||
h.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
|
||||
return GetXmlElement();
|
||||
}
|
||||
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingHardware });
|
||||
var dasList = ParseDASList(_root);
|
||||
if (!_skipNormalizing)
|
||||
{
|
||||
var newRoot = ConvertDASList(dasList);
|
||||
dasList = ParseDASList(newRoot);
|
||||
}
|
||||
importObject.AddHardwareList(dasList);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Import.Parsers.CSV;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.Common.Import.Factories
|
||||
{
|
||||
public class CSVSensorParserFactory
|
||||
{
|
||||
public static IReadOnlyDictionary<int, IParseCSVSensor> CreateCSVParsers(ICalibrationImport import, ZeroMethodOptions zmOptions,
|
||||
IImportNotification importNotification, bool importCreateDynamicGroups,
|
||||
bool useISOCodeFilterMapping, bool useZeroForUnfiltered)
|
||||
{
|
||||
var parsers = new Dictionary<int, IParseCSVSensor>();
|
||||
|
||||
var v0 = new Version0CSVSensorParser();
|
||||
v0.Initialize(import, zmOptions, importNotification, importCreateDynamicGroups, useISOCodeFilterMapping,
|
||||
useZeroForUnfiltered);
|
||||
parsers[v0.Version] = v0;
|
||||
|
||||
var v2 = new Version2CSVSensorParser();
|
||||
v2.Initialize(import, zmOptions, importNotification, importCreateDynamicGroups, useISOCodeFilterMapping,
|
||||
useZeroForUnfiltered);
|
||||
parsers[v2.Version] = v2;
|
||||
|
||||
var v3 = new Version3CSVSensorParser();
|
||||
v3.Initialize(import, zmOptions, importNotification, importCreateDynamicGroups, useISOCodeFilterMapping,
|
||||
useZeroForUnfiltered);
|
||||
parsers[v3.Version] = v3;
|
||||
|
||||
var v4 = new Version4CSVSensorParser();
|
||||
v4.Initialize(import, zmOptions, importNotification, importCreateDynamicGroups, useISOCodeFilterMapping,
|
||||
useZeroForUnfiltered);
|
||||
parsers[v4.Version] = v4;
|
||||
|
||||
return parsers;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
|
||||
namespace DTS.Common.Import.Parsers
|
||||
{
|
||||
public abstract class ParseVariantBase : IParseVariant
|
||||
{
|
||||
public string FileName { get; set; }
|
||||
|
||||
public abstract void Parse(ref ImportObject importObject);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
|
||||
namespace DTS.Common.Import.Interfaces
|
||||
{
|
||||
public interface IParseCSVSensor
|
||||
{
|
||||
int Version { get; }
|
||||
void Initialize(ICalibrationImport import, ZeroMethodOptions zmOptions,
|
||||
IImportNotification importNotification, bool importCreateDynamicGroups,
|
||||
bool useIsoCodeFilterMapping, bool useZeroForUnfiltered);
|
||||
void ParseVersion(CSVImportTags.Tags field, string val, ParseParameters pp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Classes.Groups;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.Storage;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
//FB 36879 updated to handle csv group process logic only
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class CSVGroupImport : IGroupImport
|
||||
{
|
||||
public ParseParameters ParseParameters { get; set; }
|
||||
public Tuple<TestTemplate, List<IGroup>> CreateGroups(List<SensorData> sensors, Dictionary<string, List<TsetSetupImportSensorInfo>> groupSensorLookup,
|
||||
TestTemplate testTemplate, bool createDynamicGroups, List<IGroup> staticGroups, Action<double> setProgress)
|
||||
{
|
||||
var channelDefaults = DbOperations.GetChannelSettingDefaults();
|
||||
var sensorLookup = sensors.ToDictionary(s => s.SerialNumber);
|
||||
|
||||
if (groupSensorLookup == null || !groupSensorLookup.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var allDAS = DataPROWin7.DataModel.Classes.Hardware.DASHardwareList.GetAllHardware();
|
||||
|
||||
var dasSerialToId = GroupHelper.GetDAS(groupSensorLookup, allDAS);
|
||||
if (dasSerialToId.Count > 0)
|
||||
{
|
||||
using (var e = dasSerialToId.GetEnumerator())
|
||||
{
|
||||
while (e.MoveNext())
|
||||
{
|
||||
testTemplate.AddHardware(e.Current.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int total = groupSensorLookup.Count;
|
||||
int current = 0;
|
||||
var displayOrder = 1;
|
||||
|
||||
foreach (var group in groupSensorLookup)
|
||||
{
|
||||
// Make your template
|
||||
var newGroup = GroupHelper.CreateEmptyGroup();
|
||||
newGroup.Name = group.Key;
|
||||
newGroup.DisplayName = newGroup.Name;
|
||||
|
||||
var importTemplateChannelList = group.Value;
|
||||
List<Interface.Channels.IGroupChannel> groupChannels = new List<Interface.Channels.IGroupChannel>();
|
||||
foreach (var ch in importTemplateChannelList)
|
||||
{
|
||||
var groupChannel = new GroupChannel(false, newGroup.DisplayName, newGroup, channelDefaults);
|
||||
if (!string.IsNullOrWhiteSpace(ch.DASSerialNumber) && dasSerialToId.ContainsKey(ch.DASSerialNumber))
|
||||
{
|
||||
groupChannel.DASId = dasSerialToId[ch.DASSerialNumber];
|
||||
}
|
||||
if (ch.DASChannelIndex >= 0)
|
||||
{
|
||||
groupChannel.DASChannelIndex = ch.DASChannelIndex;
|
||||
}
|
||||
|
||||
if (sensorLookup.ContainsKey(ch.SerialNumber))
|
||||
{
|
||||
var sd = sensorLookup[ch.SerialNumber];
|
||||
var tsetSetupImportSensorInfo = group.Value.Find(p => p.SerialNumber == ch.SerialNumber && p.DASSerialNumber == ch.DASSerialNumber);
|
||||
if (tsetSetupImportSensorInfo != null)
|
||||
{
|
||||
groupChannel.IsoChannelName = tsetSetupImportSensorInfo.IsoChannelName;
|
||||
groupChannel.UserChannelName = tsetSetupImportSensorInfo.UserChannelName;
|
||||
groupChannel.UserCode = tsetSetupImportSensorInfo.UserCode;
|
||||
groupChannel.IsoCode = tsetSetupImportSensorInfo.IsoCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
groupChannel.IsoChannelName = sd.Comment;
|
||||
groupChannel.UserChannelName = sd.Comment;
|
||||
groupChannel.UserCode = ch.UserCode;
|
||||
groupChannel.IsoCode = ch.IsoCode;
|
||||
}
|
||||
|
||||
groupChannel.SetSensorData(sd, null, true);
|
||||
groupChannel.SensorId = sd.DatabaseId;
|
||||
groupChannel.Range = sd.Capacity;
|
||||
|
||||
//http://manuscript.dts.local/f/cases/43490/Full-scale-is-used-for-channel-desired-range-in-import
|
||||
//set range using sd.Range if it's set and it's different than capacity and is valid
|
||||
//the default value is 0 so if we have a non zero value it should have been explicitly set
|
||||
//in the CSV import version this gets set to rangelow/rangehigh/rangemedium
|
||||
if (!ParseParameters.ImportContainedSensorRanges && sd.RangeHigh == sd.RangeLow && sd.RangeLow == sd.RangeMedium && Math.Abs(sd.Capacity - sd.RangeLow) > .1 && sd.IsAnalog() && sd.RangeMedium > 1)
|
||||
{
|
||||
groupChannel.Range = sd.RangeLow;
|
||||
}
|
||||
|
||||
groupChannel.FilterClass = sd.FilterClass;
|
||||
groupChannel.Polarity = sd.Polarity;
|
||||
|
||||
groupChannel.SquibLimitDuration = sd.LimitSquibFireDuration;
|
||||
groupChannel.SquibDuration = sd.SquibFireDurationMS;
|
||||
groupChannel.SquibDelay = sd.SquibFireDelayMS;
|
||||
groupChannel.SquibFireMode = sd.SquibFireMode;
|
||||
groupChannel.SquibCurrent = sd.SquibOutputCurrent;
|
||||
|
||||
groupChannel.DigitalOutputMode = sd.DigitalOutputMode;
|
||||
groupChannel.DigitalOutDelay = sd.DigitalOutputDelayMS;
|
||||
groupChannel.DigitalOutDuration = sd.DigitalOutputDurationMS;
|
||||
|
||||
groupChannel.DigitalInputMode = sd.InputMode;
|
||||
groupChannel.ActiveValue = sd.InputActiveValue.ToString("N0");
|
||||
groupChannel.DefaultValue = sd.InputDefaultValue.ToString("N0");
|
||||
|
||||
if (null != sd.Calibration)
|
||||
{
|
||||
groupChannel.AvailableInitialOffsets = sd.Calibration.InitialOffsets.Offsets;
|
||||
groupChannel.InitialOffset = sd.Calibration.InitialOffsets.DefaultOffset;
|
||||
//FB 36905 & 35530 check for null
|
||||
groupChannel.ZeroMethod = sd.Calibration.ZeroMethods.Methods[0].Method;
|
||||
groupChannel.ZeroMethodStart = sd.Calibration.ZeroMethods.Methods[0].Start;
|
||||
groupChannel.ZeroMethodEnd = sd.Calibration.ZeroMethods.Methods[0].End;
|
||||
}
|
||||
|
||||
groupChannel.GroupChannelOrder = 1 + sensors.IndexOf(sd);
|
||||
groupChannel.TestSetupOrder = 1 + sensors.IndexOf(sd);
|
||||
}
|
||||
groupChannels.Add(groupChannel);
|
||||
}
|
||||
newGroup.GroupChannelList = groupChannels;
|
||||
if (!createDynamicGroups)
|
||||
{
|
||||
staticGroups.Add(newGroup);
|
||||
}
|
||||
newGroup.DisplayOrder = displayOrder++;
|
||||
testTemplate.Groups.Add(newGroup);
|
||||
testTemplate.ChannelsForGroup[newGroup] = groupChannels.ToArray();
|
||||
|
||||
setProgress(100D * current / total);
|
||||
current++;
|
||||
}
|
||||
return Tuple.Create(testTemplate, staticGroups);
|
||||
|
||||
}
|
||||
|
||||
public Dictionary<string, List<TsetSetupImportSensorInfo>> GetGroupSensorLookup(List<SensorData> sensors, Dictionary<string, string> sensorGroupNameLookup, Dictionary<string, List<string>> groupNameSensorListLookup)
|
||||
{
|
||||
Dictionary<string, List<TsetSetupImportSensorInfo>> groupSensorLookup = new Dictionary<string, List<TsetSetupImportSensorInfo>>();
|
||||
//FB 30358 Either sensorGroupNameLookup or groupNameSensorListLookup will be populated. dependes on the child class
|
||||
if (sensorGroupNameLookup != null && sensorGroupNameLookup.Any())
|
||||
{
|
||||
groupSensorLookup = sensorGroupNameLookup.Values.Distinct().AsEnumerable().
|
||||
ToDictionary(groupName => groupName, groupName => new List<TsetSetupImportSensorInfo>());
|
||||
|
||||
foreach (var s in sensors)
|
||||
{
|
||||
// Build the group sensor and group type dictionary
|
||||
if (!sensorGroupNameLookup.ContainsKey(s.SerialNumber)) continue;
|
||||
|
||||
GroupHelper.GetTestSensorParameters(out var isoCode, out var isoChannelName, out var userCode, out var userChannelName, ParseParameters,
|
||||
s, out var dasSerialNumber, out var dasChannelIdx);
|
||||
|
||||
// add to group dictionary
|
||||
groupSensorLookup[sensorGroupNameLookup[s.SerialNumber]].Add(new TsetSetupImportSensorInfo(s.SerialNumber, isoCode,
|
||||
isoChannelName, userCode, userChannelName, dasSerialNumber, dasChannelIdx));
|
||||
}
|
||||
}
|
||||
|
||||
if (groupNameSensorListLookup != null && groupNameSensorListLookup.Any())
|
||||
{
|
||||
foreach (var g in groupNameSensorListLookup)
|
||||
{
|
||||
groupSensorLookup.Add(g.Key, new List<TsetSetupImportSensorInfo>());
|
||||
foreach (var sensorSerialNumber in g.Value)
|
||||
{
|
||||
var sd = sensors.Find(s => s.SerialNumber == sensorSerialNumber);
|
||||
|
||||
if (sd != null)
|
||||
{
|
||||
GroupHelper.GetTestSensorParameters(out var isoCode, out var isoChannelName, out var userCode, out var userChannelName,
|
||||
ParseParameters, sd, out var dasSerialNumber, out var dasChannelIdx);
|
||||
groupSensorLookup[g.Key].Add(new TsetSetupImportSensorInfo(sd.SerialNumber, sd.ISOCode,
|
||||
isoChannelName, userCode, userChannelName, dasSerialNumber, dasChannelIdx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return groupSensorLookup;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Import.ImportOptions;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
|
||||
namespace DTS.Common.Import.Parsers.CSV
|
||||
{
|
||||
public abstract class AbstractCSVParser : IParseCSVSensor
|
||||
{
|
||||
public abstract int Version { get; }
|
||||
protected ICalibrationImport _calibrationImport;
|
||||
protected ZeroMethodOptions _zeroMethodOptions;
|
||||
protected IImportNotification _importNotification;
|
||||
protected bool ImportCreateDynamicGroups { get; set; }
|
||||
protected bool UseISOCodeFilterMapping { get; set; }
|
||||
protected bool UseZeroForUnfiltered { get; set; }
|
||||
public void Initialize(ICalibrationImport import, ZeroMethodOptions zmOptions,
|
||||
IImportNotification importNotification, bool importCreateDynamicGroups,
|
||||
bool useISOCodeFilterMapping, bool useZeroForUnfiltered)
|
||||
{
|
||||
_calibrationImport = import;
|
||||
_zeroMethodOptions = zmOptions;
|
||||
_importNotification = importNotification;
|
||||
ImportCreateDynamicGroups = importCreateDynamicGroups;
|
||||
UseISOCodeFilterMapping = useISOCodeFilterMapping;
|
||||
UseZeroForUnfiltered = useZeroForUnfiltered;
|
||||
}
|
||||
|
||||
public abstract void ParseVersion(CSVImportTags.Tags field, string val, ParseParameters pp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using DTS.Common.Classes;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using Microsoft.VisualBasic.FileIO;
|
||||
|
||||
namespace DTS.Common.Import.Interfaces
|
||||
{
|
||||
public interface IParseCSVTest
|
||||
{
|
||||
int Version { get; }
|
||||
void ParseVersion(TextFieldParser parser, TestSetupImportData tsid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Text;
|
||||
|
||||
namespace DTS.Common.Import.Interfaces
|
||||
{
|
||||
//FB 36740 Interface to support database locks
|
||||
|
||||
public interface ILockImport
|
||||
{
|
||||
//Return true if the collection of conteneded has any items
|
||||
bool Contended { get; }
|
||||
//Set the database lock for particular import object, empty message should be passed and in case of errors it will be populated. this error message is shared between all
|
||||
//types and would contain all the errors regarding db locks
|
||||
void SetLock(ref ImportObject importObject, ref StringBuilder message);
|
||||
//Free the database lock
|
||||
void FreeLock(ref ImportObject importObject);
|
||||
//Steal the database lock
|
||||
bool StealLock(bool proceed);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseTestEngineerDetails : XMLParseBase
|
||||
{
|
||||
public XMLParseTestEngineerDetails(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
var details = ParseTestEngineerDetails(_root);
|
||||
var newRoot = ConvertTestEngineerDetails(details);
|
||||
details = ParseTestEngineerDetails(newRoot);
|
||||
importObject.AddTestEngineerDetailsList(details);
|
||||
}
|
||||
|
||||
private XmlElement ConvertTestEngineerDetails(IEnumerable<ISO.TestEngineerDetails> details)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.TestEngineerDetails.ToString());
|
||||
foreach (var c in details)
|
||||
{
|
||||
_writer.Flush();
|
||||
c.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
}
|
||||
private List<ISO.TestEngineerDetails> ParseTestEngineerDetails(XmlElement root)
|
||||
{
|
||||
List<ISO.TestEngineerDetails> details = new List<ISO.TestEngineerDetails>();
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return details; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
details.Add(ISO.TestEngineerDetails.ReadXML(node as XmlElement));
|
||||
}
|
||||
}
|
||||
return details;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,468 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Import.Enums;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.Common.ISO;
|
||||
using DTS.SensorDB;
|
||||
using DTS.Slice.Users;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class ImportObject
|
||||
{
|
||||
public ImportFormats SourceFormat { get; set; } = ImportFormats.NOT_SPECIFIED;
|
||||
|
||||
private readonly List<TestTemplate> _testSetups = new List<TestTemplate>();
|
||||
private readonly List<SensorCalibration> _calibrations = new List<SensorCalibration>();
|
||||
|
||||
private readonly List<DataPROWin7.DataModel.TestObjectTemplate> _groupTemplates = new List<DataPROWin7.DataModel.TestObjectTemplate>();
|
||||
|
||||
private readonly List<SensorData> _sensors = new List<SensorData>();
|
||||
private readonly List<DASHardware> _hardware = new List<DASHardware>();
|
||||
|
||||
private readonly List<Interface.Groups.GroupList.IGroup> _iGroups = new List<Interface.Groups.GroupList.IGroup>();
|
||||
private readonly List<DataPROWin7.DataModel.TestObject> _groupList = new List<DataPROWin7.DataModel.TestObject>();
|
||||
|
||||
private readonly List<MMEPositions> _positions = new List<MMEPositions>();
|
||||
private readonly List<MMEPhysicalDimensions> _physicalDimensions = new List<MMEPhysicalDimensions>();
|
||||
private readonly List<MMETransducerMainLocation> _mainLocations = new List<MMETransducerMainLocation>();
|
||||
private readonly List<MMEDirections> _directions = new List<MMEDirections>();
|
||||
private readonly List<MMEFilterClasses> _filterClasses = new List<MMEFilterClasses>();
|
||||
private readonly List<MMEFineLocations1> _fineLoc1s = new List<MMEFineLocations1>();
|
||||
private readonly List<MMEFineLocations2> _fineLoc2s = new List<MMEFineLocations2>();
|
||||
private readonly List<MMEFineLocations3> _fineLoc3s = new List<MMEFineLocations3>();
|
||||
private readonly List<MMETestObjects> _testObjects = new List<MMETestObjects>();
|
||||
private readonly List<MMEPossibleChannels> _customChannels = new List<MMEPossibleChannels>();
|
||||
|
||||
private readonly List<ISO.CustomerDetails> _customerDetails = new List<ISO.CustomerDetails>();
|
||||
private readonly List<ISO.TestEngineerDetails> _testEngineerDetails = new List<ISO.TestEngineerDetails>();
|
||||
private readonly List<ISO.LabratoryDetails> _labDetails = new List<ISO.LabratoryDetails>();
|
||||
|
||||
private Dictionary<string, string> _globalSettings = new Dictionary<string, string>();
|
||||
private readonly List<User> _users = new List<User>();
|
||||
|
||||
private Dictionary<string, SensorData> _sensorLookup = new Dictionary<string, SensorData>();
|
||||
private Dictionary<string, SensorModel> _sensorModelLookup = new Dictionary<string, SensorModel>();
|
||||
private readonly List<SensorModel> _sensorModels = new List<SensorModel>();
|
||||
|
||||
private Dictionary<string, List<SensorCalibration>> _calibrationLookup = new Dictionary<string, List<SensorCalibration>>();
|
||||
|
||||
private readonly Dictionary<string, string> _sensorChannelCodeLookup = new Dictionary<string, string>();
|
||||
private Dictionary<string, string> _sensorGroupNameLookup = new Dictionary<string, string>();
|
||||
private Dictionary<string, string> _sensorGroupTypeLookup = new Dictionary<string, string>();
|
||||
private Dictionary<string, string> _groupNameTestObjectLookup = new Dictionary<string, string>();
|
||||
private Dictionary<string, List<string>> _groupNameSensorsLookup = new Dictionary<string, List<string>>();
|
||||
|
||||
private Dictionary<int, int> _oldSensorDatabaseIdToNew = new Dictionary<int, int>();
|
||||
|
||||
private readonly List<ImportError> _errors = new List<ImportError>();
|
||||
//FB 36879 Added parse parameters
|
||||
private ParseParameters _parseParameters = new ParseParameters();
|
||||
|
||||
|
||||
public ImportFileFormat GetImportFileFormat()
|
||||
{
|
||||
var testSetupCount = _testSetups.Count;
|
||||
|
||||
return GetImportFileFormat(testSetupCount);
|
||||
}
|
||||
|
||||
public static ImportFileFormat GetImportFileFormat(int testSetupCount)
|
||||
{
|
||||
if (testSetupCount == 1)
|
||||
{
|
||||
return ImportFileFormat.SingleTestSetup;
|
||||
}
|
||||
|
||||
if (testSetupCount > 1)
|
||||
{
|
||||
return ImportFileFormat.MultipleTestSetup;
|
||||
}
|
||||
|
||||
return ImportFileFormat.NoTestSetup;
|
||||
}
|
||||
|
||||
public void AssignParseParameters(ParseParameters parseParameters)
|
||||
{
|
||||
_parseParameters = parseParameters;
|
||||
}
|
||||
|
||||
public ParseParameters ParseParameters() => _parseParameters;
|
||||
|
||||
public void ClearErrors() => _errors.Clear();
|
||||
public void AddErrors(IEnumerable<ImportError> d) => _errors.AddRange(d);
|
||||
public void AddError(ImportError d) => _errors.Add(d);
|
||||
public IEnumerable<ImportError> Errors() => _errors;
|
||||
//FB 40758
|
||||
/// <summary>
|
||||
/// Specify the type of test setup file, single, multiple, no test setup
|
||||
/// </summary>
|
||||
public ImportFileFormat TestSetupImportFileFormat { get; set; } = ImportFileFormat.NoTestSetup;
|
||||
|
||||
public void AssignOldSensorDatabaseIdToNew(Dictionary<int, int> oldSensorDatabaseIdToNew)
|
||||
{
|
||||
_oldSensorDatabaseIdToNew = new Dictionary<int, int>(oldSensorDatabaseIdToNew);
|
||||
}
|
||||
public void AddOldSensorDatabaseIdToNew(int key, int value)
|
||||
{
|
||||
_oldSensorDatabaseIdToNew[key] = value;
|
||||
}
|
||||
public int OldSensorDatabaseIdToNew(int key)
|
||||
{
|
||||
return _oldSensorDatabaseIdToNew[key];
|
||||
}
|
||||
public Dictionary<int, int> OldSensorDatabaseIdsToNew()
|
||||
{
|
||||
return _oldSensorDatabaseIdToNew;
|
||||
}
|
||||
|
||||
public void AssignGlobalSettings(Dictionary<string, string> settings) => _globalSettings = new Dictionary<string, string>(settings);
|
||||
public void AddGlobalSettings(string key, string value) => _globalSettings[key] = value;
|
||||
public string GlobalSetting(string key) => _globalSettings[key];
|
||||
public Dictionary<string, string> GlobalSettings() => _globalSettings;
|
||||
|
||||
public void AddCustomPhysicalDimensions(IEnumerable<MMEPhysicalDimensions> d) => _physicalDimensions.AddRange(d);
|
||||
public void AddCustomPhysicalDimension(MMEPhysicalDimensions d) => _physicalDimensions.Add(d);
|
||||
public IEnumerable<MMEPhysicalDimensions> PhysicalDimensions() => _physicalDimensions;
|
||||
|
||||
public void AddCustomPositions(IEnumerable<MMEPositions> d) => _positions.AddRange(d);
|
||||
public void AddCustomPosition(MMEPositions d) => _positions.Add(d);
|
||||
public IEnumerable<MMEPositions> CustomPositions() => _positions;
|
||||
|
||||
public void AddCustomFilterClasses(IEnumerable<MMEFilterClasses> d) => _filterClasses.AddRange(d);
|
||||
public void AddCustomFilterClass(MMEFilterClasses d) => _filterClasses.Add(d);
|
||||
public IEnumerable<MMEFilterClasses> CustomFilterClasses() => _filterClasses;
|
||||
|
||||
|
||||
public void AddCustomFineLoc1s(IEnumerable<MMEFineLocations1> d) => _fineLoc1s.AddRange(d);
|
||||
public void AddCustomFineLoc1(MMEFineLocations1 d) => _fineLoc1s.Add(d);
|
||||
public IEnumerable<MMEFineLocations1> CustomFineLoc1s() => _fineLoc1s;
|
||||
|
||||
public void AddCustomFineLoc2s(IEnumerable<MMEFineLocations2> d) => _fineLoc2s.AddRange(d);
|
||||
public void AddCustomFineLoc2(MMEFineLocations2 d) => _fineLoc2s.Add(d);
|
||||
public IEnumerable<MMEFineLocations2> CustomFineLoc2s() => _fineLoc2s;
|
||||
|
||||
public void AddCustomFineLoc3s(IEnumerable<MMEFineLocations3> d) => _fineLoc3s.AddRange(d);
|
||||
public void AddCustomFineLoc3(MMEFineLocations3 d) => _fineLoc3s.Add(d);
|
||||
public IEnumerable<MMEFineLocations3> CustomFineLoc3s() => _fineLoc3s;
|
||||
|
||||
public void AddDirections(IEnumerable<MMEDirections> d) => _directions.AddRange(d);
|
||||
public void AddDirection(MMEDirections d) => _directions.Add(d);
|
||||
public IEnumerable<MMEDirections> Directions() => _directions;
|
||||
|
||||
public void AddCustomMainLocations(IEnumerable<MMETransducerMainLocation> d) => _mainLocations.AddRange(d);
|
||||
public void AddCustomMainLocation(MMETransducerMainLocation d) => _mainLocations.Add(d);
|
||||
public IEnumerable<MMETransducerMainLocation> CustomMainLocations() => _mainLocations;
|
||||
|
||||
public void AddUsers(IEnumerable<User> users) => _users.AddRange(users);
|
||||
public void AddUser(User user) => _users.Add(user);
|
||||
public IEnumerable<User> Users() => _users;
|
||||
|
||||
public void AddSensorModels(IEnumerable<SensorModel> s) => _sensorModels.AddRange(s);
|
||||
public void AddSensorModel(SensorModel s) => _sensorModels.Add(s);
|
||||
public IEnumerable<SensorModel> SensorModels() => _sensorModels;
|
||||
|
||||
|
||||
public void AddCustomChannels(IEnumerable<MMEPossibleChannels> channels) => _customChannels.AddRange(channels);
|
||||
public void AddCustomChannel(MMEPossibleChannels channel) => _customChannels.Add(channel);
|
||||
public IEnumerable<MMEPossibleChannels> CustomChannels() => _customChannels;
|
||||
|
||||
|
||||
public void AddTestObjects(IEnumerable<MMETestObjects> objects) => _testObjects.AddRange(objects);
|
||||
public void AddTestObject(MMETestObjects objects) => _testObjects.Add(objects);
|
||||
public IEnumerable<MMETestObjects> TestObjects() => _testObjects;
|
||||
|
||||
public void AddHardwareList(IEnumerable<DASHardware> hardwareList)
|
||||
{
|
||||
_hardware.AddRange(hardwareList);
|
||||
}
|
||||
public void AddHardware(DASHardware hardware)
|
||||
{
|
||||
_hardware.Add(hardware);
|
||||
}
|
||||
public IEnumerable<DASHardware> Hardware()
|
||||
{
|
||||
return _hardware;
|
||||
}
|
||||
|
||||
public void AddCalibrations(IEnumerable<SensorCalibration> sensorCalibrations)
|
||||
{
|
||||
_calibrations.AddRange(sensorCalibrations);
|
||||
}
|
||||
public void AddCalibration(SensorCalibration sensorCalibration)
|
||||
{
|
||||
_calibrations.Add(sensorCalibration);
|
||||
}
|
||||
public IEnumerable<SensorCalibration> Calibrations()
|
||||
{
|
||||
return _calibrations;
|
||||
}
|
||||
|
||||
public void AddTestSetups(IEnumerable<TestTemplate> testTemplates)
|
||||
{
|
||||
_testSetups.AddRange(testTemplates);
|
||||
}
|
||||
public void AddTestSetup(TestTemplate testTemplate)
|
||||
{
|
||||
_testSetups.Add(testTemplate);
|
||||
}
|
||||
public IEnumerable<TestTemplate> TestSetups()
|
||||
{
|
||||
return _testSetups;
|
||||
}
|
||||
public void ClearTestSetups()
|
||||
{
|
||||
_testSetups.Clear();
|
||||
}
|
||||
|
||||
public void AddGroups(IEnumerable<DataPROWin7.DataModel.TestObject> groups)
|
||||
{
|
||||
_groupList.AddRange(groups);
|
||||
}
|
||||
public void AddGroup(DataPROWin7.DataModel.TestObject group)
|
||||
{
|
||||
_groupList.Add(group);
|
||||
}
|
||||
public IEnumerable<DataPROWin7.DataModel.TestObject> Groups()
|
||||
{
|
||||
return _groupList;
|
||||
}
|
||||
|
||||
public void AddSensors(IEnumerable<SensorData> sensorsData)
|
||||
{
|
||||
_sensors.AddRange(sensorsData);
|
||||
}
|
||||
public void AddSensor(SensorData sensorData)
|
||||
{
|
||||
_sensors.Add(sensorData);
|
||||
}
|
||||
public IEnumerable<SensorData> Sensors()
|
||||
{
|
||||
return _sensors;
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<int, ISensorData> GetSensorLookup()
|
||||
{
|
||||
var lookup = new Dictionary<int, ISensorData>();
|
||||
|
||||
var sensors = Sensors();
|
||||
foreach (var sensor in sensors)
|
||||
{
|
||||
if (lookup.ContainsKey(sensor.DatabaseId))
|
||||
{
|
||||
//I would prefer this in the APIlog, but it doesn't seem to be accessible here
|
||||
//and I didn't think it work of putting a delegate around
|
||||
System.Diagnostics.Trace.WriteLine($"sensor {sensor.SerialNumber} [{sensor.DatabaseId}] is a duplicate of {lookup[sensor.DatabaseId].SerialNumber}");
|
||||
}
|
||||
else { lookup[sensor.DatabaseId] = sensor; }
|
||||
}
|
||||
|
||||
return lookup;
|
||||
}
|
||||
public void ClearSensors()
|
||||
{
|
||||
_sensors.Clear();
|
||||
}
|
||||
|
||||
public void AddGroupTemplates(IEnumerable<DataPROWin7.DataModel.TestObjectTemplate> templates)
|
||||
{
|
||||
_groupTemplates.AddRange(templates);
|
||||
}
|
||||
public void AddGroupTemplate(DataPROWin7.DataModel.TestObjectTemplate template)
|
||||
{
|
||||
_groupTemplates.Add(template);
|
||||
}
|
||||
public IEnumerable<DataPROWin7.DataModel.TestObjectTemplate> GroupTemplates()
|
||||
{
|
||||
return _groupTemplates;
|
||||
}
|
||||
|
||||
|
||||
public void AddCustomerDetailsList(IEnumerable<ISO.CustomerDetails> details)
|
||||
{
|
||||
_customerDetails.AddRange(details);
|
||||
}
|
||||
public void AddCustomerDetails(ISO.CustomerDetails details)
|
||||
{
|
||||
_customerDetails.Add(details);
|
||||
}
|
||||
public IEnumerable<ISO.CustomerDetails> CustomerDetails()
|
||||
{
|
||||
return _customerDetails;
|
||||
}
|
||||
|
||||
|
||||
public void AddLabDetailsList(IEnumerable<ISO.LabratoryDetails> details)
|
||||
{
|
||||
_labDetails.AddRange(details);
|
||||
}
|
||||
public void AddLabDetails(ISO.LabratoryDetails details)
|
||||
{
|
||||
_labDetails.Add(details);
|
||||
}
|
||||
public IEnumerable<ISO.LabratoryDetails> LabDetails()
|
||||
{
|
||||
return _labDetails;
|
||||
}
|
||||
|
||||
public void AddTestEngineerDetailsList(IEnumerable<ISO.TestEngineerDetails> details)
|
||||
{
|
||||
_testEngineerDetails.AddRange(details);
|
||||
}
|
||||
public void AddTestEngineerDetails(ISO.TestEngineerDetails details)
|
||||
{
|
||||
_testEngineerDetails.Add(details);
|
||||
}
|
||||
public IEnumerable<ISO.TestEngineerDetails> TestEngineerDetails()
|
||||
{
|
||||
return _testEngineerDetails;
|
||||
}
|
||||
|
||||
public void AddStaticGroups(IEnumerable<Interface.Groups.GroupList.IGroup> groups)
|
||||
{
|
||||
_iGroups.AddRange(groups);
|
||||
}
|
||||
public void AddStaticGroup(Interface.Groups.GroupList.IGroup group)
|
||||
{
|
||||
_iGroups.Add(group);
|
||||
}
|
||||
public IEnumerable<Interface.Groups.GroupList.IGroup> StaticGroups()
|
||||
{
|
||||
return _iGroups;
|
||||
}
|
||||
|
||||
public void AssignSensorLookup(Dictionary<string, SensorData> sensorLookup)
|
||||
{
|
||||
_sensorLookup = new Dictionary<string, SensorData>(sensorLookup);
|
||||
}
|
||||
public void AddSensorLookup(string serial, SensorData sensorData)
|
||||
{
|
||||
_sensorLookup[serial] = sensorData;
|
||||
}
|
||||
public SensorData SensorLookup(string serial)
|
||||
{
|
||||
return _sensorLookup[serial];
|
||||
}
|
||||
public Dictionary<string, SensorData> SensorsLookup()
|
||||
{
|
||||
return _sensorLookup;
|
||||
}
|
||||
|
||||
public void AssignCalibrationLookup(Dictionary<string, List<SensorCalibration>> calibrationLookup)
|
||||
{
|
||||
_calibrationLookup = new Dictionary<string, List<SensorCalibration>>(calibrationLookup);
|
||||
}
|
||||
public void AddCalibrationLookup(string serial, List<SensorCalibration> sensorCalibrations)
|
||||
{
|
||||
_calibrationLookup[serial] = sensorCalibrations;
|
||||
}
|
||||
public List<SensorCalibration> CalibrationLookup(string serial)
|
||||
{
|
||||
return _calibrationLookup[serial];
|
||||
}
|
||||
public Dictionary<string, List<SensorCalibration>> CalibrationsLookup()
|
||||
{
|
||||
return _calibrationLookup;
|
||||
}
|
||||
|
||||
public void AssignSensorModelLookup(Dictionary<string, List<SensorCalibration>> calibrationLookup)
|
||||
{
|
||||
_sensorModelLookup = new Dictionary<string, SensorModel>();
|
||||
}
|
||||
public void AddSensorModelLookup(string key, SensorModel sensorModel)
|
||||
{
|
||||
_sensorModelLookup[key] = sensorModel;
|
||||
}
|
||||
public SensorModel SensorModelLookup(string key)
|
||||
{
|
||||
return _sensorModelLookup[key];
|
||||
}
|
||||
public Dictionary<string, SensorModel> SensorModelsLookup()
|
||||
{
|
||||
return _sensorModelLookup;
|
||||
}
|
||||
|
||||
public void AssignSensorGroupNameLookup(Dictionary<string, string> sensorGroupNameLookup)
|
||||
{
|
||||
_sensorGroupNameLookup = new Dictionary<string, string>(sensorGroupNameLookup);
|
||||
}
|
||||
public void AddSensorGroupNameLookup(string serial, string name)
|
||||
{
|
||||
_sensorGroupNameLookup[serial] = name;
|
||||
}
|
||||
public string SensorGroupNameLookup(string serial)
|
||||
{
|
||||
return _sensorGroupNameLookup[serial];
|
||||
}
|
||||
public Dictionary<string, string> SensorGroupNamesLookup()
|
||||
{
|
||||
return _sensorGroupNameLookup;
|
||||
}
|
||||
public void AssignSensorGroupTypeLookup(Dictionary<string, string> sensorGroupTypeLookup)
|
||||
{
|
||||
_sensorGroupTypeLookup = new Dictionary<string, string>(sensorGroupTypeLookup);
|
||||
}
|
||||
public void AddSensorGroupTypeLookup(string serial, string name)
|
||||
{
|
||||
_sensorGroupTypeLookup[serial] = name;
|
||||
}
|
||||
public string SensorGroupTypeLookup(string serial)
|
||||
{
|
||||
return _sensorGroupTypeLookup[serial];
|
||||
}
|
||||
public Dictionary<string, string> SensorGroupTypesLookup()
|
||||
{
|
||||
return _sensorGroupTypeLookup;
|
||||
}
|
||||
|
||||
|
||||
public void AssignGroupNameTestObjectLookup(Dictionary<string, string> groupNameTestObjectLookup)
|
||||
{
|
||||
_groupNameTestObjectLookup = new Dictionary<string, string>(groupNameTestObjectLookup);
|
||||
}
|
||||
public void AddGroupNameTestObjectLookup(string serial, string name)
|
||||
{
|
||||
_groupNameTestObjectLookup[serial] = name;
|
||||
}
|
||||
public string GroupNameTestObjectLookup(string serial)
|
||||
{
|
||||
return _groupNameTestObjectLookup[serial];
|
||||
}
|
||||
public Dictionary<string, string> GroupNameTestObjectsLookup()
|
||||
{
|
||||
return _groupNameTestObjectLookup;
|
||||
}
|
||||
|
||||
|
||||
public void AssignGroupNameSensorsLookup(Dictionary<string, List<string>> groupNameSensorsLookup)
|
||||
{
|
||||
_groupNameSensorsLookup = new Dictionary<string, List<string>>(groupNameSensorsLookup);
|
||||
}
|
||||
public void AddGroupNameSensorsLookup(string name, List<string> sensors)
|
||||
{
|
||||
_groupNameSensorsLookup[name] = sensors;
|
||||
}
|
||||
public List<string> GroupNameSensorsLookup(string name)
|
||||
{
|
||||
return _groupNameSensorsLookup[name];
|
||||
}
|
||||
public Dictionary<string, List<string>> GroupNameSensorsListLookup()
|
||||
{
|
||||
return _groupNameSensorsLookup;
|
||||
}
|
||||
|
||||
public void AddSensorChannelCodeLookup(string settingName, string serial)
|
||||
{
|
||||
_sensorChannelCodeLookup[settingName] = serial;
|
||||
}
|
||||
public string SensorChannelCodeLookup(string settingName)
|
||||
{
|
||||
return _sensorChannelCodeLookup[settingName];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{C1BC06F4-8657-4892-BC4D-1064DA01C4C7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>DTS.Common.Import</RootNamespace>
|
||||
<AssemblyName>DTS.Common.Import</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CalibrationImport.cs" />
|
||||
<Compile Include="ImportError.cs" />
|
||||
<Compile Include="Parsers\CSV\CSVFile.cs" />
|
||||
<Compile Include="DatabaseLocks\LockImportGroups.cs" />
|
||||
<Compile Include="DatabaseLocks\LockImportSensors.cs" />
|
||||
<Compile Include="DatabaseLocks\LockImportTestSetups.cs" />
|
||||
<Compile Include="Parsers\EQX\EQXGroupImport.cs" />
|
||||
<Compile Include="Factories\CSVSensorParserFactory.cs" />
|
||||
<Compile Include="Factories\CSVTestParserFactory.cs" />
|
||||
<Compile Include="Factories\DatabaseLocksFactory.cs" />
|
||||
<Compile Include="Factories\SaveVariantFactory.cs" />
|
||||
<Compile Include="Factories\XmlParserFactory.cs" />
|
||||
<Compile Include="ImportOptions\EqxImportOptions.cs" />
|
||||
<Compile Include="Interfaces\ILockImport.cs" />
|
||||
<Compile Include="Interfaces\IParseCSVSensor.cs" />
|
||||
<Compile Include="Interfaces\IParseCSVTest.cs" />
|
||||
<Compile Include="Parsers\CSV\AbstractCSVParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version0CSVSensorParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version0CSVTestParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version2CSVSensorParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version3CSVSensorParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version4CSVSensorParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version5CSVTestParser.cs" />
|
||||
<Compile Include="Parsers\CSV\Version6CSVTestParser.cs" />
|
||||
<Compile Include="Parsers\CSV\DTSCSVSensorsParser.cs" />
|
||||
<Compile Include="Parsers\CSV\DTSCSVTestSetupParser.cs" />
|
||||
<Compile Include="Interfaces\ICalibrationImport.cs" />
|
||||
<Compile Include="ImportOptions\CsvImportOptions.cs" />
|
||||
<Compile Include="Interfaces\IGroupImport.cs" />
|
||||
<Compile Include="ImportNotification.cs" />
|
||||
<Compile Include="Interfaces\IParseVariant.cs" />
|
||||
<Compile Include="ParseProcessor.cs" />
|
||||
<Compile Include="Parsers\DTSXMLParseImport.cs" />
|
||||
<Compile Include="Parsers\CSV\CSVGroupImport.cs" />
|
||||
<Compile Include="ImportObject.cs" />
|
||||
<Compile Include="Interfaces\IParseImport.cs" />
|
||||
<Compile Include="Interfaces\IPersistImport.cs" />
|
||||
<Compile Include="Parsers\DefaultParseImport.cs" />
|
||||
<Compile Include="Parsers\EQX\EQXSensorsParser.cs" />
|
||||
<Compile Include="Parsers\EQX\EQXTestSetupParser.cs" />
|
||||
<Compile Include="Parsers\ParseVariantBase.cs" />
|
||||
<Compile Include="Persist\PersistCalculator.cs" />
|
||||
<Compile Include="Persist\SaveCheckoutTestSetup.cs" />
|
||||
<Compile Include="Persist\SaveCustomChannels.cs" />
|
||||
<Compile Include="Persist\SaveGlobalSettings.cs" />
|
||||
<Compile Include="Persist\SaveGroups.cs" />
|
||||
<Compile Include="Persist\SaveGroupTemplates.cs" />
|
||||
<Compile Include="Persist\SaveHardware.cs" />
|
||||
<Compile Include="Persist\SaveLabDetails.cs" />
|
||||
<Compile Include="Persist\SaveSensor.cs" />
|
||||
<Compile Include="Persist\SaveSensorModels.cs" />
|
||||
<Compile Include="Persist\SaveServer.cs" />
|
||||
<Compile Include="Persist\SaveTestEngineerDetails.cs" />
|
||||
<Compile Include="Persist\SaveTestSetup.cs" />
|
||||
<Compile Include="Persist\SaveTestSetupHelper.cs" />
|
||||
<Compile Include="Persist\SaveUsers.cs" />
|
||||
<Compile Include="Persist\SaveVariantBase.cs" />
|
||||
<Compile Include="Persist\SaveCustomerDetails.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="GroupHelper.cs" />
|
||||
<Compile Include="TsetSetupImportSensorInfo.cs" />
|
||||
<Compile Include="XMLParseProcessor.cs" />
|
||||
<Compile Include="XML\XMLParseCustomerDetails.cs" />
|
||||
<Compile Include="XML\XMLParseDASList.cs" />
|
||||
<Compile Include="XML\XMLParseGlobalSettings.cs" />
|
||||
<Compile Include="XML\XMLParseGroupTemplates.cs" />
|
||||
<Compile Include="XML\XMLParseLabDetails.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomChannels.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomDirections.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomFilterClasses.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomFineLoc1s.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomFineLoc2s.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomFineLoc3s.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomMainLocations.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomPhysicalDimensions.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomPositions.cs" />
|
||||
<Compile Include="XML\XMLParseMMECustomTestObjects.cs" />
|
||||
<Compile Include="XML\XMLParseSensorModels.cs" />
|
||||
<Compile Include="XML\XMLParseTestEngineerDetails.cs" />
|
||||
<Compile Include="XML\XMLParseUsers.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseDASList.cs" />
|
||||
<Compile Include="XML\XMLParseGroups.cs" />
|
||||
<Compile Include="XML\XMLParseSensors.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseCalibrations.cs" />
|
||||
<Compile Include="XML\XMLParseBase.cs" />
|
||||
<Compile Include="XML\XMLParseCalibrations.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseGroups.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseGroupTemplates.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseSensors.cs" />
|
||||
<Compile Include="XML\XMLParseTestSetups.cs" />
|
||||
<Compile Include="XML\XMLPre20ParseTestSetups.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\DataPRO\EquipmentExchange\EquipmentExchange.csproj">
|
||||
<Project>{2513797d-ec82-48d5-969e-6b3b5e6002e3}</Project>
|
||||
<Name>EquipmentExchange</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\DataPRO\SensorDB\SensorDB.csproj">
|
||||
<Project>{444ef10c-046e-47ad-a9a5-17318d488723}</Project>
|
||||
<Name>SensorDB</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\DataPRO\Users\Users.csproj">
|
||||
<Project>{be8d217d-6da9-4bca-b62a-a82325b33979}</Project>
|
||||
<Name>Users</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.DAS.Concepts\DTS.Common.DAS.Concepts.csproj">
|
||||
<Project>{AE3987F7-C4C6-40FB-A353-1A2DADEF7A9A}</Project>
|
||||
<Name>DTS.Common.DAS.Concepts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.DataModel\DTS.Common.DataModel.csproj">
|
||||
<Project>{2a2f03a9-bf85-4360-a06a-cf3016d2633b}</Project>
|
||||
<Name>DTS.Common.DataModel</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.ISO\DTS.Common.ISO.csproj">
|
||||
<Project>{27d0c63b-9095-42da-95fd-f64444c80558}</Project>
|
||||
<Name>DTS.Common.ISO</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.Serialization\DTS.Common.Serialization.csproj">
|
||||
<Project>{0679d014-59c2-4327-b288-0e3bd1374710}</Project>
|
||||
<Name>DTS.Common.Serialization</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.SettingsDB\DTS.Common.Settings.csproj">
|
||||
<Project>{61017104-d8ee-41d1-b9ca-dad863ff78b2}</Project>
|
||||
<Name>DTS.Common.Settings</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.SharedResource\DTS.Common.SharedResource.csproj">
|
||||
<Project>{c01e723f-86e2-403a-864c-9f56bdb60b8d}</Project>
|
||||
<Name>DTS.Common.SharedResource</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.Storage\DTS.Common.Storage.csproj">
|
||||
<Project>{e3be457c-0ac7-4a9c-bc81-eafeb3217878}</Project>
|
||||
<Name>DTS.Common.Storage</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common.Utilities\DTS.Common.Utilities.csproj">
|
||||
<Project>{D6DA1B74-C711-43C2-91B1-1908A8D04DBF}</Project>
|
||||
<Name>DTS.Common.Utilities</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\DTS.Common\DTS.Common.csproj">
|
||||
<Project>{f7a0804f-61a4-40ae-83d0-f1137622b592}</Project>
|
||||
<Name>DTS.Common</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,33 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseMMECustomMainLocations : XMLParseBase
|
||||
{
|
||||
public XMLParseMMECustomMainLocations(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AddCustomMainLocations(ParseCustomMainLocations(_root));
|
||||
}
|
||||
|
||||
public IEnumerable<ISO.MMETransducerMainLocation> ParseCustomMainLocations(XmlElement root)
|
||||
{
|
||||
List<ISO.MMETransducerMainLocation> list = new List<ISO.MMETransducerMainLocation>();
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return list; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
list.Add(ISO.MMETransducerMainLocation.ReadXML(node as XmlElement));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public interface IGroupImport
|
||||
{
|
||||
ParseParameters ParseParameters { get; set; }
|
||||
Tuple<TestTemplate, List<IGroup>> CreateGroups(List<SensorData> sensors, Dictionary<string, List<TsetSetupImportSensorInfo>> groupSensorLookup, TestTemplate testTemplate, bool createDynamicGroups, List<IGroup> staticGroups, Action<double> setProgress);
|
||||
Dictionary<string, List<TsetSetupImportSensorInfo>> GetGroupSensorLookup(List<SensorData> sensors, Dictionary<string, string> sensorGroupNameLookup, Dictionary<string, List<string>> groupNameSensorListLookup);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Import.Persist;
|
||||
using DTS.Slice.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DTS.Common.Import.Factories
|
||||
{
|
||||
public static class SaveVariantFactory
|
||||
{
|
||||
//FB 36854 Added cancel action
|
||||
public static List<IPersistImport> CreateVariants(ImportObject importObject, ImportNotification importNotification, User user, Func<bool> isCanceled, bool showCheckoutButton)
|
||||
{
|
||||
List<IPersistImport> saveHandlers = new List<IPersistImport>();
|
||||
|
||||
IPersistCalculator persistCalculator = new PersistCalculator();
|
||||
|
||||
if (importObject.CustomerDetails().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.CustomerDetails().Count());
|
||||
var saveCustomerDetails = new SaveCustomerDetails(importObject, persistCalculator, importNotification, isCanceled);
|
||||
saveHandlers.Add(saveCustomerDetails);
|
||||
}
|
||||
|
||||
if (importObject.TestEngineerDetails().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.TestEngineerDetails().Count());
|
||||
var saveTestEngineerDetails = new SaveTestEngineerDetails(importObject, persistCalculator, importNotification, isCanceled);
|
||||
saveHandlers.Add(saveTestEngineerDetails);
|
||||
}
|
||||
|
||||
if (importObject.LabDetails().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.LabDetails().Count());
|
||||
var saveLabDetails = new SaveLabDetails(importObject, persistCalculator, importNotification, isCanceled);
|
||||
saveHandlers.Add(saveLabDetails);
|
||||
}
|
||||
|
||||
if (importObject.SensorModels().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.SensorModels().Count());
|
||||
var sensorModels = new SaveSensorModels(importObject, persistCalculator, importNotification, isCanceled);
|
||||
saveHandlers.Add(sensorModels);
|
||||
}
|
||||
|
||||
if (importObject.Sensors().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.Sensors().Count());
|
||||
persistCalculator.AddToTotal(importObject.Calibrations().Count());
|
||||
|
||||
if (importObject.SourceFormat == Enums.ImportFormats.DTS_CSV)
|
||||
{
|
||||
var saveCsvSourceSensor = new SaveCsvSourceSensor(importObject, persistCalculator, importNotification, isCanceled);
|
||||
saveCsvSourceSensor.CurrentUser = user;
|
||||
saveHandlers.Add(saveCsvSourceSensor);
|
||||
}
|
||||
else
|
||||
{
|
||||
var saveNonCsvSourceSensor = new SaveNonCsvSourceSensor(importObject, persistCalculator, importNotification, isCanceled);
|
||||
saveNonCsvSourceSensor.CurrentUser = user;
|
||||
saveHandlers.Add(saveNonCsvSourceSensor);
|
||||
}
|
||||
}
|
||||
|
||||
if (importObject.Users().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.Users().Count());
|
||||
var saveUsers = new SaveUsers(importObject, persistCalculator, importNotification, isCanceled);
|
||||
saveHandlers.Add(saveUsers);
|
||||
}
|
||||
|
||||
if (importObject.GlobalSettings().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.GlobalSettings().Count);
|
||||
var saveGlobalSettings = new SaveGlobalSettings(importObject, persistCalculator, importNotification, isCanceled);
|
||||
saveHandlers.Add(saveGlobalSettings);
|
||||
}
|
||||
|
||||
SaveCustomChannels saveCustomChannels = new SaveCustomChannels(importObject, persistCalculator, importNotification, isCanceled);
|
||||
|
||||
|
||||
var saveHardware = new SaveHardware(importObject, persistCalculator, importNotification, isCanceled);
|
||||
|
||||
if (importObject.Hardware().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.Hardware().Count());
|
||||
persistCalculator.AddToTotal(importObject.Hardware().Sum(h => h?.Channels.Length ?? 0));
|
||||
|
||||
saveHandlers.Add(saveHardware);
|
||||
}
|
||||
|
||||
if (importObject.GroupTemplates().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.GroupTemplates().Count());
|
||||
SaveGroupTemplates saveGroupTemplates = new SaveGroupTemplates(importObject, persistCalculator, importNotification, isCanceled);
|
||||
saveHandlers.Add(saveGroupTemplates);
|
||||
}
|
||||
|
||||
SaveGroups saveGroups = new SaveGroups(importObject, persistCalculator, importNotification, saveHardware, isCanceled);
|
||||
|
||||
if (importObject.Groups().Any() || importObject.StaticGroups().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.Groups().Count());
|
||||
persistCalculator.AddToTotal(importObject.StaticGroups().Count());
|
||||
|
||||
saveHandlers.Add(saveGroups);
|
||||
}
|
||||
|
||||
if (importObject.TestSetups().Any())
|
||||
{
|
||||
persistCalculator.AddToTotal(importObject.TestSetups().Count());
|
||||
SaveTestSetup saveTestSetup = new SaveTestSetup(importObject, persistCalculator, importNotification, saveCustomChannels, saveHardware, saveGroups, isCanceled);
|
||||
if (showCheckoutButton)
|
||||
{
|
||||
//FB 38039 For now the checkout setting specifies if we are in GM parse mode.
|
||||
//We concat Run Test at the end of file too
|
||||
//We might use manufacturer to set this name later
|
||||
saveTestSetup.TestSetupName = string.Concat(importObject.TestSetups()?.FirstOrDefault()?.Name, Serialization.RDF.File.SUFFIX_RUNTEST);
|
||||
}
|
||||
saveTestSetup.CurrentUser = user;
|
||||
saveHandlers.Add(saveTestSetup);
|
||||
if (showCheckoutButton)
|
||||
{
|
||||
//FB 38039 create checkout test setup
|
||||
SaveCheckoutTestSetup saveTestSetupCheckout = new SaveCheckoutTestSetup(importObject, persistCalculator, importNotification,
|
||||
saveCustomChannels, saveHardware, saveGroups, isCanceled, string.Concat(importObject.TestSetups()?.FirstOrDefault()?.Name, Serialization.RDF.File.SUFFIX_CHECKOUT));
|
||||
saveTestSetupCheckout.CurrentUser = user;
|
||||
saveHandlers.Add(saveTestSetupCheckout);
|
||||
}
|
||||
}
|
||||
|
||||
return saveHandlers;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using DTS.SensorDB;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using static DTS.Common.Enums.Sensors.SensorConstants;
|
||||
|
||||
namespace DTS.Common.Import.Parsers.CSV
|
||||
{
|
||||
public class Version2CSVSensorParser : AbstractCSVParser
|
||||
{
|
||||
public override int Version => 2;
|
||||
public override void ParseVersion(CSVImportTags.Tags field, string sVal, ParseParameters pp)
|
||||
{
|
||||
var sd = (SensorData)pp.SensorData;
|
||||
var sc = (SensorCalibration)pp.SensorCal;
|
||||
#region and another very long switch statement
|
||||
switch (field)
|
||||
{
|
||||
case CSVImportTags.Tags.AdditionalInitialOffsets:
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(sVal))
|
||||
{
|
||||
var additionalInitialOffsets = new InitialOffsets(sVal); //merge with original (initial) initial offset
|
||||
var numAdditionalInitialOffsets = additionalInitialOffsets.Offsets.Length;
|
||||
var mergedInitialOffsets = new InitialOffset[numAdditionalInitialOffsets + 1];
|
||||
mergedInitialOffsets[0] = sc.InitialOffsets.Offsets[0];
|
||||
var counter = 0;
|
||||
foreach (var additionalInitialOffset in additionalInitialOffsets.Offsets)
|
||||
{
|
||||
counter++;
|
||||
mergedInitialOffsets[counter] = additionalInitialOffset;
|
||||
}
|
||||
sc.InitialOffsets.Offsets = mergedInitialOffsets;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.AdditionalLinearSensitivity:
|
||||
if (!string.IsNullOrWhiteSpace(sVal))
|
||||
{
|
||||
//This is a non-linear sensor with additional linear attributes
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var d))
|
||||
{
|
||||
//13810 Sensor ID and sensitivity are degraded to scientific notation when editing
|
||||
if (sVal.ToLower().Contains("e"))
|
||||
{
|
||||
pp.Errors.Add(string.Format(StringResources.InvalidSensitivity,
|
||||
sd.SerialNumber, sVal));
|
||||
return;
|
||||
}
|
||||
|
||||
pp.Sensitivity = d;
|
||||
}
|
||||
else { pp.Errors.Add(string.Format(StringResources.InvalidSensitivity, sd.SerialNumber, sVal)); }
|
||||
|
||||
//Add a linear calibration record if it doesn't already exist
|
||||
sc = _calibrationImport.AddLinearCalRecordIfNeeded(sc, pp.SavedIsProportional, pp.SavedRemoveOffset);
|
||||
|
||||
sc.Records.Records[1].Sensitivity = pp.Sensitivity;
|
||||
if (sc.IsProportional) { sc.Records.Records[1].Excitation = sd.SupportedExcitation.First(); }
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.AdditionalLinearZeroMethod:
|
||||
if (!string.IsNullOrWhiteSpace(sVal))
|
||||
{
|
||||
{
|
||||
//Add a linear ZeroMethods record if it doesn't already exist
|
||||
sc = _calibrationImport.AddLinearZeroMethodIfNeeded(sc, _zeroMethodOptions.ZeroMethodType, _zeroMethodOptions.ZeroMethodStart, _zeroMethodOptions.ZeroMethodEnd);
|
||||
|
||||
if (Enum.TryParse(sVal, out ZeroMethodType zmt))
|
||||
{
|
||||
sc.ZeroMethods.Methods.Last().Method = zmt;
|
||||
pp.ZeroType = zmt;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.AdditionalLinearZeroMethodEnd:
|
||||
if (!string.IsNullOrWhiteSpace(sVal))
|
||||
{
|
||||
{
|
||||
//Add a linear ZeroMethods record if it doesn't already exist
|
||||
sc = _calibrationImport.AddLinearZeroMethodIfNeeded(sc, _zeroMethodOptions.ZeroMethodType, _zeroMethodOptions.ZeroMethodStart, _zeroMethodOptions.ZeroMethodEnd);
|
||||
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var zeroMethodEnd))
|
||||
{
|
||||
sc.ZeroMethods.Methods.Last().End = zeroMethodEnd;
|
||||
pp.ZeroEnd = zeroMethodEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.AdditionalLinearZeroMethodStart:
|
||||
if (!string.IsNullOrWhiteSpace(sVal))
|
||||
{
|
||||
{
|
||||
//Add a linear ZeroMethods record if it doesn't already exist
|
||||
sc = _calibrationImport.AddLinearZeroMethodIfNeeded(sc, _zeroMethodOptions.ZeroMethodType, _zeroMethodOptions.ZeroMethodStart, _zeroMethodOptions.ZeroMethodEnd);
|
||||
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var zeroMethodStart))
|
||||
{
|
||||
sc.ZeroMethods.Methods.Last().Start = zeroMethodStart;
|
||||
pp.ZeroStart = zeroMethodStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.AxisNumber:
|
||||
if (short.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var axisNumber))
|
||||
{
|
||||
sd.AxisNumber = axisNumber;
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.BridgeLegMode:
|
||||
BridgeLeg bl;
|
||||
if (Enum.TryParse(sVal, out bl)) { sd.BridgeLegMode = bl; }
|
||||
break;
|
||||
case CSVImportTags.Tags.BridgeType:
|
||||
if (Enum.TryParse(sVal, out BridgeType bt))
|
||||
{
|
||||
sd.Bridge = bt;
|
||||
}
|
||||
else
|
||||
{
|
||||
//FB 41817 if not parsable but contains these values use them
|
||||
if (sVal.ToLower() == "squib setting")
|
||||
{
|
||||
sd.Bridge = BridgeType.SQUIB;
|
||||
}
|
||||
else if (sVal.ToLower() == "digital input setting")
|
||||
{
|
||||
sd.Bridge = BridgeType.DigitalInput;
|
||||
}
|
||||
else if (sVal.ToLower() == "digital output setting")
|
||||
{
|
||||
sd.Bridge = BridgeType.TOMDigital;
|
||||
}
|
||||
else if (sVal.ToLower() == "full bridge")
|
||||
{
|
||||
sd.Bridge = BridgeType.FullBridge;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.CalInterval:
|
||||
{
|
||||
if (int.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var temp)) { sd.CalInterval = temp; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.CouplingMode:
|
||||
{
|
||||
if (Enum.TryParse(sVal, out CouplingModes cm)) { sd.CouplingMode = cm; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.Created:
|
||||
{
|
||||
if (DateTime.TryParse(sVal, pp.ImportCulture, DateTimeStyles.AssumeLocal, out var dt)) { sd.Created = dt; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.DelayMS:
|
||||
{
|
||||
if (double.TryParse(sVal, out var d)) { sd.DelayMS = d; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.DigitalOutputDelayMS:
|
||||
{
|
||||
if (double.TryParse(sVal, out var d)) { sd.DigitalOutputDelayMS = d; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.DigitalInputMode:
|
||||
{
|
||||
if (Enum.TryParse(sVal, out DigitalInputModes im)) { sd.InputMode = im; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.DigitalOutputMode:
|
||||
{
|
||||
if (Enum.TryParse(sVal, out DigitalOutputModes om)) { sd.DigitalOutputMode = om; }
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CSVImportTags.Tags.DigitalScaleMultiplier:
|
||||
if (!string.IsNullOrEmpty(sVal))
|
||||
{
|
||||
sd.ScaleMultiplier.FromDbSerializeString(sVal);
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.Direction:
|
||||
{
|
||||
if (sd.Direction == "?" && sd.Direction != sVal)
|
||||
{
|
||||
sd.Direction = sVal;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.DisplayUnits:
|
||||
{
|
||||
//Determine if we know about this display unit
|
||||
var calEU = MeasurementUnitList.GetMeasurementUnit(sc.Records.Records.First().EngineeringUnits);
|
||||
try
|
||||
{
|
||||
var unitConversion = calEU.GetScalerConversion(sVal);
|
||||
|
||||
// Convert all the EU values to be represented in DisplayUnits
|
||||
sd.RangeHigh *= unitConversion;
|
||||
sd.RangeMedium *= unitConversion;
|
||||
sd.RangeLow *= unitConversion;
|
||||
sd.Capacity *= unitConversion;
|
||||
sc.InitialOffsets.Offsets.First().EU *= unitConversion;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex is InvalidCastException)
|
||||
{
|
||||
sd.DisplayUnit = sc.Records.Records.First().EngineeringUnits;
|
||||
// The units don't match what we are aware of. Lets move on.
|
||||
break;
|
||||
}
|
||||
_importNotification.ReportErrors(new List<string>() { ex.Message });
|
||||
}
|
||||
|
||||
sd.DisplayUnit = sVal; break;
|
||||
}
|
||||
|
||||
case CSVImportTags.Tags.DurationMS:
|
||||
{
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var d)) { sd.DurationMS = d; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.DigitalOutputDurationMS:
|
||||
{
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var d)) { sd.DigitalOutputDurationMS = d; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.FiveVoltExcSensitivity:
|
||||
{
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var d))
|
||||
{
|
||||
pp.SensorCal = _calibrationImport.CheckForExcitationCalibration(sc, d, ExcitationVoltageOptions.ExcitationVoltageOption.Volt5, sd.DisplayUnit);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.InitialOffset: sc.InitialOffsets = new InitialOffsets(sVal); break;
|
||||
case CSVImportTags.Tags.LimitDuration: sd.LimitDuration = sVal.ToLower() == "yes"; break;
|
||||
case CSVImportTags.Tags.NonLinear: sc.NonLinear = sVal.ToLower() == "yes"; break;
|
||||
case CSVImportTags.Tags.NonLinearCalibration:
|
||||
{
|
||||
sc.Records.Records[0].Poly.FromSerializeString(sVal);
|
||||
if (sc.Records.Records[0].Poly.IsValid()) { sc.NonLinear = true; }
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.NumberOfAxes:
|
||||
{
|
||||
if (short.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var temp)) { sd.NumberOfAxes = temp; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.PhysicalDimension:
|
||||
{
|
||||
//if the physical dimension was already set by the ISOCode, don't reset it
|
||||
if (sd.PhysicalDimension == "??" && sd.PhysicalDimension != sVal)
|
||||
{
|
||||
sd.PhysicalDimension = sVal;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.Polarity: sd.Polarity = sVal; break;
|
||||
|
||||
case CSVImportTags.Tags.RangeHigh:
|
||||
{
|
||||
pp.ImportContainedSensorRanges = true;
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var d)) { sd.RangeHigh = d; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.RangeLow:
|
||||
{
|
||||
pp.ImportContainedSensorRanges = true;
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var d)) { sd.RangeLow = d; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.RangeMedium:
|
||||
{
|
||||
pp.ImportContainedSensorRanges = true;
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var d)) { sd.RangeMedium = d; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.SquibFireMode:
|
||||
{
|
||||
if (Enum.TryParse(sVal, out SquibFireMode sfm)) { sd.SquibFireMode = sfm; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.SquibMeasurementType:
|
||||
{
|
||||
if (Enum.TryParse(sVal, out SquibMeasurementType smt)) { sd.SquibMeasurementType = smt; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.SquibOutputCurrent:
|
||||
{
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var d)) { sd.SquibOutputCurrent = d; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.SupportedExcitation: sd.SetSupportedExcitationFromString(sVal); break;
|
||||
|
||||
case CSVImportTags.Tags.TenVoltExcSensitivity:
|
||||
{
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var d))
|
||||
{
|
||||
pp.SensorCal = _calibrationImport.CheckForExcitationCalibration(sc, d, ExcitationVoltageOptions.ExcitationVoltageOption.Volt10, sd.DisplayUnit);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.TimesUsed:
|
||||
{
|
||||
if (int.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var temp)) { sd.TimesUsed = temp; }
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.TwoVoltExcSensitivity:
|
||||
{
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var d))
|
||||
{
|
||||
pp.SensorCal = _calibrationImport.CheckForExcitationCalibration(sc, d, ExcitationVoltageOptions.ExcitationVoltageOption.Volt2, sd.DisplayUnit);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.Unipolar: sd.UniPolar = sVal.ToLower() == "yes"; break;
|
||||
|
||||
case CSVImportTags.Tags.Unknown: break;
|
||||
|
||||
case CSVImportTags.Tags.ZeroMethod:
|
||||
{
|
||||
if (Enum.TryParse(sVal, out ZeroMethodType zmt))
|
||||
{
|
||||
sc.ZeroMethods.Methods.First().Method = zmt;
|
||||
pp.ZeroType = zmt;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.ZeroMethodEnd:
|
||||
{
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var zeroMethodEnd))
|
||||
{
|
||||
sc.ZeroMethods.Methods.First().End = zeroMethodEnd;
|
||||
pp.ZeroEnd = zeroMethodEnd;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.ZeroMethodStart:
|
||||
{
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var zeroMethodStart))
|
||||
{
|
||||
sc.ZeroMethods.Methods.First().Start = zeroMethodStart;
|
||||
pp.ZeroStart = zeroMethodStart;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.AtCapacity:
|
||||
{
|
||||
sc.Records.Records.First().AtCapacity = sVal.ToLower() == "yes";
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.CapacityOutputIsBasedOn:
|
||||
{
|
||||
if (double.TryParse(sVal, NumberStyles.Any, pp.ImportCulture, out var temp))
|
||||
{
|
||||
sc.Records.Records.First().CapacityOutputIsBasedOn = temp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.SensitivityUnits:
|
||||
{
|
||||
if (!string.IsNullOrEmpty(sVal))
|
||||
{
|
||||
sc.Records.Records.First().SensitivityUnits = SensUnitStringConverter.ConvertFromString(sVal);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CSVImportTags.Tags.CheckOffset: { sd.CheckOffset = sVal.ToLower() == "yes"; } break;
|
||||
case CSVImportTags.Tags.Broken: { sd.Broken = sVal.ToLower() == "yes"; } break;
|
||||
case CSVImportTags.Tags.DoNotUse: { sd.DoNotUse = sVal.ToLower() == "yes"; } break;
|
||||
case CSVImportTags.Tags.ISOChannelName: { sd.ISOChannelName = sVal; } break;
|
||||
case CSVImportTags.Tags.UserCode: { sd.UserCode = sVal; } break;
|
||||
case CSVImportTags.Tags.UserChannelName: { sd.UserChannelName = sVal; } break;
|
||||
default: throw new NotSupportedException("Unknown field: " + field);
|
||||
}
|
||||
#endregion and another very long switch statement
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Events;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.ISO;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Policy;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseDASList : XMLParseBase
|
||||
{
|
||||
public XMLParseDASList(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_dasIdMapping.Clear();
|
||||
}
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public List<DASHardware> ParseDASList(XmlElement root)
|
||||
{
|
||||
List<DASHardware> dasList = new List<DASHardware>();
|
||||
var invalidDAS = new List<string>();
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return dasList; }
|
||||
if (node is XmlElement)
|
||||
{
|
||||
var isoHardware = DASHardware.ReadXML(node as XmlElement);
|
||||
if (Enum.IsDefined(typeof(DTS.Common.Enums.Hardware.HardwareTypes), isoHardware.DASType))
|
||||
{
|
||||
dasList.Add(new DASHardware(isoHardware));
|
||||
}
|
||||
else
|
||||
{
|
||||
invalidDAS.Add(isoHardware.SerialNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (invalidDAS.Any())
|
||||
{
|
||||
//???
|
||||
}
|
||||
return dasList;
|
||||
}
|
||||
|
||||
private XmlElement ConvertDASList(List<DASHardware> dasList)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.DASList.ToString());
|
||||
var count = -2; //Start the normalization at -2, since channels have a DASId of -1 if unassigned (FB 13544)
|
||||
foreach (var h in dasList)
|
||||
{
|
||||
_dasIdMapping[h.DASId] = count;
|
||||
h.SetDASId(count);
|
||||
count--;
|
||||
|
||||
_writer.Flush();
|
||||
h.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
|
||||
return GetXmlElement();
|
||||
}
|
||||
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingHardware });
|
||||
var dasList = ParseDASList(_root);
|
||||
var newRoot = ConvertDASList(dasList);
|
||||
importObject.AddHardwareList(ParseDASList(newRoot));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseMMECustomFineLoc2s : XMLParseBase
|
||||
{
|
||||
public XMLParseMMECustomFineLoc2s(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
importObject.AddCustomFineLoc2s(ParseCustomFineLoc2s(_root));
|
||||
}
|
||||
|
||||
private IEnumerable<ISO.MMEFineLocations2> ParseCustomFineLoc2s(XmlElement root)
|
||||
{
|
||||
List<ISO.MMEFineLocations2> list = new List<ISO.MMEFineLocations2>();
|
||||
|
||||
foreach (var child in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return list; }
|
||||
if (child is XmlElement)
|
||||
{
|
||||
list.Add(ISO.MMEFineLocations2.ReadXML(child as XmlElement));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using CsvHelper;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public static class CsvUtil
|
||||
{
|
||||
public static CsvReader CreateCsvReader(string filename)
|
||||
{
|
||||
var reader = new StreamReader(filename);
|
||||
var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture);
|
||||
return csvReader;
|
||||
}
|
||||
/// <summary>
|
||||
/// Read fields from csv reader
|
||||
/// </summary>
|
||||
/// <param name="csvReader">an instance of csv readere</param>
|
||||
/// <param name="readNextLine">determine if read next line and then get the fields or just get fields from the existing state</param>
|
||||
/// <returns></returns>
|
||||
public static List<string> ReadFields(CsvReader csvReader, bool readNextLine = true)
|
||||
{
|
||||
List<string> tokens = new List<string>();
|
||||
if (readNextLine)
|
||||
{
|
||||
csvReader.Read();
|
||||
}
|
||||
for (int i = 0; i < csvReader.ColumnCount; i++)
|
||||
{
|
||||
tokens.Add(csvReader.GetField(i)?.Trim());
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace DTS.Common.Import.Parsers.CSV
|
||||
{
|
||||
public class Version4CSVSensorParser : AbstractCSVParser
|
||||
{
|
||||
public override int Version => 4;
|
||||
public override void ParseVersion(CSVImportTags.Tags field, string sVal, ParseParameters pp)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case CSVImportTags.Tags.DASSerialNumber:
|
||||
pp.SensorDASSerialNumber[pp.SensorData.SerialNumber] = sVal;
|
||||
break;
|
||||
case CSVImportTags.Tags.DASChannelIndex:
|
||||
{
|
||||
if (int.TryParse(sVal, out var iTemp))
|
||||
{
|
||||
pp.SensorDASChannelIndex[pp.SensorData.SerialNumber] = iTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.StreamProfile:
|
||||
if (Enum.TryParse(sVal, out UDPStreamProfile profile))
|
||||
{
|
||||
pp.SensorData.StreamOutUDPProfile = profile;
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.UDPAddress:
|
||||
pp.SensorData.StreamInUDPAddress = sVal;
|
||||
pp.SensorData.StreamOutUDPAddress = sVal;
|
||||
break;
|
||||
case CSVImportTags.Tags.TimeChannelId:
|
||||
{
|
||||
if (ushort.TryParse(sVal, out var uTemp))
|
||||
{
|
||||
pp.SensorData.StreamOutUDPTimeChannelId = uTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.DataChannelId:
|
||||
{
|
||||
if (ushort.TryParse(sVal, out var uTemp))
|
||||
{
|
||||
pp.SensorData.StreamOutUDPDataChannelId = uTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.TmNSConfig:
|
||||
pp.SensorData.StreamOutUDPTmNSConfig = sVal;
|
||||
break;
|
||||
case CSVImportTags.Tags.IRIGTimeDataPacketIntervalMS:
|
||||
{
|
||||
if (ushort.TryParse(sVal, out var uTemp))
|
||||
{
|
||||
pp.SensorData.StreamOutIRIGTimeDataPacketIntervalMs = uTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.TMATSIntervalMS:
|
||||
{
|
||||
if (ushort.TryParse(sVal, out var uTemp))
|
||||
{
|
||||
pp.SensorData.StreamOutTMATSIntervalMs = uTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.BaudRate:
|
||||
{
|
||||
if (uint.TryParse(sVal, out var iTemp))
|
||||
{
|
||||
pp.SensorData.UartBaudRate = iTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.DataBits:
|
||||
{
|
||||
if (uint.TryParse(sVal, out var iTemp))
|
||||
{
|
||||
pp.SensorData.UartDataBits = iTemp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.StopBits:
|
||||
{
|
||||
if (Enum.TryParse(sVal, out StopBits stopBits))
|
||||
{
|
||||
pp.SensorData.UartStopBits = stopBits;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.Parity:
|
||||
{
|
||||
if (Enum.TryParse(sVal, out Parity parity))
|
||||
{
|
||||
pp.SensorData.UartParity = parity;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.DataFormat:
|
||||
{
|
||||
if (Enum.TryParse(sVal, out UartDataFormat dataFormat))
|
||||
{
|
||||
pp.SensorData.UartDataFormat = dataFormat;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSVImportTags.Tags.TestUserCode:
|
||||
pp.SensorUserCode[pp.SensorData.SerialNumber] = sVal;
|
||||
break;
|
||||
case CSVImportTags.Tags.TestUserChannelName:
|
||||
pp.SensorUserChannelName[pp.SensorData.SerialNumber] = sVal;
|
||||
break;
|
||||
case CSVImportTags.Tags.TestIsoCode:
|
||||
pp.SensorISOCode[pp.SensorData.SerialNumber] = sVal;
|
||||
break;
|
||||
case CSVImportTags.Tags.TestIsoChannelName:
|
||||
pp.SensorISOChannelName[pp.SensorData.SerialNumber] = sVal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public enum ImportSeverityError
|
||||
{
|
||||
Critical,
|
||||
Error,
|
||||
Warning,
|
||||
Info
|
||||
}
|
||||
public class ImportError
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public ImportSeverityError Severity { get; set; }
|
||||
public bool ContinueImportOnError { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.SensorDB;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLPre20ParseSensors : XMLParseBase
|
||||
{
|
||||
private readonly XMLParseSensors _xmlParseSensors;
|
||||
public XMLPre20ParseSensors(XmlElement root, double importedVersion, XMLParseSensors xmlParseSensors, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_xmlParseSensors = xmlParseSensors;
|
||||
}
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
var sensors = _xmlParseSensors.ParseSensors(_root);
|
||||
var newRoot = MigrateSensors(sensors);
|
||||
importObject.AddSensors(_xmlParseSensors.ParseSensors(newRoot));
|
||||
}
|
||||
|
||||
public XmlElement MigrateSensors(IEnumerable<SensorData> sensors)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.Sensors.ToString());
|
||||
var count = -1;
|
||||
foreach (var sd in sensors)
|
||||
{
|
||||
sd.DatabaseId = count;
|
||||
count--;
|
||||
_writer.Flush();
|
||||
sd.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using DataPROWin7.DataModel;
|
||||
using DTS.Common.Import.Enums;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveCustomerDetails : SaveVariantBase
|
||||
{
|
||||
bool invalidCustomerDetails = false;
|
||||
public SaveCustomerDetails(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
_importNotification.SetStatus.Invoke(new ImportStatus { ExtraStatus = ImportExtraStatus.ReadingLabDetails, PossibleStatus = PossibleStatus.Importing });
|
||||
foreach (var c in _importObject.CustomerDetails())
|
||||
{
|
||||
if (IsCancelled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (c.IsInvalidBlank())
|
||||
{
|
||||
invalidCustomerDetails = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CustomerDetailsList.AddCustomer(new CustomerDetails(c));
|
||||
}
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using DTS.Common.Classes.Sensors;
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Enums.Sensors;
|
||||
using DTS.Common.Interface.Sensors;
|
||||
using DTS.SensorDB;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.Common.Import
|
||||
{
|
||||
public class CalibrationImport : ICalibrationImport
|
||||
{
|
||||
public SensorCalibration CheckForExcitationCalibration(SensorCalibration sc, double sensitivity, ExcitationVoltageOptions.ExcitationVoltageOption excitation, string EU)
|
||||
{
|
||||
//we may have already handled this, so check
|
||||
if (sc.Records.Records[0].Excitation == excitation)
|
||||
{
|
||||
return sc;
|
||||
}
|
||||
var records = new List<ICalibrationRecord>(sc.Records.Records);
|
||||
var r = new CalibrationRecord
|
||||
{
|
||||
AtCapacity = false,
|
||||
EngineeringUnits = EU,
|
||||
Excitation = excitation,
|
||||
Sensitivity = sensitivity,
|
||||
CapacityOutputIsBasedOn = 1.000
|
||||
};
|
||||
records.Add(r);
|
||||
sc.Records.Records = records.ToArray();
|
||||
return sc;
|
||||
}
|
||||
public SensorCalibration AddLinearCalRecordIfNeeded(SensorCalibration sc, bool savedIsProportional, bool savedRemoveOffset)
|
||||
{
|
||||
if (sc.Records.Records.Length == 1)
|
||||
{
|
||||
//Since sc.Records.Records is an array and not a List, make a list of two records - the existing
|
||||
//non-linear and a new linear - and replace the existing array of length 1 with a new array of length 2.
|
||||
var records = new List<ICalibrationRecord>();
|
||||
|
||||
//Add the existing non-linear
|
||||
records.AddRange(sc.Records.Records);
|
||||
|
||||
//Add a new record for linear
|
||||
var newSc = new SensorCalibration();
|
||||
newSc.Records.Records[0].Poly.MarkValid(false);
|
||||
records.Add(newSc.Records.Records[0]);
|
||||
|
||||
//Replace the existing single record with two
|
||||
sc.Records.Records = records.ToArray();
|
||||
|
||||
//Since there is both a linear and non-linear calibration, IsProportional and RemoveOffset
|
||||
//should apply to the linear, and were set to False when the sensor was set to NonLinear
|
||||
sc.IsProportional = savedIsProportional;
|
||||
sc.RemoveOffset = savedRemoveOffset;
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
public SensorCalibration AddLinearZeroMethodIfNeeded(SensorCalibration sc, ZeroMethodType zeroMethodType, double zeroMethodStart, double zeroMethodEnd)
|
||||
{
|
||||
if (sc.ZeroMethods.Methods.Length == 1)
|
||||
{
|
||||
//Since sc.ZeroMethods.Methods is an array and not a List, make a list of two records - the existing
|
||||
//non-linear and a new linear - and replace the existing array of length 1 with a new array of length 2.
|
||||
var methods = new List<ZeroMethod>();
|
||||
|
||||
//Add the existing non-linear
|
||||
methods.AddRange(sc.ZeroMethods.Methods);
|
||||
|
||||
//Add a new record for linear
|
||||
var newZm = new ZeroMethod(zeroMethodType, zeroMethodStart, zeroMethodEnd);
|
||||
methods.Add(newZm);
|
||||
|
||||
//Replace the existing single record with two
|
||||
sc.ZeroMethods.Methods = methods.ToArray();
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.Common.Import.Persist
|
||||
{
|
||||
public class SaveGroupTemplates : SaveVariantBase
|
||||
{
|
||||
public SaveGroupTemplates(ImportObject importObject, IPersistCalculator persistCalculator, IImportNotification importNotification, Func<bool> isCancelled = null) :
|
||||
base(importObject, persistCalculator, importNotification, isCancelled)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
foreach (var t in _importObject.GroupTemplates())
|
||||
{
|
||||
if (IsCancelled()) { return; }
|
||||
_persistCalculator.AddDone();
|
||||
_importNotification.SetProgress(_persistCalculator.ProgressValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface.GroupTemplate;
|
||||
using DTS.Common.SharedResource.Strings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLPre20ParseGroupTemplates : XMLParseBase
|
||||
{
|
||||
private XMLParseGroupTemplates _xmlParseGroupTemplates;
|
||||
public XMLPre20ParseGroupTemplates(XmlElement root, double importedVersion,
|
||||
XMLParseGroupTemplates xmlParseGroupTemplates, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_xmlParseGroupTemplates = xmlParseGroupTemplates;
|
||||
}
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
var groupTemplates = _xmlParseGroupTemplates.ParseGroupTemplates(ref importObject, _root);
|
||||
importObject.AddGroupTemplates(groupTemplates);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
using DTS.Common.Enums.DBExport;
|
||||
using DTS.Common.Import.Interfaces;
|
||||
using DTS.Common.Interface.Groups.GroupList;
|
||||
using DTS.Common.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Policy;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace DTS.Common.Import.XML
|
||||
{
|
||||
public class XMLParseGroups : XMLParseBase
|
||||
{
|
||||
|
||||
public XMLParseGroups(XmlElement root, double importedVersion, Func<bool> isCancelled = null) : base(root, importedVersion, isCancelled)
|
||||
{
|
||||
_groupIdMapping.Clear();
|
||||
}
|
||||
public IImportNotification ImportNotification { get; set; }
|
||||
public override void Parse(ref ImportObject importObject)
|
||||
{
|
||||
ImportNotification?.SetStatus(new ImportStatus { PossibleStatus = Enums.PossibleStatus.Reading, ExtraStatus = Enums.ImportExtraStatus.ReadingGroups });
|
||||
var staticGroups = ParseGroups(_root, ref importObject);
|
||||
if (!staticGroups.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var newRoot = ConvertGroups(staticGroups);
|
||||
if (newRoot == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
staticGroups = ParseGroups(newRoot, ref importObject);
|
||||
importObject.AddStaticGroups(staticGroups);
|
||||
|
||||
}
|
||||
private XmlElement ConvertGroups(List<IGroup> staticGroups)
|
||||
{
|
||||
_writer.WriteStartElement(TopLevelFields.Groups.ToString());
|
||||
var count = -2; //Start the normalization at -2, to be consistent with channel mapping(?)
|
||||
foreach (var g in staticGroups)
|
||||
{
|
||||
if (_importedVersion >= FileUtils.DataPRO21XmlVersion)
|
||||
{
|
||||
_groupIdMapping[g.Id.ToString()] = count;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Must be an export from 2.0 or earlier
|
||||
_groupIdMapping[g.Name] = count;
|
||||
}
|
||||
g.Id = count;
|
||||
count--;
|
||||
foreach (var channel in g.GroupChannelList)
|
||||
{
|
||||
if (_dasIdMapping.ContainsKey(channel.DASId))
|
||||
{
|
||||
channel.DASId = _dasIdMapping[channel.DASId];
|
||||
}
|
||||
if (_sensorIdMapping.ContainsKey(channel.SensorId))
|
||||
{
|
||||
channel.SensorId = _sensorIdMapping[channel.SensorId];
|
||||
}
|
||||
else
|
||||
{
|
||||
//FB 14308 - Don't fail Group import if it was
|
||||
//exported with a deleted sensor.
|
||||
channel.SensorId = 0;
|
||||
}
|
||||
}
|
||||
_writer.Flush();
|
||||
g.WriteXML(ref _writer);
|
||||
_writer.Flush();
|
||||
}
|
||||
_writer.WriteEndElement();
|
||||
return GetXmlElement();
|
||||
|
||||
}
|
||||
|
||||
public List<IGroup> ParseGroups(XmlElement root, ref ImportObject importObject)
|
||||
{
|
||||
List<IGroup> staticGroups = new List<IGroup>();
|
||||
var importedHardware = new Dictionary<string, DataPROWin7.DataModel.DASHardware>();
|
||||
foreach (var h in importObject.Hardware())
|
||||
{
|
||||
importedHardware[h.GetHardware().GetId()] = h;
|
||||
}
|
||||
foreach (var node in root.ChildNodes)
|
||||
{
|
||||
if (IsCancelled()) { return staticGroups; }
|
||||
if (!(node is XmlElement)) continue;
|
||||
|
||||
IGroup groupInstance = GroupHelper.CreateEmptyGroup();
|
||||
if (groupInstance != null)
|
||||
{
|
||||
var channelLookup = new Dictionary<long, Interface.Channels.IGroupChannel>();
|
||||
var iSensors = new List<Interface.Sensors.ISensorData>();
|
||||
foreach (var sensor in importObject.Sensors())
|
||||
{
|
||||
iSensors.Add(sensor);
|
||||
}
|
||||
var g = groupInstance.ReadXML(node as XmlElement, channelLookup, iSensors);
|
||||
if (!string.IsNullOrWhiteSpace(g.Name))
|
||||
{
|
||||
var groupCopy = GroupHelper.CreateEmptyGroup();
|
||||
groupCopy.Name = g.Name;
|
||||
groupCopy.DisplayName = g.Name;
|
||||
groupCopy.LastModified = g.LastModified;
|
||||
groupCopy.Embedded = g.Embedded;
|
||||
groupCopy.IncludedHardwareStringList = g.IncludedHardwareStringList;
|
||||
groupCopy.Id = g.Id;
|
||||
groupCopy.Tags = g.Tags;
|
||||
staticGroups.Add(groupCopy);
|
||||
|
||||
foreach (var channel in channelLookup.Select(p => p.Value))
|
||||
{
|
||||
channel.Group = groupCopy;
|
||||
groupCopy.GroupChannelList.Add(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return staticGroups;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user