1005 lines
39 KiB
C#
1005 lines
39 KiB
C#
using DTS.Common.Enums;
|
|
using DTS.Common.Enums.DASFactory;
|
|
using DTS.Common.Enums.Viewer;
|
|
using DTS.Common.Interface.Groups.GroupList;
|
|
using DTS.Common.Interface.RegionOfInterest;
|
|
using DTS.Common.Interface.TestSetups.TestSetupsList;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using System.Xml;
|
|
using DTS.Common.Interface.Channels;
|
|
using DTS.Common.Interface;
|
|
|
|
namespace DTS.Common.Classes.TestSetups
|
|
{
|
|
public abstract class TestTemplateBase : TestSetupRecord
|
|
{
|
|
public TestTemplateBase() { }
|
|
public TestTemplateBase(TestTemplateBase copy)
|
|
: base(copy)
|
|
{
|
|
}
|
|
public new bool LowgLevelTriggerOn
|
|
{
|
|
get => base.LowgLevelTriggerOn;
|
|
set
|
|
{
|
|
base.LowgLevelTriggerOnX = value;
|
|
base.LowgLevelTriggerOnY = value;
|
|
base.LowgLevelTriggerOnZ = value;
|
|
base.LowgLevelTriggerOn = value;
|
|
}
|
|
}
|
|
|
|
private void DetermineLowgLevelTriggersMixed()
|
|
{
|
|
LowgLevelTriggersMixed = !(LowgLinearLevelTriggerX == LowgLinearLevelTriggerY &&
|
|
LowgLinearLevelTriggerX == LowgLinearLevelTriggerZ);
|
|
}
|
|
private bool _lowgLevelTriggersMixed = false;
|
|
public bool LowgLevelTriggersMixed
|
|
{
|
|
get => _lowgLevelTriggersMixed;
|
|
set => SetProperty(ref _lowgLevelTriggersMixed, value, "LowgLevelTriggersMixed");
|
|
}
|
|
private void CheckLowgLevelTrigger()
|
|
{
|
|
_bLowgLevelTriggerOn = LowgLevelTriggerOnX || LowgLevelTriggerOnY || LowgLevelTriggerOnZ;
|
|
OnPropertyChanged("LowgLevelTriggerOn");
|
|
}
|
|
|
|
public new bool LowgLevelTriggerOnX
|
|
{
|
|
get => base.LowgLevelTriggerOnX;
|
|
set
|
|
{
|
|
base.LowgLevelTriggerOnX = value;
|
|
CheckLowgLevelTrigger();
|
|
}
|
|
}
|
|
|
|
public new bool LowgLevelTriggerOnY
|
|
{
|
|
get => base.LowgLevelTriggerOnY;
|
|
set
|
|
{
|
|
base.LowgLevelTriggerOnY = value;
|
|
CheckLowgLevelTrigger();
|
|
}
|
|
}
|
|
|
|
public new bool LowgLevelTriggerOnZ
|
|
{
|
|
get => base.LowgLevelTriggerOnZ;
|
|
set
|
|
{
|
|
base.LowgLevelTriggerOnZ = value;
|
|
CheckLowgLevelTrigger();
|
|
}
|
|
}
|
|
|
|
public new bool HighgLevelTriggerOn
|
|
{
|
|
get => base.HighgLevelTriggerOn;
|
|
set
|
|
{
|
|
base.HighgLevelTriggerOnX = value;
|
|
base.HighgLevelTriggerOnY = value;
|
|
base.HighgLevelTriggerOnZ = value;
|
|
base.HighgLevelTriggerOn = value;
|
|
}
|
|
}
|
|
|
|
private void CheckHighgLevelTrigger()
|
|
{
|
|
_bHighgLevelTriggerOn = HighgLevelTriggerOnX || HighgLevelTriggerOnY || HighgLevelTriggerOnZ;
|
|
OnPropertyChanged("HighgLevelTriggerOn");
|
|
}
|
|
public new bool HighgLevelTriggerOnX
|
|
{
|
|
get => base.HighgLevelTriggerOnX;
|
|
set
|
|
{
|
|
base.HighgLevelTriggerOnX = value;
|
|
CheckHighgLevelTrigger();
|
|
}
|
|
}
|
|
public new bool HighgLevelTriggerOnY
|
|
{
|
|
get => base.HighgLevelTriggerOnY;
|
|
set
|
|
{
|
|
base.HighgLevelTriggerOnY = value;
|
|
CheckHighgLevelTrigger();
|
|
}
|
|
}
|
|
|
|
public new bool HighgLevelTriggerOnZ
|
|
{
|
|
get => base.HighgLevelTriggerOnZ;
|
|
set
|
|
{
|
|
base.HighgLevelTriggerOnZ = value;
|
|
CheckHighgLevelTrigger();
|
|
}
|
|
}
|
|
|
|
public new bool AngularAccelLevelTriggerOn
|
|
{
|
|
get => base.AngularAccelLevelTriggerOn;
|
|
set
|
|
{
|
|
AngularAccelLevelTriggerOnX = value;
|
|
AngularAccelLevelTriggerOnY = value;
|
|
AngularAccelLevelTriggerOnZ = value;
|
|
base.AngularAccelLevelTriggerOn = value;
|
|
}
|
|
}
|
|
|
|
private void CheckAngularAccelLevelTriggerOn()
|
|
{
|
|
_bAngularAccelLevelTriggerOn =
|
|
AngularAccelLevelTriggerOnX || AngularAccelLevelTriggerOnY || AngularAccelLevelTriggerOnZ;
|
|
OnPropertyChanged("AngularAccelLevelTriggerOn");
|
|
}
|
|
|
|
public new bool AngularAccelLevelTriggerOnX
|
|
{
|
|
get => base.AngularAccelLevelTriggerOnX;
|
|
set
|
|
{
|
|
base.AngularAccelLevelTriggerOnX = value;
|
|
CheckAngularAccelLevelTriggerOn();
|
|
}
|
|
}
|
|
|
|
public new bool AngularAccelLevelTriggerOnY
|
|
{
|
|
get => base.AngularAccelLevelTriggerOnY;
|
|
set
|
|
{
|
|
base.AngularAccelLevelTriggerOnY = value;
|
|
CheckAngularAccelLevelTriggerOn();
|
|
}
|
|
}
|
|
|
|
public new bool AngularAccelLevelTriggerOnZ
|
|
{
|
|
get => base.AngularAccelLevelTriggerOnZ;
|
|
set
|
|
{
|
|
base.AngularAccelLevelTriggerOnZ = value;
|
|
CheckAngularAccelLevelTriggerOn();
|
|
}
|
|
}
|
|
|
|
public new bool AngularRateLevelTriggerOn
|
|
{
|
|
get => base.AngularRateLevelTriggerOn;
|
|
set
|
|
{
|
|
AngularRateLevelTriggerOnX = value;
|
|
AngularRateLevelTriggerOnY = value;
|
|
AngularRateLevelTriggerOnZ = value;
|
|
base.AngularRateLevelTriggerOn = value;
|
|
}
|
|
}
|
|
|
|
private void CheckAngularRateLevelTriggerOn()
|
|
{
|
|
_bAngularRateLevelTriggerOn =
|
|
AngularRateLevelTriggerOnX || AngularRateLevelTriggerOnY || AngularRateLevelTriggerOnZ;
|
|
OnPropertyChanged("AngularRateLevelTriggerOn");
|
|
}
|
|
public new bool AngularRateLevelTriggerOnX
|
|
{
|
|
get => base.AngularRateLevelTriggerOnX;
|
|
set
|
|
{
|
|
base.AngularRateLevelTriggerOnX = value;
|
|
CheckAngularRateLevelTriggerOn();
|
|
}
|
|
}
|
|
|
|
public new bool AngularRateLevelTriggerOnY
|
|
{
|
|
get => base.AngularRateLevelTriggerOnY;
|
|
set
|
|
{
|
|
base.AngularRateLevelTriggerOnY = value;
|
|
CheckAngularRateLevelTriggerOn();
|
|
}
|
|
}
|
|
|
|
public new bool AngularRateLevelTriggerOnZ
|
|
{
|
|
get => base.AngularRateLevelTriggerOnZ;
|
|
set
|
|
{
|
|
base.AngularRateLevelTriggerOnZ = value;
|
|
CheckAngularRateLevelTriggerOn();
|
|
}
|
|
}
|
|
|
|
public double LowgLinearLevelTriggerAggregate
|
|
{
|
|
get => LowgLinearLevelTriggerX;
|
|
set
|
|
{
|
|
LowgLinearLevelTriggerX = value;
|
|
LowgLinearLevelTriggerY = value;
|
|
LowgLinearLevelTriggerZ = value;
|
|
OnPropertyChanged("LowgLinearLevelTriggerAggregate");
|
|
}
|
|
}
|
|
|
|
public new double LowgLinearLevelTriggerX
|
|
{
|
|
get => base.LowgLinearLevelTriggerX;
|
|
set
|
|
{
|
|
base.LowgLinearLevelTriggerX = value;
|
|
DetermineLowgLevelTriggersMixed();
|
|
}
|
|
}
|
|
|
|
|
|
public new double LowgLinearLevelTriggerY
|
|
{
|
|
get => base.LowgLinearLevelTriggerY;
|
|
set
|
|
{
|
|
base.LowgLinearLevelTriggerY = value;
|
|
DetermineLowgLevelTriggersMixed();
|
|
}
|
|
}
|
|
|
|
public new double LowgLinearLevelTriggerZ
|
|
{
|
|
get => base.LowgLinearLevelTriggerZ;
|
|
set
|
|
{
|
|
base.LowgLinearLevelTriggerZ = value;
|
|
DetermineLowgLevelTriggersMixed();
|
|
}
|
|
}
|
|
|
|
private bool _highgLevelTriggersMixed = false;
|
|
public bool HighgLevelTriggersMixed
|
|
{
|
|
get => _highgLevelTriggersMixed;
|
|
set => SetProperty(ref _highgLevelTriggersMixed, value, "HighgLevelTriggersMixed");
|
|
}
|
|
|
|
private void DetermineHighgLevelTriggersMixed()
|
|
{
|
|
HighgLevelTriggersMixed = !(HighgLinearLevelTriggerX == HighgLinearLevelTriggerY &&
|
|
HighgLinearLevelTriggerX == HighgLinearLevelTriggerZ);
|
|
}
|
|
|
|
public double HighgLinearLevelTriggerAggregate
|
|
{
|
|
get => HighgLinearLevelTriggerX;
|
|
set
|
|
{
|
|
HighgLinearLevelTriggerX = value;
|
|
HighgLinearLevelTriggerY = value;
|
|
HighgLinearLevelTriggerZ = value;
|
|
OnPropertyChanged("HighgLinearLevelTriggerAggregate");
|
|
}
|
|
}
|
|
|
|
public new double HighgLinearLevelTriggerX
|
|
{
|
|
get => base.HighgLinearLevelTriggerX;
|
|
set
|
|
{
|
|
base.HighgLinearLevelTriggerX = value;
|
|
DetermineHighgLevelTriggersMixed();
|
|
}
|
|
}
|
|
|
|
public new double HighgLinearLevelTriggerY
|
|
{
|
|
get => base.HighgLinearLevelTriggerY;
|
|
set
|
|
{
|
|
base.HighgLinearLevelTriggerY = value;
|
|
DetermineHighgLevelTriggersMixed();
|
|
}
|
|
}
|
|
|
|
public new double HighgLinearLevelTriggerZ
|
|
{
|
|
get => base.HighgLinearLevelTriggerZ;
|
|
set
|
|
{
|
|
base.HighgLinearLevelTriggerZ = value;
|
|
DetermineHighgLevelTriggersMixed();
|
|
}
|
|
}
|
|
private bool _angularRateLevelTriggersMixed = false;
|
|
public bool AngularRateLevelTriggersMixed
|
|
{
|
|
get => _angularRateLevelTriggersMixed;
|
|
set => SetProperty(ref _angularRateLevelTriggersMixed, value, "AngularRateLevelTriggersMixed");
|
|
}
|
|
|
|
private void DetermineAngularRateLevelTriggeresMixed()
|
|
{
|
|
AngularRateLevelTriggersMixed = !(AngularRateLevelTriggerX == AngularRateLevelTriggerY &&
|
|
AngularRateLevelTriggerX == AngularRateLevelTriggerZ);
|
|
}
|
|
public double AngularRateLevelTriggerAggregate
|
|
{
|
|
get => AngularRateLevelTriggerX;
|
|
set
|
|
{
|
|
AngularRateLevelTriggerX = value;
|
|
AngularRateLevelTriggerY = value;
|
|
AngularRateLevelTriggerZ = value;
|
|
OnPropertyChanged("AngularRateLevelTriggerAggregate");
|
|
}
|
|
}
|
|
|
|
public new double AngularRateLevelTriggerX
|
|
{
|
|
get => base.AngularRateLevelTriggerX;
|
|
set
|
|
{
|
|
base.AngularRateLevelTriggerX = value;
|
|
DetermineAngularRateLevelTriggeresMixed();
|
|
}
|
|
}
|
|
|
|
public new double AngularRateLevelTriggerY
|
|
{
|
|
get => base.AngularRateLevelTriggerY;
|
|
set
|
|
{
|
|
base.AngularRateLevelTriggerY = value;
|
|
DetermineAngularRateLevelTriggeresMixed();
|
|
}
|
|
}
|
|
|
|
public new double AngularRateLevelTriggerZ
|
|
{
|
|
get => base.AngularRateLevelTriggerZ;
|
|
set
|
|
{
|
|
base.AngularRateLevelTriggerZ = value;
|
|
DetermineAngularRateLevelTriggeresMixed();
|
|
}
|
|
}
|
|
|
|
private bool _angularAccelLevelTriggersMixed = false;
|
|
public bool AngularAccelLevelTriggersMixed
|
|
{
|
|
get => _angularAccelLevelTriggersMixed;
|
|
set => SetProperty(ref _angularAccelLevelTriggersMixed, value, "AngularAccelLevelTriggersMixed");
|
|
}
|
|
|
|
private void DetermineAngularAccelLevelTriggeresMixed()
|
|
{
|
|
AngularAccelLevelTriggersMixed = !(AngularAccelLevelTriggerX == AngularAccelLevelTriggerY &&
|
|
AngularAccelLevelTriggerX == AngularAccelLevelTriggerZ);
|
|
}
|
|
public double AngularAccelLevelTriggerAggregate
|
|
{
|
|
get => AngularAccelLevelTriggerX;
|
|
set
|
|
{
|
|
AngularAccelLevelTriggerX = value;
|
|
AngularAccelLevelTriggerY = value;
|
|
AngularAccelLevelTriggerZ = value;
|
|
OnPropertyChanged("AngularAccelLevelTriggerAggregate");
|
|
}
|
|
}
|
|
|
|
public new double AngularAccelLevelTriggerX
|
|
{
|
|
get => base.AngularAccelLevelTriggerX;
|
|
set
|
|
{
|
|
base.AngularAccelLevelTriggerX = value;
|
|
DetermineAngularAccelLevelTriggeresMixed();
|
|
}
|
|
}
|
|
|
|
public new double AngularAccelLevelTriggerY
|
|
{
|
|
get => base.AngularAccelLevelTriggerY;
|
|
set
|
|
{
|
|
base.AngularAccelLevelTriggerY = value;
|
|
DetermineAngularAccelLevelTriggeresMixed();
|
|
}
|
|
}
|
|
|
|
public new double AngularAccelLevelTriggerZ
|
|
{
|
|
get => base.AngularAccelLevelTriggerZ;
|
|
set
|
|
{
|
|
base.AngularAccelLevelTriggerZ = value;
|
|
DetermineAngularAccelLevelTriggeresMixed();
|
|
}
|
|
}
|
|
|
|
//FB 44625 set the default to NotSet /null
|
|
private bool? _destructiveTest = null;
|
|
|
|
/// <summary>
|
|
/// this is the XML tag that contains all the TSR Air Settings in the xml for a test setup
|
|
/// </summary>
|
|
protected const string TSRAIRSETTINGS_ROOT = "TSRAIR_Settings";
|
|
/// <summary>
|
|
/// reads all TSR Air settings from xml
|
|
/// </summary>
|
|
protected void ReadTSRAirSettings(XmlElement node)
|
|
{
|
|
_bLowgLevelTriggerOn = GetBool(node, "LowgLevelTriggerOn", false);
|
|
_lowgLevelTriggersMixed = GetBool(node, "LowgLevelTriggersMixed", false);
|
|
_bLowgLevelTriggerOnX = GetBool(node, "LowgLevelTriggersMixed", false);
|
|
_bLowgLevelTriggerOnY = GetBool(node, "LowgLevelTriggerOnY", false);
|
|
_bLowgLevelTriggerOnZ = GetBool(node, "LowgLevelTriggerOnZ", false);
|
|
_bHighgLevelTriggerOn = GetBool(node, "HighgLevelTriggerOn", false);
|
|
_bHighgLevelTriggerOnX = GetBool(node, "HighgLevelTriggerOnX", false);
|
|
_bHighgLevelTriggerOnY = GetBool(node, "HighgLevelTriggerOnY", false);
|
|
_bHighgLevelTriggerOnZ = GetBool(node, "HighgLevelTriggerOnZ", false);
|
|
_bAngularAccelLevelTriggerOn = GetBool(node, "AngularAccelLevelTriggerOn", false);
|
|
_bAngularAccelLevelTriggerOnX = GetBool(node, "AngularAccelLevelTriggerOnX", false);
|
|
_bAngularAccelLevelTriggerOnY = GetBool(node, "AngularAccelLevelTriggerOnY", false);
|
|
_bAngularAccelLevelTriggerOnZ = GetBool(node, "AngularAccelLevelTriggerOnZ", false);
|
|
_bAngularRateLevelTriggerOn = GetBool(node, "AngularRateLevelTriggerOn", false);
|
|
_bAngularRateLevelTriggerOnX = GetBool(node, "AngularRateLevelTriggerOnX", false);
|
|
_bAngularRateLevelTriggerOnY = GetBool(node, "AngularRateLevelTriggerOnY", false);
|
|
_bAngularRateLevelTriggerOnZ = GetBool(node, "AngularRateLevelTriggerOnZ", false);
|
|
_lowgLinearLevelTriggerX = GetDouble(node, "LowgLinearLevelTriggerX", 0D);
|
|
_lowgLinearLevelTriggerY = GetDouble(node, "LowgLinearLevelTriggerY", 0D);
|
|
_lowgLinearLevelTriggerZ = GetDouble(node, "LowgLinearLevelTriggerZ", 0D);
|
|
_highgLevelTriggersMixed = GetBool(node, "HighgLevelTriggersMixed", false); ;
|
|
_highgLinearLevelTriggerX = GetDouble(node, "HighgLinearLevelTriggerX", 0D);
|
|
_highgLinearLevelTriggerY = GetDouble(node, "HighgLinearLevelTriggerY", 0D);
|
|
_highgLinearLevelTriggerZ = GetDouble(node, "HighgLinearLevelTriggerZ", 0D);
|
|
_angularAccelLevelTriggersMixed = GetBool(node, "AngularAccelLevelTriggersMixed", false);
|
|
_angularAccelLevelTriggerX = GetDouble(node, "AngularAccelLevelTriggerX", 0D);
|
|
_angularAccelLevelTriggerY = GetDouble(node, "AngularAccelLevelTriggerY", 0D);
|
|
_angularAccelLevelTriggerZ = GetDouble(node, "AngularAccelLevelTriggerZ", 0D);
|
|
_angularRateLevelTriggersMixed = GetBool(node, "AngularRateLevelTriggersMixed", false);
|
|
_angularRateLevelTriggerX = GetDouble(node, "AngularRateLevelTriggerX", 0D);
|
|
_angularRateLevelTriggerY = GetDouble(node, "AngularRateLevelTriggerY", 0D);
|
|
_angularRateLevelTriggerZ = GetDouble(node, "AngularRateLevelTriggerZ", 0D);
|
|
_humidityLevelTriggerOn = GetBool(node, "HumidityLevelTriggerOn", false);
|
|
_pressureLevelTriggerOn = GetBool(node, "PressureLevelTriggerOn", false);
|
|
_temperatureLevelTriggerOn = GetBool(node, "TemperatureLevelTriggerOn", false);
|
|
_humidityLevelTriggerBelow = GetDouble(node, "HumidityLevelTriggerBelow", 0D);
|
|
_humidityLevelTriggerAbove = GetDouble(node, "HumidityLevelTriggerAbove", 0D);
|
|
_pressureLevelTriggerBelow = GetDouble(node, "PressureLevelTriggerBelow", 0D);
|
|
_pressureLevelTriggerAbove = GetDouble(node, "PressureLevelTriggerAbove", 0D);
|
|
_temperatureLevelTriggerBelow = GetDouble(node, "TemperatureLevelTriggerBelow", 0D);
|
|
_temperatureLevelTriggerAbove = GetDouble(node, "TemperatureLevelTriggerAbove", 0D);
|
|
_lowgLinearAccRate = GetDouble(node, "LowgLinearAccRate", 0D);
|
|
_highgLinearAccRate = GetDouble(node, "HighgLinearAccRate", 0D);
|
|
_angularRate = GetDouble(node, "AngularRate", 0D);
|
|
_temperatureHumidityPressureRate = GetDouble(node, "TemperatureHumidityPressureRate", 0D);
|
|
_batterySaverModeOn = GetBool(node, "BatterySaverModeOn", false);
|
|
_wakeUpAndArmTriggerOn = GetBool(node, "WakeUpAndArmTriggerOn", false);
|
|
_wakeUpMotionTimeout = GetInt(node, "WakeUpMotionTimeout", 0);
|
|
_wakeUpMagnetTimeout = GetInt(node, "WakeUpMagnetTimeout", 0);
|
|
_wakeUpTimeSessionStart = GetDateTime(node, "WakeUpTimeSessionStart", DateTime.Now);
|
|
_wakeUpTimeDuration = GetTimeSpan(node, "WakeUpTimeDuration", TimeSpan.Zero);
|
|
|
|
if (node.HasAttribute("WakeUpTrigger"))
|
|
{
|
|
var attr = node.GetAttribute("WakeUpTrigger");
|
|
if (Enum.TryParse(attr, out WakeupTriggers trigger))
|
|
{
|
|
WakeUpTrigger = trigger;
|
|
}
|
|
else { _wakeUpTrigger = WakeupTriggers.MotionDetect; }
|
|
}
|
|
else { _wakeUpTrigger = WakeupTriggers.MotionDetect; }
|
|
|
|
_timedIntervalTriggerOn = GetBool(node, "TimedIntervalTriggerOn", false);
|
|
_timedIntervalDuration = GetDouble(node, "TimedIntervalDuration", 0D);
|
|
_timedIntervalEvents = GetDouble(node, "TimedIntervalEvents", 0D);
|
|
_intervalBetweenEventStartsMinutes = GetInt(node, "IntervalBetweenEventStartsMinutes", 0);
|
|
if (node.HasAttribute("TimedIntervalUnits"))
|
|
{
|
|
var attr = node.GetAttribute("TimedIntervalUnits");
|
|
if (Enum.TryParse(attr, out TimeUnitTypeEnum units))
|
|
{
|
|
TimedIntervalUnits = units;
|
|
}
|
|
else { _timedIntervalUnits = TimeUnitTypeEnum.MS; }
|
|
}
|
|
else { _timedIntervalUnits = TimeUnitTypeEnum.MS; }
|
|
|
|
_rtcScheduleTriggerOn = GetBool(node, "RTCScheduleTriggerOn", false);
|
|
_rtcScheduleStartDateTime = GetDateTime(node, "RTCScheduleDateTime", DateTime.Now);
|
|
_rtcScheduleDuration = GetTimeSpan(node, "RTCScheduleDuration", TimeSpan.Zero);
|
|
_startWithEvent = GetBool(node, "StartWithEvent", false);
|
|
}
|
|
/// <summary>
|
|
/// reads an attribute bool from xml if found, otherwise returns with default value
|
|
/// </sumarry>
|
|
private bool GetBool(XmlElement node, string attribute, bool defaultValue)
|
|
{
|
|
if (!node.HasAttribute(attribute)) { return defaultValue; }
|
|
var attr = node.GetAttribute(attribute);
|
|
if (bool.TryParse(attr, out var b))
|
|
{
|
|
return b;
|
|
}
|
|
return defaultValue;
|
|
}
|
|
/// <summary>
|
|
/// reads an attribute double from xml if found, otherwise returns with default value
|
|
/// </summary>
|
|
private double GetDouble(XmlElement node, string attribute, double defaultValue)
|
|
{
|
|
if (!node.HasAttribute(attribute)) { return defaultValue; }
|
|
var attr = node.GetAttribute(attribute);
|
|
if (double.TryParse(attr, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var d))
|
|
{
|
|
return d;
|
|
}
|
|
return defaultValue;
|
|
}
|
|
/// <summary>
|
|
/// reads an attribute double from xml if found, otherwise returns with default value
|
|
/// </summary>
|
|
private int GetInt(XmlElement node, string attribute, int defaultValue)
|
|
{
|
|
if (!node.HasAttribute(attribute)) { return defaultValue; }
|
|
var attr = node.GetAttribute(attribute);
|
|
if (int.TryParse(attr, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var d))
|
|
{
|
|
return d;
|
|
}
|
|
return defaultValue;
|
|
}
|
|
/// <summary>
|
|
/// reads an attribute datetime from xml if found, otherwise returns with default value
|
|
/// </summary>
|
|
private DateTime GetDateTime(XmlElement node, string attribute, DateTime defaultValue)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(attribute) || !node.HasAttribute(attribute)) { return defaultValue; }
|
|
var attr = node.GetAttribute(attribute);
|
|
if (DateTime.TryParse(attr, out var d))
|
|
{
|
|
return d;
|
|
}
|
|
return defaultValue;
|
|
}
|
|
/// <summary>
|
|
/// reads an attribute timespan from xml if found, otherwise returns with default value
|
|
/// </summary>
|
|
private TimeSpan GetTimeSpan(XmlElement node, string attribute, TimeSpan defaultValue)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(attribute) || !node.HasAttribute(attribute)) { return defaultValue; }
|
|
var attr = node.GetAttribute(attribute);
|
|
if (TimeSpan.TryParse(attr, out var t))
|
|
{
|
|
return t;
|
|
}
|
|
return defaultValue;
|
|
}
|
|
/// <summary>
|
|
/// Writes all TSRAir settings to xml
|
|
/// </summary>
|
|
protected void WriteTSRAirSettings(ref XmlWriter writer)
|
|
{
|
|
writer.WriteStartElement(TSRAIRSETTINGS_ROOT);
|
|
var inv = System.Globalization.CultureInfo.InvariantCulture;
|
|
writer.WriteAttributeString("BatterySaverModeOn", BatterySaverModeOn.ToString());
|
|
writer.WriteAttributeString("WakeUpAndArmTriggerOn", WakeUpAndArmTriggerOn.ToString());
|
|
writer.WriteAttributeString("WakeUpTrigger", WakeUpTrigger.ToString());
|
|
writer.WriteAttributeString("WakeUpMotionTimeout", WakeUpMotionTimeout.ToString());
|
|
writer.WriteAttributeString("WakeUpMagnetTimeout", WakeUpMagnetTimeout.ToString());
|
|
writer.WriteAttributeString("WakeUpTimeSessionStart", WakeUpTimeSessionStart.ToString());
|
|
writer.WriteAttributeString("WakeUpTimeDuration", WakeUpTimeDuration.ToString());
|
|
writer.WriteAttributeString("TimedIntervalTriggerOn", TimedIntervalTriggerOn.ToString());
|
|
writer.WriteAttributeString("TimedIntervalDuration", TimedIntervalDuration.ToString(inv));
|
|
writer.WriteAttributeString("TimedIntervalEvents", TimedIntervalEvents.ToString(inv));
|
|
writer.WriteAttributeString("IntervalBetweenEventStartsMinutes", IntervalBetweenEventStartsMinutes.ToString(inv));
|
|
writer.WriteAttributeString("TimedIntervalUnits", TimedIntervalUnits.ToString());
|
|
writer.WriteAttributeString("RTCScheduleTriggerOn", RTCScheduleTriggerOn.ToString());
|
|
writer.WriteAttributeString("RTCScheduleStartDateTime", RTCScheduleStartDateTime.ToString(inv));
|
|
writer.WriteAttributeString("RTCScheduleDuration", RTCScheduleDuration.ToString());
|
|
writer.WriteAttributeString("StartWithEvent", StartWithEvent.ToString());
|
|
writer.WriteEndElement();
|
|
}
|
|
/// <summary>
|
|
/// the copy constructor is already pretty long, so I split the TSRAir relevant settings
|
|
/// out into it's own copyconstructor method
|
|
/// </summary>
|
|
protected void CopyTSRAirSettings(ITestTemplate setup)
|
|
{
|
|
_batterySaverModeOn = setup.BatterySaverModeOn;
|
|
_wakeUpAndArmTriggerOn = setup.WakeUpAndArmTriggerOn;
|
|
_wakeUpTrigger = setup.WakeUpTrigger;
|
|
_wakeUpMotionTimeout = setup.WakeUpMotionTimeout;
|
|
_wakeUpMagnetTimeout = setup.WakeUpMagnetTimeout;
|
|
_wakeUpTimeSessionStart = setup.WakeUpTimeSessionStart;
|
|
_wakeUpTimeDuration = setup.WakeUpTimeDuration;
|
|
_timedIntervalTriggerOn = setup.TimedIntervalTriggerOn;
|
|
_timedIntervalDuration = setup.TimedIntervalDuration;
|
|
_timedIntervalEvents = setup.TimedIntervalEvents;
|
|
_intervalBetweenEventStartsMinutes = setup.IntervalBetweenEventStartsMinutes;
|
|
_timedIntervalUnits = setup.TimedIntervalUnits;
|
|
_rtcScheduleTriggerOn = setup.RTCScheduleTriggerOn;
|
|
_rtcScheduleStartDateTime = setup.RTCScheduleStartDateTime;
|
|
_rtcScheduleDuration = setup.RTCScheduleDuration;
|
|
_startWithEvent = setup.StartWithEvent;
|
|
}
|
|
/// <summary>
|
|
/// property used to indicate that the test is destructive or impact and should set the first use date
|
|
/// of any relevant sensors or DAS
|
|
/// 15524 DAS "First Use Date"
|
|
/// note: this property is not serialized with the test setup, it's a run-time set property when
|
|
/// running the test
|
|
/// </summary>
|
|
public bool? DestructiveTest
|
|
{
|
|
get => _destructiveTest;
|
|
set => SetProperty(ref _destructiveTest, value, "DestructiveTest");
|
|
}
|
|
|
|
/// <summary>
|
|
/// returns true whenever the test template is a quick test setup, false otherwise
|
|
/// </summary>
|
|
public bool QuickSensorCheck { get; set; }
|
|
|
|
public const string NON_ISO_INTERNAL_GROUP_NAME = "[NONE]";
|
|
protected const int MAX_REALTIME_CHANNELS = 6;
|
|
protected const int MAX_ERRORS_TO_DISPLAY = 5;
|
|
|
|
protected static readonly object ChannelLookupLock = new object();
|
|
protected static readonly object CountLock = new object();
|
|
|
|
private string _setupFile = string.Empty;
|
|
public string SetupFile
|
|
{
|
|
get => _setupFile;
|
|
set => SetProperty(ref _setupFile, value, "SetupFile");
|
|
}
|
|
|
|
protected string _id = "";
|
|
public string TestId
|
|
{
|
|
get => _id;
|
|
set
|
|
{
|
|
SetProperty(ref _id, value, TestTemplateTags.TestId.ToString());
|
|
var directory = System.IO.Path.GetFullPath(System.IO.Path.Combine(Environment.CurrentDirectory, DownloadFolder, Name.Trim()));
|
|
try
|
|
{
|
|
directory = System.IO.Path.Combine(directory, value);
|
|
TestDirectory = directory;
|
|
|
|
TestIdNode = GetTestIdNode();
|
|
}
|
|
catch
|
|
{
|
|
//Validation will fail later
|
|
}
|
|
}
|
|
}
|
|
public List<Interface.DownloadEvent.IDownloadEvent> EventsToDownload { get; set; }
|
|
public string TestIdNode { get; set; } = string.Empty;
|
|
|
|
private string _testDirectory;
|
|
public string TestDirectory
|
|
{
|
|
get => _testDirectory;
|
|
set => SetProperty(ref _testDirectory, value, TestTemplateTags.TestDirectory.ToString());
|
|
}
|
|
private string _originalTestDirectory;
|
|
public string OriginalTestDirectory
|
|
{
|
|
get => _originalTestDirectory;
|
|
set => SetProperty(ref _originalTestDirectory, value, TestTemplateTags.OriginalTestDirectory.ToString());
|
|
}
|
|
public new double SamplesPerSecondAggregate
|
|
{
|
|
get => base.SamplesPerSecondAggregate;
|
|
set
|
|
{
|
|
base.SamplesPerSecondAggregate = value;
|
|
OnPropertyChanged("SamplesPerSecond");
|
|
OnPropertyChanged(TestTemplateTags.SampleRateText.ToString());
|
|
}
|
|
}
|
|
|
|
|
|
public new RecordingModes RecordingMode
|
|
{
|
|
get => base.RecordingMode;
|
|
set
|
|
{
|
|
if (value != RecordingMode)
|
|
{
|
|
base.RecordingMode = value;
|
|
OnPropertyChanged(TestTemplateTags.RecordingModeText.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
// FB15323: Restrict Sample Rates when in UART recording modes
|
|
public bool UARTRecordingMode => RecordingModeExtensions.IsAUartMode(RecordingMode);
|
|
|
|
protected List<string> _checkedDASList = new List<string>();
|
|
public List<string> CheckedDASList
|
|
{
|
|
get => _checkedDASList;
|
|
set => _checkedDASList = value;
|
|
}
|
|
private bool _groupsStepValid;
|
|
public bool GroupsStepValid
|
|
{
|
|
get => _groupsStepValid;
|
|
set => SetProperty(ref _groupsStepValid, value, TestTemplateTags.GroupsStepValid.ToString());
|
|
}
|
|
public ObservableCollection<IGroup> Groups { get; set; } = new ObservableCollection<IGroup>();
|
|
//assumes list is in order and sets display orders accordingly
|
|
public void SetGroupsListOrder()
|
|
{
|
|
Groups.OrderBy(g => g.DisplayOrder);
|
|
if (Groups.Where(g => g.DisplayOrder == -1).Any())
|
|
{
|
|
//Some need to be ordered
|
|
var newDisplayOrder = 1; //If all are -1, start with 1
|
|
if (Groups.Where(g => g.DisplayOrder > -1).Any())
|
|
{
|
|
//Some don't need to be ordered, but don't stomp on their DisplayOrders
|
|
var startingMinDisplayOrder = Groups.Where(g => g.DisplayOrder > -1).Min(g => g.DisplayOrder);
|
|
newDisplayOrder = Groups.Where(g => g.DisplayOrder > -1).Max(g => g.DisplayOrder) + 1;
|
|
foreach (var group in Groups)
|
|
{
|
|
if (group.DisplayOrder == startingMinDisplayOrder)
|
|
{
|
|
//We've handled all of the -1s, so we're done
|
|
break;
|
|
}
|
|
group.DisplayOrder = newDisplayOrder;
|
|
newDisplayOrder++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var group in Groups)
|
|
{
|
|
group.DisplayOrder = newDisplayOrder;
|
|
newDisplayOrder++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected List<IGroup> _groups = new List<IGroup>();
|
|
|
|
|
|
public new BindingList<IRegionOfInterest> RegionsOfInterest
|
|
{
|
|
get => base.RegionsOfInterest;
|
|
set
|
|
{
|
|
if (null != value)
|
|
{
|
|
_regionsOfInterest.ListChanged -= _roi_ListChanged;
|
|
base.RegionsOfInterest = value;
|
|
_regionsOfInterest.ListChanged += _roi_ListChanged;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Visibility ViewExportButtonVisibility => ViewExport ? Visibility.Visible : Visibility.Collapsed;
|
|
|
|
|
|
|
|
|
|
protected string _downloadFolder;
|
|
public string DownloadFolder
|
|
{
|
|
get => _downloadFolder;
|
|
set => SetProperty(ref _downloadFolder, value, TestTemplateTags.DownloadFolder.ToString());
|
|
}
|
|
|
|
protected string _exportFolder;
|
|
public string ExportFolder
|
|
{
|
|
get => _exportFolder;
|
|
set => SetProperty(ref _exportFolder, value, TestTemplateTags.ExportFolder.ToString());
|
|
}
|
|
|
|
|
|
|
|
private DateTime _testTime = DateTime.Now;
|
|
public DateTime TestTime
|
|
{
|
|
get => _testTime;
|
|
set => SetProperty(ref _testTime, value, TestTemplateTags.TestTime.ToString());
|
|
}
|
|
/// <summary>
|
|
/// allows current test setup to be notified of ROI changes
|
|
/// this was necessary as Test setup was not notifying on changes itself
|
|
/// 27034 ROI channel assignments are not saved when modifying and clicking save in test setup
|
|
/// </summary>
|
|
public void NotifyROIChanged()
|
|
{
|
|
OnPropertyChanged(TestTemplateTags.RegionsOfInterest.ToString());
|
|
}
|
|
private void _roi_ListChanged(object sender, ListChangedEventArgs e)
|
|
{
|
|
NotifyROIChanged();
|
|
}
|
|
|
|
protected string _defaultDownloadFolder;
|
|
public string GetTestIdNode()
|
|
{
|
|
var downloadFolder = System.IO.Path.Combine(Environment.CurrentDirectory, _defaultDownloadFolder);
|
|
var testIdNode = TestId;
|
|
var binaryDirectory = System.IO.Path.Combine(downloadFolder, Name, testIdNode, "Binary");
|
|
if (!System.IO.Directory.Exists(binaryDirectory)) return TestId;
|
|
var recoveryFileCounter = 0;
|
|
while (System.IO.Directory.Exists(binaryDirectory))
|
|
{
|
|
recoveryFileCounter++;
|
|
testIdNode = TestId + "-" + Strings.Strings.Download_Recovery + recoveryFileCounter;
|
|
//18430 Recovery download replaces previous download using download data tab.
|
|
//the check here had included the actual binary directory, however
|
|
//sometimes the test directory exists without the binary directory, but we still need to increment the recovery file counter
|
|
//this is the case when you use the download tile to download roi but not the all dataset
|
|
binaryDirectory = System.IO.Path.Combine(downloadFolder, Name, testIdNode);
|
|
}
|
|
return TestId + "-" + Strings.Strings.Download_Recovery + recoveryFileCounter;
|
|
}
|
|
/// <summary>
|
|
/// This function takes an embedded GroupChannel and returns a string that
|
|
/// is analogous to a non-embedded channel.Hardware.
|
|
/// The returned format is "[<embedded module>] CH-xx".
|
|
/// </summary>
|
|
/// <param name="channel"></param>
|
|
/// <returns></returns>
|
|
public static string GetEmbeddedChannelHardware(IGroupChannel channel)
|
|
{
|
|
var hardwareChannel = string.Empty;
|
|
|
|
if (channel.HardwareChannel != null)
|
|
{
|
|
if (channel.HardwareChannel.IsTSRAIR && !string.IsNullOrWhiteSpace(channel.Hardware))
|
|
{
|
|
var moduleName = channel.HardwareChannel.ModuleSerialNumber;
|
|
var hardwareCh = channel.Hardware.Remove(0, moduleName.Length + 1);
|
|
hardwareChannel = $"[{moduleName}] {hardwareCh}";
|
|
}
|
|
else
|
|
{
|
|
//Must be a Voltage input, so return channel.Hardware
|
|
if (channel.Hardware != null)
|
|
{
|
|
hardwareChannel = channel.Hardware;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hardwareChannel;
|
|
}
|
|
}
|
|
public enum TestTemplateTags
|
|
{
|
|
UploadData,
|
|
UploadExportsOnly,
|
|
UploadFolder,
|
|
CommonLine,
|
|
AllCustomers,
|
|
AllTestEngineers,
|
|
AllLabs,
|
|
Test,
|
|
AllowMissingSensors,
|
|
AllowSensorIdToBlankChannel,
|
|
AutomaticProgression,
|
|
AutomaticProgressionDelayMS,
|
|
InvertTriggerCompletion,
|
|
TriggerCheckStep,
|
|
PostTestDiagnostics,
|
|
TriggerCheckRealtime,
|
|
InvertStartRecordCompletion,
|
|
ViewDiagnostics,
|
|
VerifyChannels,
|
|
AutoVerifyProgress,
|
|
AutoVerifyDelaySeconds,
|
|
TestGraphs,
|
|
GraphCount,
|
|
Name,
|
|
TestId,
|
|
SetupFile,
|
|
Description,
|
|
AvailableTestObjects,
|
|
SamplesPerSecond,
|
|
SampleRateText,
|
|
IntervalBetweenEventStartsMinutes,
|
|
PreTriggerSeconds,
|
|
PostTriggerSeconds,
|
|
RecordingMode,
|
|
RecordingModeText,
|
|
StrictDiagnostics,
|
|
TestObjects,
|
|
AllTestObjects,
|
|
SysBuiltTestObjects,
|
|
RequireUserConfirmationOnErrors,
|
|
DoROIDownload,
|
|
ROIButtonVisibility,
|
|
ViewROIDownload,
|
|
ViewROIDownloadButtonVisibility,
|
|
DownloadAll,
|
|
DownloadAllButtonVisibility,
|
|
ViewRealtime,
|
|
ViewRealtimeButtonVisibility,
|
|
RegionsOfInterest,
|
|
ROIStart,
|
|
ROIEnd,
|
|
ViewDownloadAll,
|
|
ViewDownloadAllButtonVisibility,
|
|
ViewExport,
|
|
ViewExportButtonVisibility,
|
|
ExportFormats,
|
|
DownloadFolder,
|
|
ExportFolder,
|
|
SameAsDownloadFolder,
|
|
TestTime,
|
|
LabDetails,
|
|
CustomerDetails,
|
|
TestEngineerDetails,
|
|
DefaultNumberRealtimeGraphs,
|
|
GraphDetailsVisibility,
|
|
CurrentGraph,
|
|
UseCustomerDetails,
|
|
UseTestEngineerDetails,
|
|
TurnOffExcitation,
|
|
UseLabratoryDetails,
|
|
TestDirectory,
|
|
OriginalTestDirectory,
|
|
LocalOnly,
|
|
LastModified,
|
|
LastMmodifiedBy,
|
|
ExpressTestSetup,
|
|
EW,
|
|
ExcitationWarmupTimeMS,
|
|
ArmCheckListStep,
|
|
CheckListBatteryVoltageCheck,
|
|
CheckListInputVoltageCheck,
|
|
CheckListSquibResistanceCheck,
|
|
CheckListSensorIDCheck,
|
|
CheckListTriggerStartCheck,
|
|
CheckListMustPass,
|
|
WarnOnFailedBattery,
|
|
HardwareOverrides,
|
|
DoAutoArm,
|
|
DoStreaming,
|
|
WakeUpWithMotion,
|
|
SysBuiltTestObjectTypes,
|
|
AddedGroupRemoved,
|
|
CheckoutMode,
|
|
QuitTestWithoutWarning,
|
|
SuppressMissingSensorsWarning,
|
|
ISFFile,
|
|
TestObjectsAndAddedGroups,
|
|
NotAllChannelsRealTime,
|
|
NotAllChannelsViewer,
|
|
GroupsStepValid,
|
|
CalibrationBehavior,
|
|
ClockSyncProfileMaster,
|
|
ClockSyncProfileSlave,
|
|
ExtraProperties,
|
|
MeasureSquibResistancesStep,
|
|
NumberOfEvents
|
|
}
|
|
}
|