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 { /// /// 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 /// public class DASChannel : DependencyObject, INotifyPropertyChanged { #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; public bool SetProperty(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 Polarities => new[] { POSITIVE, NEGATIVE }; public IEnumerable SquibFireModes => new[] { SquibFireMode.CAP, SquibFireMode.CONSTANT }; public IEnumerable 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 /// /// the digital output mode (if relevant) /// 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"); } } /// /// the delay between trigger and output (if relevant) /// public double DigitalOutputDelayMs { get => Channel?.DigitalOutputDelay ?? 0D; set { if (null != Channel) { Channel.DigitalOutputDelay = value; Channel.IsModified = true; } } } /// /// the duration of output after output started (if relevant) /// public double DigitalOutputDurationMs { get => Channel?.DigitalOutputDuration ?? 100D; set { if (null != Channel) { Channel.DigitalOutputDuration = value; Channel.IsModified = true; } } } /// /// the polarity of the sensor associated with this hardware channel (if any) /// 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; } } } /// /// 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 /// public bool Disabled { get => (bool)GetValue(DisabledProperty); set => SetValue(DisabledProperty, value); } /// /// this is the Toyota channel record associated with the hardware channel /// can be null if there's no sensor associated /// public ITTSChannelRecord Channel { get; private set; } /// /// a string representation of the hardware channel (eg [SPS00001] ch 13) /// public string DASChannelString => HardwareChannel?.ToString() ?? ""; /// /// the Channel code associated with the physical hardware channel (if any) /// public string ToyotaCode { get => Channel?.ChannelCode ?? ""; set { if (null != Channel) { Channel.ChannelCode = value; Channel.IsModified = true; } } } /// /// the electronic id on the physical channel (if any) /// public string EID { get; set; } /// /// the "name" of the channel, if any (is blank if no TTSRecord associated with this channel) /// public string Name { get => Channel?.JCodeOrDescription ?? ""; set { if (null != Channel) { Channel.JCodeOrDescription = value; Channel.IsModified = true; } } } /// /// the serial number for a sensor on this channel (if any) /// public string SerialNumber => Channel?.SensorSerialNumber ?? ""; public string SensitivityString => Sensitivity.ToString("N12"); /// /// the sensitivity of the sensor on this channel (if any) /// public double Sensitivity => Channel?.SensorSensitivity ?? 0D; /// /// true as long as there is a TTS record associated with this physical channel /// public bool IsActive { get { if (null == Channel) return false; if (null != Channel.HardwareChannel && Channel.HardwareChannel.IsDigitalOut) { return Channel.DigitalOutputMode != DigitalOutputModes.NONE; } return true; } } /// /// the capacity of the sensor associated with this physical channel (if any) /// public double Capacity => Channel?.SensorCapacity ?? 0D; /// /// the range of the sensor associated with this physical channel (if any) /// 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; } } } /// /// the delay in ms between trigger and squib fire /// public double SquibFireDelayMs { get => Channel?.SquibFireDelayMs ?? 0D; set { if (null != Channel) { Channel.SquibFireDelayMs = value; Channel.IsModified = true; } } } /// /// the limit for current (amps) /// public double SquibFireCurrent { get => Channel?.SquibFireCurrent ?? 0D; set { if (null != Channel) { Channel.SquibFireCurrent = value; Channel.IsModified = true; } } } /// /// whether to limit the duration or not of squib fire /// 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"); } } } /// /// the duration of the squib fire in ms from the start of firing /// (if limiting duration) /// public double SquibFireDurationMs { get => Channel?.SquibFireDurationMs ?? .20D; set { if (null != Channel) { Channel.SquibFireDurationMs = value; Channel.IsModified = true; } } } /// /// the squib resistance tolerance low value (ohms) /// public double SquibFireResistanceLowOhm { get => Channel?.SquibFireResistanceLowOhm ?? 1D; set { if (null != Channel) { Channel.SquibFireResistanceLowOhm = value; Channel.IsModified = true; } } } /// /// the squib resistance tolerance high value (ohms) /// public double SquibFireResistanceHighOhm { get => Channel?.SquibFireResistanceHighOhm ?? 8D; set { if (null != Channel) { Channel.SquibFireResistanceHighOhm = value; Channel.IsModified = true; } } } /// /// this is the hardware channel we are wrapping /// public IHardwareChannel HardwareChannel { get; } #endregion #region dependency properties /// /// 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 /// public static readonly DependencyProperty DisabledProperty = DependencyProperty.Register("Disabled", typeof(bool), typeof(DASChannel), new PropertyMetadata(false)); #endregion #region methods /// /// Assigns this hardware to that TTSChannelRecord, or that channel record to this physical hardware /// [depending on the POV] /// /// the channel being assigned (can be null if removing a sensor from a physical channel) 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; } /// /// Adds a Digital Output channel to the Test Setup when DigitalOutputMode /// changes from None to something other than None. /// private void AddDigitalOutputChannel() { var newChannels = new List(TestSetup.Channels); newChannels.Add(Channel); TestSetup.Channels = newChannels.ToArray(); } /// /// Removes a Digital Output channel from the Test Setup when DigitalOutputMode /// changes to None. /// private void RemoveDigitalOutputChannel() { var newChannels = new List(); foreach (var channel in TestSetup.Channels) { if (channel.HardwareChannel != Channel.HardwareChannel) { newChannels.Add(channel); } } TestSetup.Channels = newChannels.ToArray(); } #endregion } }