486 lines
16 KiB
C#
486 lines
16 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.ComponentModel;
|
|||
|
|
using System.Windows;
|
|||
|
|
using DTS.Common.Interface.DataRecorders;
|
|||
|
|
using DTS.Common.Interface.TestSetups.Imports.TTS.ReadFile;
|
|||
|
|
using DTS.Common.Enums;
|
|||
|
|
|
|||
|
|
namespace TTSImport.Model
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// this class represents a hardware channel + some additional meta information (mostly the TTSChannelRecord or sensor that might be assigned)
|
|||
|
|
/// It's currently for use in AnalogChannelsViewModel
|
|||
|
|
/// </summary>
|
|||
|
|
public class DASChannel : DependencyObject, INotifyPropertyChanged
|
|||
|
|
{
|
|||
|
|
#region INotifyPropertyChanged
|
|||
|
|
|
|||
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|||
|
|
|
|||
|
|
public bool SetProperty<T>(ref T storage, T value, string propertyName = null)
|
|||
|
|
{
|
|||
|
|
if (Equals(storage, value)) return false;
|
|||
|
|
|
|||
|
|
storage = value;
|
|||
|
|
OnPropertyChanged(propertyName);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void OnPropertyChanged(string propertyName = null)
|
|||
|
|
{
|
|||
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region enums and constants
|
|||
|
|
|
|||
|
|
public const string POSITIVE = "+";
|
|||
|
|
public const string NEGATIVE = "-";
|
|||
|
|
public IEnumerable<string> Polarities => new[] { POSITIVE, NEGATIVE };
|
|||
|
|
public IEnumerable<SquibFireMode> SquibFireModes => new[]
|
|||
|
|
{
|
|||
|
|
SquibFireMode.CAP, SquibFireMode.CONSTANT
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
public IEnumerable<DigitalOutputModes> OutputModes => new[]
|
|||
|
|
{
|
|||
|
|
DigitalOutputModes.NONE,
|
|||
|
|
DigitalOutputModes.CCNO,
|
|||
|
|
DigitalOutputModes.CCNC,
|
|||
|
|
DigitalOutputModes.FVHL,
|
|||
|
|
DigitalOutputModes.FVLH
|
|||
|
|
};
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region constructors and initializers
|
|||
|
|
|
|||
|
|
public DASChannel(IHardwareChannel channel)
|
|||
|
|
{
|
|||
|
|
HardwareChannel = channel;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public DASChannel(IHardwareChannel channel, ITTSSetup setup)
|
|||
|
|
{
|
|||
|
|
HardwareChannel = channel;
|
|||
|
|
TestSetup = setup;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public ITTSSetup TestSetup { get; }
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region properties
|
|||
|
|
/// <summary>
|
|||
|
|
/// the digital output mode (if relevant)
|
|||
|
|
/// </summary>
|
|||
|
|
public DigitalOutputModes DigitalOutputMode
|
|||
|
|
{
|
|||
|
|
get => Channel?.DigitalOutputMode ?? DigitalOutputModes.NONE;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (Channel.DigitalOutputMode == value) return;
|
|||
|
|
if (Channel.DigitalOutputMode == DigitalOutputModes.NONE)
|
|||
|
|
{
|
|||
|
|
//Add to the Test Setup
|
|||
|
|
AddDigitalOutputChannel();
|
|||
|
|
}
|
|||
|
|
else if (value == DigitalOutputModes.NONE)
|
|||
|
|
{
|
|||
|
|
//Remove from the Test Setup
|
|||
|
|
RemoveDigitalOutputChannel();
|
|||
|
|
}
|
|||
|
|
Channel.DigitalOutputMode = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
OnPropertyChanged("IsActive");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the delay between trigger and output (if relevant)
|
|||
|
|
/// </summary>
|
|||
|
|
public double DigitalOutputDelayMs
|
|||
|
|
{
|
|||
|
|
get => Channel?.DigitalOutputDelay ?? 0D;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.DigitalOutputDelay = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the duration of output after output started (if relevant)
|
|||
|
|
/// </summary>
|
|||
|
|
public double DigitalOutputDurationMs
|
|||
|
|
{
|
|||
|
|
get => Channel?.DigitalOutputDuration ?? 100D;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.DigitalOutputDuration = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the polarity of the sensor associated with this hardware channel (if any)
|
|||
|
|
/// </summary>
|
|||
|
|
public string Polarity
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
return Channel.SensorPolarity ? POSITIVE : NEGATIVE;
|
|||
|
|
}
|
|||
|
|
return POSITIVE;
|
|||
|
|
}
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.SensorPolarity = value == POSITIVE;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public SquibFireMode SquibFireMode
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
return Channel.SquibFireMode;
|
|||
|
|
}
|
|||
|
|
return SquibFireMode.CAP;
|
|||
|
|
}
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.SquibFireMode = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// whether this channel should be considered disabled or not
|
|||
|
|
/// disabled channels will exist in the test setup but won't be used during run test
|
|||
|
|
/// </summary>
|
|||
|
|
public bool Disabled
|
|||
|
|
{
|
|||
|
|
get => (bool)GetValue(DisabledProperty);
|
|||
|
|
set => SetValue(DisabledProperty, value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// this is the Toyota channel record associated with the hardware channel
|
|||
|
|
/// can be null if there's no sensor associated
|
|||
|
|
/// </summary>
|
|||
|
|
public ITTSChannelRecord Channel { get; private set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// a string representation of the hardware channel (eg [SPS00001] ch 13)
|
|||
|
|
/// </summary>
|
|||
|
|
public string DASChannelString => HardwareChannel?.ToString() ?? "";
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the Channel code associated with the physical hardware channel (if any)
|
|||
|
|
/// </summary>
|
|||
|
|
public string ToyotaCode
|
|||
|
|
{
|
|||
|
|
get => Channel?.ChannelCode ?? "";
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.ChannelCode = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the electronic id on the physical channel (if any)
|
|||
|
|
/// </summary>
|
|||
|
|
public string EID { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the "name" of the channel, if any (is blank if no TTSRecord associated with this channel)
|
|||
|
|
/// </summary>
|
|||
|
|
public string Name
|
|||
|
|
{
|
|||
|
|
get => Channel?.JCodeOrDescription ?? "";
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.JCodeOrDescription = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the serial number for a sensor on this channel (if any)
|
|||
|
|
/// </summary>
|
|||
|
|
public string SerialNumber => Channel?.SensorSerialNumber ?? "";
|
|||
|
|
|
|||
|
|
public string SensitivityString => Sensitivity.ToString("N12");
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the sensitivity of the sensor on this channel (if any)
|
|||
|
|
/// </summary>
|
|||
|
|
public double Sensitivity => Channel?.SensorSensitivity ?? 0D;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// true as long as there is a TTS record associated with this physical channel
|
|||
|
|
/// </summary>
|
|||
|
|
public bool IsActive
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
if (null == Channel) return false;
|
|||
|
|
if (null != Channel.HardwareChannel && Channel.HardwareChannel.IsDigitalOut)
|
|||
|
|
{
|
|||
|
|
return Channel.DigitalOutputMode != DigitalOutputModes.NONE;
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the capacity of the sensor associated with this physical channel (if any)
|
|||
|
|
/// </summary>
|
|||
|
|
public double Capacity => Channel?.SensorCapacity ?? 0D;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the range of the sensor associated with this physical channel (if any)
|
|||
|
|
/// </summary>
|
|||
|
|
public double Range
|
|||
|
|
{
|
|||
|
|
get => Channel?.ChannelRange ?? 0D;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.ChannelRange = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public double CableMultiplier
|
|||
|
|
{
|
|||
|
|
get => Channel?.CableMultiplier ?? 1D;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.CableMultiplier = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// the delay in ms between trigger and squib fire
|
|||
|
|
/// </summary>
|
|||
|
|
public double SquibFireDelayMs
|
|||
|
|
{
|
|||
|
|
get => Channel?.SquibFireDelayMs ?? 0D;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.SquibFireDelayMs = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the limit for current (amps)
|
|||
|
|
/// </summary>
|
|||
|
|
public double SquibFireCurrent
|
|||
|
|
{
|
|||
|
|
get => Channel?.SquibFireCurrent ?? 0D;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.SquibFireCurrent = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// whether to limit the duration or not of squib fire
|
|||
|
|
/// </summary>
|
|||
|
|
public bool LimitDuration
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
if (null == Channel) { return false; }
|
|||
|
|
if (Channel.IsDigitalOutput && Channel.DigitalOutputMode == DigitalOutputModes.NONE) { return false; }
|
|||
|
|
return Channel.LimitDuration;
|
|||
|
|
}
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.LimitDuration = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
OnPropertyChanged("LimitDuration");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the duration of the squib fire in ms from the start of firing
|
|||
|
|
/// (if limiting duration)
|
|||
|
|
/// </summary>
|
|||
|
|
public double SquibFireDurationMs
|
|||
|
|
{
|
|||
|
|
get => Channel?.SquibFireDurationMs ?? .20D;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.SquibFireDurationMs = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the squib resistance tolerance low value (ohms)
|
|||
|
|
/// </summary>
|
|||
|
|
public double SquibFireResistanceLowOhm
|
|||
|
|
{
|
|||
|
|
get => Channel?.SquibFireResistanceLowOhm ?? 1D;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.SquibFireResistanceLowOhm = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the squib resistance tolerance high value (ohms)
|
|||
|
|
/// </summary>
|
|||
|
|
public double SquibFireResistanceHighOhm
|
|||
|
|
{
|
|||
|
|
get => Channel?.SquibFireResistanceHighOhm ?? 8D;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.SquibFireResistanceHighOhm = value;
|
|||
|
|
Channel.IsModified = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// this is the hardware channel we are wrapping
|
|||
|
|
/// </summary>
|
|||
|
|
public IHardwareChannel HardwareChannel { get; }
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region dependency properties
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// the disabled property allows controls to make use of Disabled in styles, allow us to have a specific style for when a DASChannel is disabled
|
|||
|
|
/// </summary>
|
|||
|
|
public static readonly DependencyProperty DisabledProperty =
|
|||
|
|
DependencyProperty.Register("Disabled", typeof(bool), typeof(DASChannel), new PropertyMetadata(false));
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region methods
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Assigns this hardware to that TTSChannelRecord, or that channel record to this physical hardware
|
|||
|
|
/// [depending on the POV]
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="channel">the channel being assigned (can be null if removing a sensor from a physical channel)</param>
|
|||
|
|
public void SetITTSChannelRecord(ITTSChannelRecord channel)
|
|||
|
|
{
|
|||
|
|
//if we are assigning something to this DASChannel, then any existing sensor
|
|||
|
|
//record on this channel is no longer on it, so unassign the hardwareassignment to existing
|
|||
|
|
if (null != Channel)
|
|||
|
|
{
|
|||
|
|
Channel.HardwareChannel = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Channel = channel;
|
|||
|
|
//now assign the hardware channel on the channelrecord to this hardware channel
|
|||
|
|
if (null != channel)
|
|||
|
|
{
|
|||
|
|
channel.HardwareChannel = HardwareChannel;
|
|||
|
|
}
|
|||
|
|
//clean up the ui
|
|||
|
|
OnPropertyChanged("ToyotaCode");
|
|||
|
|
OnPropertyChanged("EID");
|
|||
|
|
OnPropertyChanged("Name");
|
|||
|
|
OnPropertyChanged("SerialNumber");
|
|||
|
|
OnPropertyChanged("SensitivityString");
|
|||
|
|
OnPropertyChanged("IsActive");
|
|||
|
|
OnPropertyChanged("Capacity");
|
|||
|
|
OnPropertyChanged("Range");
|
|||
|
|
OnPropertyChanged("Polarity");
|
|||
|
|
OnPropertyChanged("CableMultiplier");
|
|||
|
|
OnPropertyChanged("SquibFireDelayMs");
|
|||
|
|
OnPropertyChanged("SquibFireCurrent");
|
|||
|
|
OnPropertyChanged("LimitDuration");
|
|||
|
|
OnPropertyChanged("SquibFireDurationMs");
|
|||
|
|
OnPropertyChanged("SquibFireResistanceLowOhm");
|
|||
|
|
OnPropertyChanged("SquibFireResistanceHighOhm");
|
|||
|
|
OnPropertyChanged("InputMode");
|
|||
|
|
OnPropertyChanged("OutputMode");
|
|||
|
|
OnPropertyChanged("DigitalOutputDelayMs");
|
|||
|
|
OnPropertyChanged("DigitalOutputDurationMs");
|
|||
|
|
Disabled = channel?.Disabled ?? false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Adds a Digital Output channel to the Test Setup when DigitalOutputMode
|
|||
|
|
/// changes from None to something other than None.
|
|||
|
|
/// </summary>
|
|||
|
|
private void AddDigitalOutputChannel()
|
|||
|
|
{
|
|||
|
|
var newChannels = new List<ITTSChannelRecord>(TestSetup.Channels);
|
|||
|
|
newChannels.Add(Channel);
|
|||
|
|
TestSetup.Channels = newChannels.ToArray();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Removes a Digital Output channel from the Test Setup when DigitalOutputMode
|
|||
|
|
/// changes to None.
|
|||
|
|
/// </summary>
|
|||
|
|
private void RemoveDigitalOutputChannel()
|
|||
|
|
{
|
|||
|
|
var newChannels = new List<ITTSChannelRecord>();
|
|||
|
|
foreach (var channel in TestSetup.Channels)
|
|||
|
|
{
|
|||
|
|
if (channel.HardwareChannel != Channel.HardwareChannel)
|
|||
|
|
{
|
|||
|
|
newChannels.Add(channel);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
TestSetup.Channels = newChannels.ToArray();
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
}
|