Files
DP44/DataPRO/Modules/DatabaseImporter/DatabaseImport/Classes/TestTemplate/TestTemplate.cs
2026-04-17 14:55:32 -04:00

1683 lines
74 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.ComponentModel;
using System.Data.SqlClient;
using System.Windows;
namespace DatabaseImport
{
public class TestTemplate : TagAwareBase, IComparable<TestTemplate>, ICachedContainer
{
/// <summary>
/// returns true whenever the test template is a quick test setup, false otherwise
/// </summary>
public bool QuickSensorCheck { get; set; }
// #region var and const
public const string NON_ISO_INTERNAL_GROUP_NAME = "[NONE]";
private const int MAX_REALTIME_CHANNELS = 6;
private const int MAX_ERRORS_TO_DISPLAY = 5;
internal List<CalculatedValueClass> CalculatedChannels = new List<CalculatedValueClass>();
private string _errorMessage = "";
/// <summary>
/// dictionary of harware overrides for the test
/// key is hardware id
/// if present, then value is whether the hardware is included or removed from the test.
/// </summary>
internal Dictionary<string, HardwareInclusionInstruction> HardwareOverrides = new Dictionary<string, HardwareInclusionInstruction>();
/// <summary>
/// cache of sensors for the test setup
/// this keeps us from having to lookup sensors and apply changes every time we need to use them
/// </summary>
public Dictionary<string, Dictionary<string, Dictionary<string, SensorData>>> SensorLookup = new Dictionary<string, Dictionary<string, Dictionary<string, SensorData>>>();
public string TestSetupXml { get; set; }
private readonly Dictionary<string, DASSettings> _dasSettings = new Dictionary<string, DASSettings>();
public DASSettings[] DASSettings
{
get => _dasSettings.Count < 1 ? new DASSettings[0] : _dasSettings.Values.ToArray();
set
{
_dasSettings.Clear();
foreach (var setting in value) { _dasSettings[setting.DASSerialNumber] = setting; }
}
}
/// <summary>
/// whether to upload data after data collection is completed
/// this lets you separate out the time consumptive network data tasks from the ones you want to keep fast (export/view)
/// </summary>
private bool _uploadData;
public bool UploadData
{
get => _uploadData;
set => SetProperty(ref _uploadData, value, TestTemplateTags.UploadData.ToString());
}
/// <summary>
/// whether to upload data after data collection is completed
/// this lets you separate out the time consumptive network data tasks from the ones you want to keep fast (export/view)
/// </summary>
private bool _uploadExportsOnly;
public bool UploadExportsOnly
{
get => _uploadExportsOnly;
set => SetProperty(ref _uploadExportsOnly, value, TestTemplateTags.UploadExportsOnly.ToString());
}
/// <summary>
/// folder to upload to
/// </summary>
private string _uploadFolder = "";
public string UploadFolder
{
get => _uploadFolder;
set => SetProperty(ref _uploadFolder, value, TestTemplateTags.UploadFolder.ToString());
}
/// <summary>
/// whether all units in the test share a common line
/// this should be set to false if DAS in the test don't share a common line
/// the default is true
/// if units share a common status line and there are multiple units in the test, then each unit will monitor the status line
/// if false or there's only one unit, the status line should not be monitored
/// </summary>
private bool _bCommonLine;
public bool CommonLine
{
get => _bCommonLine;
set => SetProperty(ref _bCommonLine, value, TestTemplateTags.CommonLine.ToString());
}
/// <summary>
/// true if the test objects and other fields have already been loaded from the database, false otherwise
/// </summary>
internal bool _bIsLoaded;
public bool IsLoaded => _bIsLoaded;
/// <summary>
/// when true the expectation is that any unit that can have a battery will have a battery, and the user should be warned
/// whenever a unit that should have a battery does not have an acceptable battery voltage
/// </summary>
private bool _warnOnFailedBattery;
public bool WarnOnFailedBattery
{
get => _warnOnFailedBattery;
set => SetProperty(ref _warnOnFailedBattery, value, TestTemplateTags.WarnOnFailedBattery.ToString());
}
public string CompletionErrorMessage => _testTemplateLite.CompletionErrorMessage;
/// <summary>
/// returns whether the test setup is dirty or not (whether the is complete is calculated already or not)
/// </summary>
private bool _bIsDirty = true;
public bool IsDirty
{
get => _bIsDirty;
set => _bIsDirty = value;
}
private List<TestGraph> _testGraphs = new List<TestGraph>();
private TestTemplateLite _testTemplateLite;
public string Name
{
get => _testTemplateLite.Name;
set => _testTemplateLite.Name = value;
}
private bool _bAllowMissingSensors;
public bool AllowMissingSensors
{
get => _bAllowMissingSensors;
set => SetProperty(ref _bAllowMissingSensors, value, TestTemplateTags.AllowMissingSensors.ToString());
}
private bool _bAllowSensorIdToBlankChannel;
public bool AllowSensorIdToBlankChannel
{
get => _bAllowSensorIdToBlankChannel;
set => SetProperty(ref _bAllowSensorIdToBlankChannel, value, TestTemplateTags.AllowSensorIdToBlankChannel.ToString());
}
private bool _bAutomaticProgression;
public bool AutomaticProgression
{
get => _bAutomaticProgression;
set => SetProperty(ref _bAutomaticProgression, value, TestTemplateTags.AutomaticProgression.ToString());
}
private int _automaticProgressionDelayMs;
public int AutomaticProgressionDelayMS
{
get => _automaticProgressionDelayMs;
set => SetProperty(ref _automaticProgressionDelayMs, value,
TestTemplateTags.AutomaticProgressionDelayMS.ToString());
}
private bool _invertTriggerCompletion;
public bool InvertTriggerCompletion
{
get => _invertTriggerCompletion;
set => SetProperty(ref _invertTriggerCompletion, value,
TestTemplateTags.InvertTriggerCompletion.ToString());
}
private bool _triggerCheckStep;
public bool TriggerCheckStep
{
get => _triggerCheckStep;
set => SetProperty(ref _triggerCheckStep, value, TestTemplateTags.TriggerCheckStep.ToString());
}
private int _postTestDiagnosticsLevel;
public bool PostTestDiagnosticsLevel
{
get => _postTestDiagnosticsLevel != 0;
set
{
if (value) { SetProperty(ref _postTestDiagnosticsLevel, 255, TestTemplateTags.PostTestDiagnostics.ToString()); }
else { SetProperty(ref _postTestDiagnosticsLevel, 0, TestTemplateTags.PostTestDiagnostics.ToString()); }
}
}
private bool _triggerCheckRealtime;
public bool TriggerCheckRealtime
{
get => _triggerCheckRealtime;
set => SetProperty(ref _triggerCheckRealtime, value, TestTemplateTags.TriggerCheckRealtime.ToString());
}
private bool _invertStartRecordCompletion;
public bool InvertStartRecordCompletion
{
get => _invertStartRecordCompletion;
set => SetProperty(ref _invertStartRecordCompletion, value,
TestTemplateTags.InvertStartRecordCompletion.ToString());
}
private bool _bViewDiagnostics = true;
public bool ViewDiagnostics
{
get => _bViewDiagnostics;
set => SetProperty(ref _bViewDiagnostics, value, TestTemplateTags.ViewDiagnostics.ToString());
}
private bool _bVerify = true;
public bool VerifyChannels
{
get => _bVerify;
set => SetProperty(ref _bVerify, value, TestTemplateTags.VerifyChannels.ToString());
}
private bool _bAutoVerifyChannels = true;
public bool AutoVerifyChannels
{
get => _bAutoVerifyChannels;
set => SetProperty(ref _bAutoVerifyChannels, value, TestTemplateTags.AutoVerifyProgress.ToString());
}
private double _autoVerifyDelay = 2D;
public double AutoVerifyDelaySeconds
{
get => _autoVerifyDelay;
set => SetProperty(ref _autoVerifyDelay, value, TestTemplateTags.AutoVerifyDelaySeconds.ToString());
}
private bool _bUseCustomerDetails;
public bool UseCustomerDetails
{
get => _bUseCustomerDetails;
set => SetProperty(ref _bUseCustomerDetails, value, TestTemplateTags.UseCustomerDetails.ToString());
}
private bool _bUseTestEngineerDetails;
public bool UseTestEngineerDetails
{
get => _bUseTestEngineerDetails;
set => SetProperty(ref _bUseTestEngineerDetails, value, TestTemplateTags.UseTestEngineerDetails.ToString());
}
private bool _bTurnOffExcitation = true;
public bool TurnOffExcitation
{
get => _bTurnOffExcitation;
set => SetProperty(ref _bTurnOffExcitation, value, TestTemplateTags.TurnOffExcitation.ToString());
}
private bool _bUseLabratoryDetails;
public bool UseLabratoryDetails
{
get => _bUseLabratoryDetails;
set => SetProperty(ref _bUseLabratoryDetails, value, TestTemplateTags.UseLabratoryDetails.ToString());
}
private bool _localOnly;
public bool LocalOnly
{
get => _localOnly;
set => SetProperty(ref _localOnly, value, TestTemplateTags.LocalOnly.ToString());
}
public DateTime LastModified
{
get => _testTemplateLite.LastModified;
set
{
_testTemplateLite.LastModified = value;
OnPropertyChanged(TestTemplateTags.LastModified.ToString());
}
}
public string LastModifiedBy
{
get => _testTemplateLite.LastModifiedBy;
set
{
_testTemplateLite.LastModifiedBy = value;
OnPropertyChanged(TestTemplateTags.LastMmodifiedBy.ToString());
}
}
public string Description
{
get => _testTemplateLite.Description;
set
{
_testTemplateLite.Description = value;
OnPropertyChanged(TestTemplateTags.Description.ToString());
}
}
private double _samplesPerSecond;
public double SamplesPerSecond
{
get => _samplesPerSecond;
set
{
SetProperty(ref _samplesPerSecond, value, TestTemplateTags.SamplesPerSecond.ToString());
OnPropertyChanged(TestTemplateTags.SampleRateText.ToString());
}
}
public double PreTriggerSeconds
{
get => _testTemplateLite.PreTriggerSeconds;
set
{
_testTemplateLite.PreTriggerSeconds = value;
foreach (var roi in RegionsOfInterest)
{
roi.PreTrigger = PreTriggerSeconds * -1D;
}
OnPropertyChanged(TestTemplateTags.PreTriggerSeconds.ToString());
}
}
public double PostTriggerSeconds
{
get => _testTemplateLite.PostTriggerSeconds;
set
{
_testTemplateLite.PostTriggerSeconds = value;
foreach (var roi in RegionsOfInterest)
{
roi.PostTrigger = PostTriggerSeconds;
}
OnPropertyChanged(TestTemplateTags.PostTriggerSeconds.ToString());
}
}
private string _isfFile = "";
public string ISFFile
{
get => _isfFile;
set => SetProperty(ref _isfFile, value, TestTemplateTags.ISFFile.ToString());
}
private bool _doAutoArm;
public bool DoAutoArm
{
get => _doAutoArm;
set => SetProperty(ref _doAutoArm, value, TestTemplateTags.DoAutoArm.ToString());
}
/// <summary>
/// CheckoutMode means a non destructive data collection
/// squib fires will only occur internally
/// </summary>
private bool _checkoutMode;
public bool CheckoutMode
{
get => _checkoutMode;
set => SetProperty(ref _checkoutMode, value, TestTemplateTags.CheckoutMode.ToString());
}
/// <summary>
/// QuitTestWithoutWarning flag will suppress warnings on exit
/// see: 7509 add option to Quit Test Without Warning
/// </summary>
private bool _quitTestWithoutWarning;
public bool QuitTestWithoutWarning
{
get => _quitTestWithoutWarning;
set => SetProperty(ref _quitTestWithoutWarning, value, TestTemplateTags.QuitTestWithoutWarning.ToString());
}
/// <summary>
/// SuppressMissingSensorsWarning flag will suppress missing sensors warnings
/// see: 8877 Suppress modal warning in checkout mode for missing sensors.
/// </summary>
private bool _suppressMissingSensorsWarning;
public bool SuppressMissingSensorsWarning
{
get => _suppressMissingSensorsWarning;
set => SetProperty(ref _suppressMissingSensorsWarning, value, TestTemplateTags.SuppressMissingSensorsWarning.ToString());
}
/// <summary>
/// suppress warnings on exit
/// see: 7642 add two test setup option to suppress "not all channels have been viewed" warnings in both real-time and viewer.
/// </summary>
private bool _notAllChannelsRealTime;
public bool NotAllChannelsRealTime
{
get => _notAllChannelsRealTime;
set => SetProperty(ref _notAllChannelsRealTime, value, TestTemplateTags.NotAllChannelsRealTime.ToString());
}
/// <summary>
/// suppress warnings on exit
/// see: 7642 add two test setup option to suppress "not all channels have been viewed" warnings in both real-time and viewer.
/// </summary>
private bool _notAllChannelsViewer;
public bool NotAllChannelsViewer
{
get => _notAllChannelsViewer;
set => SetProperty(ref _notAllChannelsViewer, value, TestTemplateTags.NotAllChannelsViewer.ToString());
}
public RecordingModes RecordingMode
{
get => _testTemplateLite.RecordingMode;
set
{
if (value != _testTemplateLite.RecordingMode)
{
_testTemplateLite.RecordingMode = value;
OnPropertyChanged(TestTemplateTags.RecordingMode.ToString());
OnPropertyChanged(TestTemplateTags.RecordingModeText.ToString());
}
}
}
private bool _bStrictDiagnostics;
public bool StrictDiagnostics
{
get => _bStrictDiagnostics;
set => SetProperty(ref _bStrictDiagnostics, value, TestTemplateTags.StrictDiagnostics.ToString());
}
public TestTestObject[] TestObjectsWithChannels
{
get
{
var list = new List<TestTestObject>(_testObjects);
for (var i = list.Count - 1; i >= 0; i--)
{
var isoTestObject = list[i].GetISOTestObject();
if (0 == isoTestObject.AllChannels.Length) { list.RemoveAt(i); }
}
return list.ToArray();
}
}
public List<TestObject> TestObjectsAndAddedGroupsList = new List<TestObject>();
// public TestObject[] TestObjectsAndAddedGroups => TestObjectsAndAddedGroupsList.ToArray();
private List<TestTestObject> _testObjects = new List<TestTestObject>();
public TestTestObject[] TestObjects
{
get => _testObjects.ToArray();
}
private List<TestTestObject> _addedGroups = new List<TestTestObject>();
public TestTestObject[] AddedGroups
{
get => _addedGroups.ToArray();
set
{
//MarkIsCompleteUnchecked(); Removed to fix FB 10241 with the assumption that simply Setting AddedGroups should not cause a database write.
SetProperty(ref _addedGroups, new List<TestTestObject>(value), TestTemplateTags.SysBuiltTestObjectTypes.ToString());
OnPropertyChanged(TestTemplateTags.AllTestObjects.ToString());//check this
OnPropertyChanged("TestObjectsAndAddedGroups");
OnPropertyChanged(TestTemplateTags.TestObjectsAndAddedGroups.ToString());
}
}
private bool _bRequireUserConfirmationOnErrors;
public bool RequireUserConfirmationOnErrors
{
get => _bRequireUserConfirmationOnErrors;
set => SetProperty(ref _bRequireUserConfirmationOnErrors, value, TestTemplateTags.RequireUserConfirmationOnErrors.ToString());
}
private bool _roiDownload;
public bool DoROIDownload
{
get => _roiDownload;
set
{
SetProperty(ref _roiDownload, value, TestTemplateTags.DoROIDownload.ToString());
OnPropertyChanged(TestTemplateTags.ROIButtonVisibility.ToString());
}
}
private bool _roiDownloadView;
public bool ViewROIDownload
{
get => _roiDownloadView;
set
{
SetProperty(ref _roiDownloadView, value, TestTemplateTags.ViewROIDownload.ToString());
OnPropertyChanged(TestTemplateTags.ViewROIDownloadButtonVisibility.ToString());
}
}
private bool _downloadAll;
public bool DownloadAll
{
get => _downloadAll;
set
{
SetProperty(ref _downloadAll, value, TestTemplateTags.DownloadAll.ToString());
OnPropertyChanged(TestTemplateTags.DownloadAllButtonVisibility.ToString());
}
}
private bool _viewRealtime;
public bool ViewRealtime
{
get => 0 != GetNumberOfRealtimeSupportedChannels() && _viewRealtime;
set
{
SetProperty(ref _viewRealtime, value, TestTemplateTags.ViewRealtime.ToString());
OnPropertyChanged(TestTemplateTags.ViewRealtime.ToString());
}
}
private BindingList<RegionOfInterest> _regionsOfInterest = new BindingList<RegionOfInterest>();
public BindingList<RegionOfInterest> RegionsOfInterest
{
get => _regionsOfInterest;
set
{
if (null != value)
{
_regionsOfInterest.ListChanged -= _roi_ListChanged;
foreach (var roi in value)
{
roi.PreTrigger = PreTriggerSeconds * -1D;
roi.PostTrigger = PostTriggerSeconds;
}
SetProperty(ref _regionsOfInterest, value, TestTemplateTags.RegionsOfInterest.ToString());
_regionsOfInterest.ListChanged += _roi_ListChanged;
}
}
}
private double _roiStart;
public double ROIStart
{
get => _roiStart;
set => SetProperty(ref _roiStart, value, TestTemplateTags.ROIStart.ToString());
}
private double _roiEnd;
public double ROIEnd
{
get => _roiEnd;
set => SetProperty(ref _roiEnd, value, TestTemplateTags.ROIEnd.ToString());
}
private bool _viewDownloadAll;
public bool ViewDownloadAll
{
get => _viewDownloadAll;
set
{
SetProperty(ref _viewDownloadAll, value, TestTemplateTags.ViewDownloadAll.ToString());
OnPropertyChanged(TestTemplateTags.ViewDownloadAllButtonVisibility.ToString());
}
}
private bool _viewExport;
public bool ViewExport
{
get => _viewExport;
set
{
SetProperty(ref _viewExport, value, TestTemplateTags.ViewExport.ToString());
OnPropertyChanged(TestTemplateTags.ViewExportButtonVisibility.ToString());
}
}
private SupportedExportFormatBitFlags _exportFormats;
public SupportedExportFormatBitFlags ExportFormats
{
get => _exportFormats;
set => SetProperty(ref _exportFormats, value, TestTemplateTags.ExportFormats.ToString());
}
private string _downloadFolder = Properties.Settings.Default.DownloadFolder;
public string DownloadFolder
{
get => _downloadFolder;
set => SetProperty(ref _downloadFolder, value, TestTemplateTags.DownloadFolder.ToString());
}
private string _exportFolder = Properties.Settings.Default.DownloadFolder;
public string ExportFolder
{
get => _exportFolder;
set => SetProperty(ref _exportFolder, value, TestTemplateTags.ExportFolder.ToString());
}
private bool _sameAsDownloadFolder = true;
public bool SameAsDownloadFolder
{
get => _sameAsDownloadFolder;
set => SetProperty(ref _sameAsDownloadFolder, value, TestTemplateTags.SameAsDownloadFolder.ToString());
}
private LabratoryDetails _labDetails;
public LabratoryDetails LabDetails
{
get => _labDetails;
set => SetProperty(ref _labDetails, value, TestTemplateTags.LabDetails.ToString());
}
private CustomerDetails _customerDetails;
public CustomerDetails CustomerDetails
{
get => _customerDetails;
set => SetProperty(ref _customerDetails, value, TestTemplateTags.CustomerDetails.ToString());
}
private TestEngineerDetails _testEngineerDetails;
public TestEngineerDetails TestEngineerDetails
{
get => _testEngineerDetails;
set => SetProperty(ref _testEngineerDetails, value, TestTemplateTags.TestEngineerDetails.ToString());
}
private int _defaultNumberRealtimeGraphs;
public int DefaultNumberRealtimeGraphs
{
get
{
switch (_defaultNumberRealtimeGraphs)
{
case 6:
return 6;
case 3:
return 3;
case 1:
default:
return 1;
}
}
set
{
switch (value)
{
case 6:
_defaultNumberRealtimeGraphs = value;
break;
case 3:
_defaultNumberRealtimeGraphs = value;
break;
case 1:
default:
_defaultNumberRealtimeGraphs = value;
break;
}
OnPropertyChanged(TestTemplateTags.DefaultNumberRealtimeGraphs.ToString());
}
}
/// <summary>
/// this is a brave new world, this is the hardware for this test.
/// now groups in this test setup may have hardware assigned, or no hardware assigned
/// we'll take that if we find it, but then we'll also check a list we have for the test itself and intersect the two
/// we then modify the groups IN MEMORY and change their hardware to match all hardware officially in the test
/// </summary>
/// <returns></returns>
public void ApplyHardwareOverrides()
{
//for now don't do anything if the test setup is non iso
var hardwareInTest = new Dictionary<string, DASHardware>();
foreach (var group in TestObjects)
{
foreach (var h in group.Hardware)
{
var hiso = h.GetHardware();
if (!hardwareInTest.ContainsKey(hiso.GetId()))
{
hardwareInTest.Add(hiso.GetId(), h);
}
}
}
foreach (var group in AddedGroups)
{
foreach (var h in group.Hardware)
{
var hiso = h.GetHardware();
if (!hardwareInTest.ContainsKey(hiso.GetId()))
{
hardwareInTest.Add(hiso.GetId(), h);
}
}
}
using (var e = HardwareOverrides.GetEnumerator())
{
while (e.MoveNext())
{
switch (e.Current.Value.Action)
{
case HardwareInclusionInstruction.Actions.Add:
if (!hardwareInTest.ContainsKey(e.Current.Value.HardwareId))
{
DASHardware h = null;
try
{
h = DASHardwareList.GetList().GetHardware(e.Current.Value.HardwareId);
}
catch (DASHardwareList.HardwareTypeChangedException)
{
//APILogger.Log("test: " + Name + " refers to hardware: " +
// e.Current.Value.HardwareId + " which has changed types. " +
// ex.Message);
}
if (null != h)
{
hardwareInTest.Add(h.GetHardware().GetId(), h);
}
}
break;
case HardwareInclusionInstruction.Actions.Remove:
if (hardwareInTest.ContainsKey(e.Current.Value.HardwareId))
{
hardwareInTest.Remove(e.Current.Value.HardwareId);
}
break;
}
}
}
GetNonISOTestObject();
foreach (var group in TestObjects)
{
var hardware = new List<DASHardware>();
using (var e2 = hardwareInTest.GetEnumerator())
{
while (e2.MoveNext())
{
var newH = new DASHardware(e2.Current.Value.GetHardware());
newH.SetTimeStampMemory(e2.Current.Value.GetTimeStampMemory());
hardware.Add(newH);
}
}
group.SetHardware(hardware.ToArray());
}
foreach (var ag in AddedGroups)
{
var hardware = new List<DASHardware>();
using (var e2 = hardwareInTest.GetEnumerator())
{
while (e2.MoveNext())
{
var newH = new DASHardware(e2.Current.Value.GetHardware());
newH.SetTimeStampMemory(e2.Current.Value.GetTimeStampMemory());
hardware.Add(newH);
}
}
ag.SetHardware(hardware.ToArray());
}
}
internal Dictionary<string, LevelTriggerChannel> LevelTriggerChannels = new Dictionary<string, LevelTriggerChannel>();
public string GetLTKey(LevelTriggerChannel ch)
{
return $"{ch.HardwareChannelId}x{ch.SensorSerialNumber}";
}
public void SetLevelTrigger(LevelTriggerChannel channel)
{
var key = GetLTKey(channel);
LevelTriggerChannels[key] = new LevelTriggerChannel(channel);//do a copy just for safety
}
/// <summary>
/// sets a channel to be disabled
/// disabled channels don't appear in run test
/// </summary>
/// <param name="groupName"></param>
/// <param name="channelName"></param>
/// <param name="disabled"></param>
public void SetDisabled(string groupName, string channelName, bool disabled)
{
var matches = from g in TestObjects where g.SerialNumber == groupName select g;
if (!matches.Any()) return;
var iso = matches.First().GetISOTestObject();
var allChannels = iso.AllChannels;
foreach (var ch in allChannels)
{
if (ch.Name == channelName)
{
ch.Disabled = disabled;
break;
}
}
}
public SensorData GetSensor(string serialNumber, string testObjectSerial, string channelName)
{
lock (SensorLock)
{
var tto = GetTestTestObject(testObjectSerial);
if (!SensorLookup.ContainsKey(testObjectSerial) ||
!SensorLookup[testObjectSerial].ContainsKey(channelName) ||
!SensorLookup[testObjectSerial][channelName].ContainsKey(serialNumber))
{
var matches = from s in _sensorsFromBinary where s.SerialNumber == serialNumber select s;
if (matches.Any())
{
var s = matches.First();
var position = tto.Position.Position;
if (position != TestTestObject.UserSetKey && position != TestTestObject.ChannelDefaultsKey &&
position != s.Position)
{
s.Position = position;
}
return s;
}
}
if (SensorLookup.ContainsKey(testObjectSerial))
{
if (SensorLookup[testObjectSerial].ContainsKey(channelName))
{
if (SensorLookup[testObjectSerial][channelName].ContainsKey(serialNumber))
{
if (SensorLookup[testObjectSerial][channelName][serialNumber].FilterClassIso == "?")
{
SensorLookup[testObjectSerial][channelName][serialNumber].FilterClassIso =
"P"; // "Prefiltered > CFC 1000" (Unfiltered)
}
//for some reason the Filter isn't always set, setting filterclassiso will ensure it gets set, even though it should have already _been_ set
SensorLookup[testObjectSerial][channelName][serialNumber].FilterClassIso =
SensorLookup[testObjectSerial][channelName][serialNumber].FilterClassIso;
if (null == tto)
{
return SensorLookup[testObjectSerial][channelName][serialNumber];
}
var position = tto.Position.Position;
if (position != TestTestObject.UserSetKey &&
position != TestTestObject.ChannelDefaultsKey &&
position != SensorLookup[testObjectSerial][channelName][serialNumber].Position)
{
SensorLookup[testObjectSerial][channelName][serialNumber].Position = position;
}
return SensorLookup[testObjectSerial][channelName][serialNumber];
}
}
}
if (null == tto)
{
return SensorData.IsTestSpecificDigitalOutSN(serialNumber)
? new DigitalOutputSetting { SerialNumber = serialNumber }
: SensorsCollection.SensorsList.GetSensorBySerialNumber(serialNumber);
}
var ttosd = tto.GetSensor(channelName, serialNumber);
if (ttosd != null)
{
ttosd.TestObject = tto.TestObject.Test_Object;
var position = tto.Position.Position;
if (position != TestTestObject.UserSetKey &&
position != TestTestObject.ChannelDefaultsKey &&
position != ttosd.Position)
{
ttosd.Position = position;
}
}
else
{
return SensorData.IsTestSpecificDigitalOutSN(serialNumber)
? new DigitalOutputSetting { SerialNumber = serialNumber }
: null;
}
return ttosd;
}
}
public void SetSensor(SensorData sd, string testobjectserial, string channelname)
{
SetSensor(sd, testobjectserial, channelname, false);
}
private static readonly object SensorLock = new object();
/// <summary>
/// sets the sensor (and custom values like range/CFC/polarity) for a channel in the test
/// </summary>
/// <param name="sd"></param>
/// <param name="testobjectserial"></param>
/// <param name="channelname"></param>
/// <param name="bSetPositionFromSensor"></param>
public void SetSensor(SensorData sd, string testobjectserial, string channelname, bool bSetPositionFromSensor)
{
lock (SensorLock)
{
if (!SensorLookup.ContainsKey(testobjectserial))
{
SensorLookup.Add(testobjectserial, new Dictionary<string, Dictionary<string, SensorData>>());
}
if (!SensorLookup[testobjectserial].ContainsKey(channelname))
{
SensorLookup[testobjectserial].Add(channelname, new Dictionary<string, SensorData>());
}
//Build out the ISO fields we know about
// FB 5423
var tto = GetTestTestObject(testobjectserial) ?? new TestTestObject(new TestObject());
sd.TestObject = tto.TestObject.Test_Object;
// ReSharper disable once InconsistentNaming
var isoTO = tto.GetISOTestObject();
var channel = isoTO.GetChannel(channelname);
if (bSetPositionFromSensor)
{
if (tto.Position.Position != sd.Position && tto.Position.Position != TestTestObject.UserSetKey)
{
tto.SetPosition(TestTestObject.UserSetKey);
}
}
else
{
if ((tto.Position.Position != TestTestObject.ChannelDefaultsKey) && //Remove this?
(tto.Position.Position != TestTestObject.UserSetKey))
{
sd.Position = tto.Position.Position;
}
}
if (null != channel)
{
sd.FineLocation1 = channel.Channel.Fine_Loc_1;
sd.FineLocation2 = channel.Channel.Fine_Loc_2;
sd.FineLocation3 = channel.Channel.Fine_Loc_3;
sd.MainLocation = channel.Channel.Trans_Main_Loc;
sd.PhysicalDimension = channel.Channel.Physical_Dimension;
sd.Direction = channel.Channel.Direction;
}
SensorLookup[testobjectserial][channelname][sd.SerialNumber] = sd;
}
}
/// <summary>
/// sets the dirty flag
/// does NOT set the flag in the database, so this should only be called when the flag needs to be set in memory
/// (for instance during initialization)
/// </summary>
/// <param name="bDirty"></param>
public void SetIsDirty(bool bDirty)
{
_bIsDirty = bDirty;
}
/// <summary>
/// sets the complete flag
/// does not set the flag in the database, so this should only be called when the flag needs to be set in memory
/// (for instance during initialization)
/// </summary>
/// <param name="bComplete"></param>
public void SetIsComplete(bool bComplete)
{
_testTemplateLite.IsComplete = bComplete;
}
/// <summary>
/// sets the completion error message.
/// does not set the field in the db, so this should only be called when the information nets to be set in memory and not the db
/// (for instance during initialization)
/// </summary>
/// <param name="msg"></param>
public void SetCompletionErrorMessage(string msg)
{
_errorMessage = msg;
}
public int CompareTo(TestTemplate right)
{
if (null == right) { return 1; }
var r = string.Compare(Name, right.Name, StringComparison.Ordinal);
return 0 == r ? LastModified.CompareTo(right.LastModified) : r;
}
public TestTestObject GetTestTestObject(string testObjectSerial)
{
foreach (var tto in TestObjects)
{
if (tto.SerialNumber == testObjectSerial) { return tto; }
}
return Array.Find(AddedGroups, addedGroup => addedGroup.SerialNumber == testObjectSerial);
}
/// <summary>
/// a list of hardware as read from the XML/binary
/// this is used as the record of hardware that was present when test was committed
/// </summary>
private List<DASHardware> _hardwareFromBinary = new List<DASHardware>();
/// <summary>
/// a list of sensors as read from the XML/binary
/// this is used as the record of hardware that was present when test was committed
/// </summary>
private List<SensorData> _sensorsFromBinary = new List<SensorData>();
/// <summary>
/// a list of sensor calibrations as read from the XML/binary
/// this is used as the record of calibrations that was present when test was committed
/// </summary>
private List<SensorCalibration> _calibrationsFromBinary = new List<SensorCalibration>();
public IISOHardware[] GetAllCachedHardware()
{
var list = from h in _hardwareFromBinary select h.GetHardware();
if (list.Any())
{
return list.ToArray();
}
return new IISOHardware[0];
}
public DASHardware GetCachedHardware(string serialNumber)
{
var matches = from h in _hardwareFromBinary where h.SerialNumber == serialNumber select h;
if (matches.Any())
{
return matches.First();
}
return null;
}
// #region Validate
public static bool ValidateTestSetupName(ref List<string> errors, TestTemplate CurrentTestSetup)
{
if (string.IsNullOrWhiteSpace(CurrentTestSetup.Name))
{
errors.Add("EditTestSetup_NameRequired");
return false;
}
if (CurrentTestSetup.Name == "QuickSensorCheck_DefaultTestName" &&
!CurrentTestSetup.QuickSensorCheck)
{
errors.Add("QuickSensorCheck_DefaultTestNameInvalid");
return false;
}
if (DiskUtility.ValidateFileAndPathNameChars(CurrentTestSetup.Name))
{
var nameToCheck = CurrentTestSetup.Name.ToLower();
if (nameToCheck.Equals("iso") || nameToCheck.Equals("csv") || nameToCheck.Equals("realtime"))
{
errors.Add("EditTestSetup_NameCannotBeISOCSVOrRealtime");
return false;
}
var encoding = Encoding.GetEncoding("UTF-8");
var nameInBytes = encoding.GetBytes(nameToCheck);
if (nameInBytes.Length == nameToCheck.Length) return true;
errors.Add("EditTestSetup_NameCannotContainDoubleByteCharacters");
return false;
}
errors.Add("EditTestSetup_NameContainsInvalidCharacters");
//fatal
return false;
}
public static bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow, TestTemplate CurrentTestSetup, bool bValid, StrictLevel strictness, bool bWarnOnNotFullyAssigned, bool bRefreshHardware = true)
{
if (!Validate(ref errors, ref warnings, displayWindow, CurrentTestSetup, bValid, strictness, true,
bWarnOnNotFullyAssigned, bRefreshHardware))
{
CurrentTestSetup.SetIsComplete(false);
return false;
}
if (errors.Any())
{
CurrentTestSetup.SetIsComplete(false);
return false;
}
CurrentTestSetup.SetIsComplete(true);
return true;
}
private SensorCalibration GetSensorCalibration(SensorData sd, ExcitationVoltageOptions.ExcitationVoltageOption preferredExcitation)
{
var matches = from sc in _calibrationsFromBinary where sc.SerialNumber == sd.SerialNumber select sc;
if (matches.Any())
{
SensorCalibration sc = null;
foreach (var cal in matches)
{
if (cal.IsProportional)
{
var bIsOk = Array.Exists(cal.Records.Records, record => record.Excitation == preferredExcitation);
if (!bIsOk) { continue; }
}
if (null == sc) { sc = cal; }
else if (sc.CalibrationDate < cal.CalibrationDate) { sc = cal; }
else if (sc.CalibrationDate == cal.CalibrationDate && sc.ModifyDate < cal.ModifyDate)
{
sc = cal;
}
}
if (null != sc) { return sc; }
}
return SensorCalibration.GetLatestCalibrationBySerialNumberAndExcitation(sd, preferredExcitation);
}
public static bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow, TestTemplate CurrentTestSetup, bool bValid, StrictLevel strictness, bool markIsCompleteUnchecked, bool bWarnOnNotFullyAssigned, bool bRefreshHardware)
{
//I'm not sure of all the entry points into this function
//it seems like there are many
//however there are definite times we _don't_ want to just blindly change the iscompleteunchecked flag
//just because we want to do some validation on the test plan ...
//for now I just fixed the ones I know shouldn't be changing the flag blindly
//and preserved current behavior for the rest ...
//if (markIsCompleteUnchecked) { CurrentTestSetup.MarkIsCompleteUnchecked(); }
var bHasHardware = false;
var bHasChannels = false;
var testobjects = new List<TestTestObject>();
testobjects.AddRange(CurrentTestSetup.TestObjects);
testobjects.AddRange(CurrentTestSetup.AddedGroups);
var serialNumbersProcessed = new Dictionary<string, bool>();
var hardwareChannelIdsProcessed = new Dictionary<string, bool>();
var channelLookup = new Dictionary<string, HardwareChannel>();
var usedISOCodesLookup = new Dictionary<string, bool>();
var availableAnalogChannels = 0;
var availableDigitalInputChannels = 0;
var availableDigitalOutputChannels = 0;
var availableSquibChannels = 0;
if (testobjects.Any())
{
//this is using the assumption that all testobjects now have the same list of hardware
foreach (var lastTo in testobjects)
{
if (bRefreshHardware) { lastTo.RefreshHardware(); }
foreach (var h in lastTo.Hardware)
{
if (null == h)
{
continue;
}
var hType = h.GetHardwareTypeEnum();
if (hType == HardwareTypes.SLICE_EthernetController
|| hType == HardwareTypes.SLICE_Distributor
|| hType == HardwareTypes.SLICE_LabEthernet
|| hType == HardwareTypes.SLICE6DB)
{
continue;
}
bHasHardware = true;
if (CurrentTestSetup.DoAutoArm)
{
switch (hType)
{
case HardwareTypes.TDAS_Pro_Rack:
case HardwareTypes.TDAS_LabRack:
case HardwareTypes.G5INDUMMY:
case HardwareTypes.G5VDS:
errors.Add("EditTestSetupPage_HardwareDoesNotSupportAutoArm");
break;
}
}
for (var i = 0; i < h.Channels.Length; i++)
{
var ch = h.Channels[i];
if (channelLookup.ContainsKey(ch.GetId())) continue;
channelLookup.Add(ch.GetId(), ch);
if (ch.IsSupportedBridgeType(Test.Module.Channel.Sensor.BridgeType.SQUIB))
{
availableSquibChannels++; i++; /*bypass next channel as it's also a squib*/
}
else if (ch.IsSupportedBridgeType(Test.Module.Channel.Sensor.BridgeType.DigitalInput))
{ availableDigitalInputChannels++; }
else if (ch.IsSupportedBridgeType(Test.Module.Channel.Sensor.BridgeType.TOMDigital))
{ availableDigitalOutputChannels++; }
else { availableAnalogChannels++; }
}
}
}
if (!bHasHardware && bWarnOnNotFullyAssigned)
{
errors.Add("EditTestSetupPage_NoHardwareInTest");
}
}
else
{
errors.Add("EditTestSetupPage_NoGroupsInTest");
}
foreach (var to in testobjects)
{
var isoTo = to.GetISOTestObject();
foreach (var ch in isoTo.AllChannels)
{
if (!ch.Required)
{
continue;
}
bHasChannels = true;
if (string.IsNullOrWhiteSpace(ch.SensorSerialNumber))
{
if (!errors.Contains("EditTestSetupPage_NoSensorOnChannel") &&
bWarnOnNotFullyAssigned)
{
errors.Add("EditTestSetupPage_NoSensorOnChannel");
}
}
else
{
if (serialNumbersProcessed.ContainsKey(ch.SensorSerialNumber))
{
var err = string.Format("EditTestSetupPage_SerialNumberAppearsTwice",
ch.SensorSerialNumber);
if (!errors.Contains(err))
{
errors.Add(err);
}
return false;
}
serialNumbersProcessed.Add(ch.SensorSerialNumber, true);
var sd = CurrentTestSetup.GetSensor(ch.SensorSerialNumber, to.SerialNumber, ch.Name);
if (null == sd)
{
var err = string.Format("EditTestSetupPage_CouldNotFindSensor",
ch.SensorSerialNumber, ch.Name, to.DisplaySerialNumber);
if (!errors.Contains(err))
{
errors.Add(err);
}
}
else
{
if (sd.IsSquib())
{
availableSquibChannels--;
if (sd.SquibFireDelayMS + sd.SquibFireDurationMS >
CurrentTestSetup.PostTriggerSeconds * 1000)
{
errors.Add(string.Format(
"TestTemplate_InsufficientPostTriggerLength",
sd.SerialNumber, ch.Name));
}
}
else if (sd.IsDigitalInput())
{
availableDigitalInputChannels--;
}
else if (sd.IsDigitalOutput())
{
availableDigitalOutputChannels--;
if (sd.DigitalOutputDelayMS + sd.DigitalOutputDurationMS >
CurrentTestSetup.PostTriggerSeconds * 1000)
{
errors.Add(string.Format(
"TestTemplate_InsufficientPostTriggerLength",
sd.SerialNumber, ch.Name));
}
}
else
{
availableAnalogChannels--;
}
var sensor = SensorsCollection.SensorsList.GetSensorBySerialNumber(ch.SensorSerialNumber);
if (sensor != null)
{
var sensorDimension = sensor.PhysicalDimension;
if ((((App)Application.Current).IsoDb.GetPhysicalDimensionByIso(sensorDimension) !=
null) &&
(((App)Application.Current).IsoDb.GetPhysicalDimensionByIso(ch.Channel
.Physical_Dimension) != null) &&
(sd.IncompatibleSensorAssignment(sensorDimension, ch.Channel.Physical_Dimension)))
{
var err = string.Format(
"EditTestSetupPage_IncompatibleSensorNotSupported",
((App)Application.Current).IsoDb.GetPhysicalDimensionByIso(sensorDimension)
.Text_L1,
ch.SensorSerialNumber,
((App)Application.Current).IsoDb
.GetPhysicalDimensionByIso(ch.Channel.Physical_Dimension).Text_L1,
ch.Name, to.DisplaySerialNumber);
switch (SerializedSettings.IsoChannelSensorCompatibilityLevel)
{
case IsoChannelSensorCompatibilityLevels.DontAllow:
if (!errors.Contains(err))
{
errors.Add(err);
}
bValid = false;
break;
case IsoChannelSensorCompatibilityLevels.Warn:
if (!warnings.Contains(
"EditObjectSensorsControl_Warning" + ": " + err))
{
warnings.Add("EditObjectSensorsControl_Warning" +
": " + err);
}
break;
}
}
}
if (!sd.IsDigitalOutput() &&
(CurrentTestSetup.GetISOTestSetupISOSupportLevel() ==
SerializedSettings.ISOSupportLevels.ISO_ONLY))
{
if (sd.MainLocation.Contains('?') ||
sd.FineLocation1.Contains('?') ||
sd.FineLocation2.Contains('?') ||
sd.FineLocation3.Contains('?') ||
sd.Direction.Contains('?') ||
sd.PhysicalDimension.Contains('?'))
{
var isoto = to.GetISOTestObject();
foreach (var isotoChannel in isoto.AllChannels)
{
//reapplying channel iso settings here with the exception of filter class, position, and test object
if (ch.Name != isotoChannel.Name) continue;
sd.MainLocation = ch.Channel.Trans_Main_Loc;
sd.FineLocation1 = ch.Channel.Fine_Loc_1;
sd.FineLocation2 = ch.Channel.Fine_Loc_2;
sd.FineLocation3 = ch.Channel.Fine_Loc_3;
sd.Direction = ch.Channel.Direction;
sd.PhysicalDimension = ch.Channel.Physical_Dimension;
}
}
if (usedISOCodesLookup.ContainsKey(sd.ISOCode))
{
var err = string.Format("TestTemplate_DuplicateISOCode",
sd.ISOCode);
if (!errors.Contains(err))
{
errors.Add(err);
}
}
else
{
usedISOCodesLookup[sd.ISOCode] = true;
}
}
SensorCalibration sc = null;
var preferredExcitation = sd.SupportedExcitation[0];
sc = CurrentTestSetup.GetSensorCalibration(sd, preferredExcitation);
//sc = SensorCalibration.GetLatestCalibrationBySerialNumberAndExcitation(sd, preferredExcitation); //se);
if (null == sc)
{
bValid = false;
var err = string.Format("EditTestSEtupPage_MissingCalibration",
ch.Name, sd.SerialNumber);
if (!errors.Contains(err))
{
errors.Add(err);
}
}
else
{
var now = DateTime.Now;
var days = sc.CalibrationDate.AddDays(sd.CalInterval).Subtract(now).TotalDays;
if (SerializedSettings.TestSetupDefaultDontAllowOutOfCalSensors &&
((days < 0) || (days < Properties.Settings.Default.CalWarningPeriodDays)))
{
bValid = false;
var err = string.Format(
"OverdueSensors_CalibrationDateOverdueOrNear",
ch.Name, sd.SerialNumber);
if (!errors.Contains(err))
{
errors.Add(err);
}
}
}
if (string.IsNullOrWhiteSpace(ch.HardwareId)) continue;
if (!channelLookup.ContainsKey(ch.HardwareId))
{
var err = string.Format("EditTestSetupPage_InvalidHardware",
ch.Name, to.DisplaySerialNumber);
if (!errors.Contains(err))
{
errors.Add(err);
}
}
else
{
if (hardwareChannelIdsProcessed.ContainsKey(ch.HardwareId))
{
bValid = false;
var err = string.Format(
"EditTestSetupPage_HardwareAlreadyInUse", ch.Name,
to.DisplaySerialNumber);
if (!errors.Contains(err))
{
errors.Add(err);
}
}
else
{
hardwareChannelIdsProcessed.Add(ch.HardwareId, true);
var hch = channelLookup[ch.HardwareId];
if (sd.ByPassFilter &&
((hch.Hardware.GetHardwareTypeEnum() != HardwareTypes.TDAS_Pro_Rack) &&
(hch.Hardware.GetHardwareTypeEnum() != HardwareTypes.TDAS_LabRack)))
{
var err = string.Format(
"EditTestSetupPage_BypassAAFilterNotSupported",
ch.Name, to.DisplaySerialNumber);
if (!errors.Contains(err))
{
errors.Add(err);
}
}
else
{
if (hch.IsSupportedBridgeType(sd.Bridge)) continue;
var err = string.Format(
"EditTestSetupPage_BridgeNotSupported",
sd.Bridge.ToString(), ch.Name, to.DisplaySerialNumber);
if (!errors.Contains(err))
{
errors.Add(err);
}
}
}
}
}
}
}
}
if (!bHasChannels) { errors.Add("EditTestSetupPage_NoChannelsInTest"); }
if (availableAnalogChannels < 0 && !CurrentTestSetup.AllowMissingSensors && bWarnOnNotFullyAssigned)
{
if (!errors.Contains("EditTestSetupPage_NeedMoreAnalogChannels") && !errors.Contains("EditTestSetupPage_NoHardwareInTest"))
{ errors.Add("EditTestSetupPage_NeedMoreAnalogChannels"); }
}
if (availableDigitalInputChannels < 0 && !CurrentTestSetup.AllowMissingSensors && bWarnOnNotFullyAssigned)
{
if (!errors.Contains("EditTestSetupPage_NeedMoreDigitalInputChannels") && !errors.Contains("EditTestSetupPage_NoHardwareInTest"))
{ errors.Add("EditTestSetupPage_NeedMoreDigitalInputChannels"); }
}
if (availableDigitalOutputChannels < 0 && !CurrentTestSetup.AllowMissingSensors && bWarnOnNotFullyAssigned)
{
if (!errors.Contains("EditTestSetupPage_NeedMoreDigitalOutputChannels") && !errors.Contains("EditTestSetupPage_NoHardwareInTest"))
{ errors.Add("EditTestSetupPage_NeedMoreDigitalOutputChannels"); }
}
if (availableSquibChannels < 0 && !CurrentTestSetup.AllowMissingSensors && bWarnOnNotFullyAssigned)
{
if (!errors.Contains("EditTestSetupPage_NeedMoreSquibChannels") && !errors.Contains("EditTestSetupPage_NoHardwareInTest"))
{ errors.Add("EditTestSetupPage_NeedMoreSquibChannels"); }
}
if (!ValidateTestSetupName(ref errors, CurrentTestSetup)) { bValid = false; }
ValidateStorageSpace(ref errors, CurrentTestSetup);//not fatal
ValidateUploadFolder(ref errors, CurrentTestSetup);//not fatal
ValidateAutoArmAllowability(ref errors, CurrentTestSetup);
return bValid;
}
public static bool ValidateUploadFolder(ref List<string> errors, TestTemplate currentTest)
{
//if we have a export ini file, we still allow a blank upload folder
if (!currentTest.UploadData || !string.IsNullOrWhiteSpace(currentTest.UploadFolder)) return true;
if (SerializedSettings.ExportINIFile.Length > 0) { return true; }
errors.Add("TestTestTemplate_InvalidUploadPath");
return false;
}
private static bool ValidateAutoArmAllowability(ref List<string> errors, TestTemplate currentTest)
{
if (!currentTest.DoAutoArm || Properties.Settings.Default.AllowAutoArm) return true;
errors.Add("EditTestSetupInfo_AutoArmNotAllowed");
return false;
}
public static bool ValidateStorageSpace(ref List<string> errors, TestTemplate currentTest)
{
var bStorageSpaceValid = true;
var preTriggerSeconds = currentTest.PreTriggerSeconds;
var postTriggerSeconds = currentTest.PostTriggerSeconds;
var sampleRate = currentTest.SamplesPerSecond;
var secondsToRecord = preTriggerSeconds + postTriggerSeconds;
var sampleClocksToRecord = (ulong)(secondsToRecord * sampleRate + 1);
var das = new List<DASHardware>();
foreach (var to in currentTest.TestObjects)
{
foreach (var h in to.Hardware)
{
if (!das.Contains(h)) { das.Add(h); }
}
}
foreach (var to in currentTest.AddedGroups)
{
foreach (var h in to.Hardware)
{
if (!das.Contains(h)) { das.Add(h); }
}
}
foreach (var d in das)
{
double maxSampleClockTicks = d.GetMaxMemoryLong();
if (!(maxSampleClockTicks > 0)) continue;
if (!(sampleClocksToRecord > maxSampleClockTicks)) continue;
bStorageSpaceValid = false;
errors.Add(string.Format("TestTemplate_InsufficientMemory", d.SerialNumber, maxSampleClockTicks));
}
return bStorageSpaceValid;
}
private void _roi_ListChanged(object sender, ListChangedEventArgs e)
{
OnPropertyChanged(TestTemplateTags.RegionsOfInterest.ToString());
}
public void AddTestGraph(TestGraph tg)
{
_testGraphs.Add(tg);
}
/// <summary>
/// holds test settings that don't have individual db columns
/// </summary>
//private ISO.TestSettingDictionary _settings = CreateSettingsDictionary();
private TestSettingDictionary _settings;
/// <summary>
/// loads values from a serialized string into the settings table
/// </summary>
/// <param name="s"></param>
public void LoadSettings(string s)
{
_settings.LoadSettings(s);
}
/// <summary>
/// returns the iso support level of object (as determined by it's groups, or the current application support level)
/// </summary>
/// <returns></returns>
public SerializedSettings.ISOSupportLevels GetISOTestSetupISOSupportLevel()
{
var nonIsoTestObject = GetNonISOTestObject();
foreach (var to in TestObjects)
{
if (to == nonIsoTestObject)
{
//if it only has digital outputs, it could be either a non iso or an iso group, so ignore it
var isoto = to.GetISOTestObject();
if (isoto.AllChannels.Where(ch => ch.Required && !string.IsNullOrWhiteSpace(ch.SensorSerialNumber)).Any(ch => !SensorData.IsTestSpecificDigitalOutSN(ch.SensorSerialNumber)))
{
return SerializedSettings.ISOSupportLevels.NO_ISO;
}
}
else
{
return to.GetObjectISOLevel();
}
}
if (AddedGroups.Any())
{
return SerializedSettings.ISOSupportLevels.ISO_ONLY;
}
return SerializedSettings.ISOSupportLevel;
}
private TestTestObject CreateNonISOGroupIfNecessary()
{
foreach (var group in _testObjects)
{
if (group.SerialNumberOrOriginalSerialNumber == NON_ISO_INTERNAL_GROUP_NAME)
{
return group;
}
}
//if you got here it wasn't found
var guid = Guid.NewGuid();
var template = new TestObjectTemplate();
var isoTestObjectTemplate = template.ToISOTestObjectTemplate();
isoTestObjectTemplate.Embedded = true;
isoTestObjectTemplate.TemplateName = guid.ToString();
if (Application.Current is App app)
{
var db = app.IsoDb;
template = new TestObjectTemplate(isoTestObjectTemplate, ref db);
}
var to = new TestObject { Template = template };
to.GetISOTestObject().Embedded = true;
to.GetISOTestObject().OriginalSerialNumber = NON_ISO_INTERNAL_GROUP_NAME;
to.SerialNumber = guid.ToString();
var g = new TestTestObject(to);
_testObjects.Add(g);
TestObjectsAndAddedGroupsList.Add(g);
return g;
}
public TestTestObject GetNonISOTestObject()
{
return CreateNonISOGroupIfNecessary();
}
public void AddTestObject(TestObject to, int excitationWarmupMs, double targetSampleRate, string testobject, string position)
{
if (null != to)
{
var tto = new TestTestObject(to)
{
ExcitationWarmupTimeMS = excitationWarmupMs,
TargetSampleRate = targetSampleRate
};
tto.SetPosition(position);
tto.SetTestObject(testobject);
//if this is the NON ISO group (which is created by default), the replace the original NONE group ...
if (tto.SerialNumberOrOriginalSerialNumber == NON_ISO_INTERNAL_GROUP_NAME)
{
var index = -1;
for (var i = 0; i < TestObjectsAndAddedGroupsList.Count; i++)
{
if (TestObjectsAndAddedGroupsList[i].SerialNumberOrOriginalSerialNumber != NON_ISO_INTERNAL_GROUP_NAME) continue;
index = i;
break;
}
if (index >= 0)
{
TestObjectsAndAddedGroupsList.RemoveAt(index);
}
index = -1;
for (var i = 0; i < _testObjects.Count; i++)
{
if (_testObjects[i].SerialNumberOrOriginalSerialNumber != NON_ISO_INTERNAL_GROUP_NAME) continue;
index = i;
break;
}
if (index >= 0)
{
_testObjects.RemoveAt(index);
}
}
_testObjects.Add(tto);
TestObjectsAndAddedGroupsList.Add(tto);
OnPropertyChanged(TestTemplateTags.TestObjects.ToString());
OnPropertyChanged(TestTemplateTags.DefaultNumberRealtimeGraphs.ToString());
}
}
public void AddTestObject(string serialNumber, int excitationWarmupMs, double targetSampleRate, string testobject, string position)
{
var to = TestObjectList.TestObjectsList.GetTestObject(serialNumber);
AddTestObject(to, excitationWarmupMs, targetSampleRate, testobject, position);
OnPropertyChanged(TestTemplateTags.DefaultNumberRealtimeGraphs.ToString());
}
public void AddAddedGroup(TestObject to, string testobject, string position)
{
if (null == to) return;
var tto = new TestTestObject(to);
tto.SetPosition(position);
tto.SetTestObject(testobject);
tto.SerialNumberConverted = tto.SerialNumber.Remove(0, Name.Length + 1);
tto.TestSetupName = Name;
_addedGroups.Add(tto);
TestObjectsAndAddedGroupsList.Add(tto);
OnPropertyChanged(TestTemplateTags.DefaultNumberRealtimeGraphs.ToString());
}
public void AddAddedGroup(string serialNumber, string testobject, string position)
{
var to = TestObjectList.AddedGroupsList.GetAddedGroup(serialNumber);
AddAddedGroup(to, testobject, position);
OnPropertyChanged(TestTemplateTags.DefaultNumberRealtimeGraphs.ToString());
}
public int GetNumberOfRealtimeSupportedChannels()
{
var count = 0;
foreach (var to in TestObjects)
{
var isoto = to.GetISOTestObject();
count += isoto.AllChannels.Where(ch => ch.Required && !string.IsNullOrWhiteSpace(ch.SensorSerialNumber)).Select(ch => GetSensor(ch.SensorSerialNumber, to.SerialNumber, ch.Name)).Where(sd => null != sd).Count(sd => !sd.IsDigitalInput() && !sd.IsDigitalOutput() && !sd.IsSquib());
}
foreach (var to in AddedGroups)
{
var isoto = to.GetISOTestObject();
count += isoto.AllChannels.Where(ch => ch.Required && !string.IsNullOrWhiteSpace(ch.SensorSerialNumber)).Select(ch => GetSensor(ch.SensorSerialNumber, to.SerialNumber, ch.Name)).Where(sd => null != sd).Count(sd => !sd.IsDigitalInput() && !sd.IsDigitalOutput() && !sd.IsSquib());
}
if (0 == count) { count = MAX_REALTIME_CHANNELS; }
return count;
}
public void AddCalculatedChannel(CalculatedValueClass ch)
{
CalculatedChannels.Add(ch);
}
private readonly Dictionary<char, TestObjectMetaData> _metaDataLookup = new Dictionary<char, TestObjectMetaData>();
private TestSetupMetaData _testSetupMeta = new TestSetupMetaData(Properties.Settings.Default.RequireXCrashCompatibilityForISOExports);
public void SetTestSetupMetaData(TestSetupMetaData meta)
{
_testSetupMeta = meta;
}
public void SetMetaData(char testobject, TestObjectMetaData meta)
{
_metaDataLookup[testobject] = meta;
}
}
}