This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1 @@
12

View File

@@ -0,0 +1 @@
12

View File

@@ -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 });
}
}
}

View File

@@ -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);
}
}

View File

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

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}
}

View File

@@ -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")]

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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));
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -0,0 +1,8 @@
namespace DTS.Common.Import.Interfaces
{
public interface IParseVariant
{
string FileName { get; set; }
void Parse(ref ImportObject importObject);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
});
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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 });
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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));
}
}
}

View File

@@ -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 });
}
}
}

View File

@@ -0,0 +1,7 @@
namespace DTS.Common.Import
{
public interface IPersistImport
{
void Save();
}
}

View File

@@ -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; }
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace DTS.Common.Import
{
public interface IParseImport
{
ImportObject Parse(IEnumerable<string> importFiles);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}
}
}

View File

@@ -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();
}
}
}
}
}

View File

@@ -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;
}
}
}

View File

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

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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];
}
}
}

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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));
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More