using System; using System.Data; using DTS.Common.Interface.Channels; using DTS.Common.Interface.DataRecorders; using DTS.Common.Interface.Groups.GroupList; using DTS.Common.Interface.Sensors.SensorsList; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using DTS.Common.Events; using DTS.Common.Interface.Sensors; using Prism.Events; using Prism.Ioc; using DTS.Common.Enums; using DTS.Common.Enums.Channels; using DTS.Common.Enums.Sensors; using System.Linq; using DTS.Common.Classes.Groups.ChannelSettings; using DTS.Common.Enums.Sensors.SensorsList; using DTS.Common.Classes.ChannelCodes; using System.Text; using DTS.Common.Classes.Sensors; using DTS.Common.Classes.Channels; using DTS.Common.Interface.Sensors.SoftwareFilters; using DTS.Common.Enums.DASFactory; using DTS.Common.Enums.Hardware; using System.IO.Ports; using DTS.Common.Classes.DASFactory; namespace DTS.Common.Classes.Groups { public class GroupChannel : ChannelDbRecord, IComparable, IGroupChannel, IEquatable { public static void GetTSRAppendString(IHardwareChannel hardwarechannel, out string serial, out string moduleName, out int channelNumber, out string hardware) { serial = !string.IsNullOrWhiteSpace(hardwarechannel.ModuleSerialNumber) ? hardwarechannel.ModuleSerialNumber : hardwarechannel.GetParentDAS().SerialNumber; var tokens = serial.Split(new[] { "-" }, StringSplitOptions.RemoveEmptyEntries); moduleName = tokens[tokens.Length - 1]; channelNumber = hardwarechannel.ChannelNumber % 3; hardware = tokens[0]; } public static string GetEmbeddedSensorString(IHardwareChannel hardwarechannel) { GetTSRAppendString(hardwarechannel, out var serial, out var moduleName, out var channelNumber, out var hardware); switch (moduleName) { case DFConstantsAndEnums.ARS_SERIAL_APPEND: switch (channelNumber) { case (0): return $"{hardware}-{Strings.Strings.TSA_Embedded_ARS1}"; case (1): return $"{hardware}-{Strings.Strings.TSA_Embedded_ARS2}"; case (2): return $"{hardware}-{Strings.Strings.TSA_Embedded_ARS3}"; } break; case DFConstantsAndEnums.ANGACCEL_SERIAL_APPEND: switch (channelNumber) { case (0): return $"{hardware}-{Strings.Strings.TSA_Embedded_Angular1}"; case (1): return $"{hardware}-{Strings.Strings.TSA_Embedded_Angular2}"; case (2): return $"{hardware}-{Strings.Strings.TSA_Embedded_Angular3}"; } break; case "ATM": case DFConstantsAndEnums.ATMOSPHERIC_SERIAL_APPEND: switch (channelNumber) { case (0): return $"{hardware}-{Strings.Strings.TSA_Embedded_Temperature}"; case (1): return $"{hardware}-{Strings.Strings.TSA_Embedded_Humidity}"; case (2): return $"{hardware}-{Strings.Strings.TSA_Embedded_Atmosphere}"; } break; case DFConstantsAndEnums.HIGHG_SERIAL_APPEND: //case HardwareTypes.EMB_LIN_ACC_HI: switch (channelNumber) { case (0): return $"{hardware}-{Strings.Strings.TSA_Embedded_HighGLinear1}"; case (1): return $"{hardware}-{Strings.Strings.TSA_Embedded_HighGLinear2}"; case (2): return $"{hardware}-{Strings.Strings.TSA_Embedded_HighGLinear3}"; } break; case DFConstantsAndEnums.LOWG_SERIAL_APPEND: //case HardwareTypes.EMB_LIN_ACC_LO: switch (channelNumber) { case (0): return $"{hardware}-{Strings.Strings.TSA_Embedded_LowGLinear1}"; case (1): return $"{hardware}-{Strings.Strings.TSA_Embedded_LowGLinear2}"; case (2): return $"{hardware}-{Strings.Strings.TSA_Embedded_LowGLinear3}"; } break; } return string.Empty; } //FB 29472 Use channel hardware index to get the default scale factor for the type of sensor public static double GetEmbeddedSensorScaleFactor(IHardwareChannel hardwarechannel) { //FB 29472 // http://dtsinfo/dtswiki/index.php/TSR_AIR_Production_Attribute_Settings //Copied from default values for StackChannelScaleFactorsMillivoltsPerADC double[] scaleFactors = new double[12] { -0.00195, -0.00195, 0.00195, 0.2, 0.2, -0.2, 1, 1, -1, 0.01, 0.01, 1 }; GetTSRAppendString(hardwarechannel, out var serial, out var moduleName, out var channelNumber, out var hardware); switch (moduleName) { case DFConstantsAndEnums.ARS_SERIAL_APPEND: switch (channelNumber) { case 0: return scaleFactors[6]; case 1: return scaleFactors[7]; case 2: return scaleFactors[8]; } break; case "ATM": case DFConstantsAndEnums.ATMOSPHERIC_SERIAL_APPEND: switch (channelNumber) { case 0: return scaleFactors[9]; case 1: return scaleFactors[10]; case 2: return scaleFactors[11]; } break; case DFConstantsAndEnums.HIGHG_SERIAL_APPEND: switch (channelNumber) { case 0: return scaleFactors[3]; case 1: return scaleFactors[4]; case 2: return scaleFactors[5]; } break; case DFConstantsAndEnums.LOWG_SERIAL_APPEND: switch (channelNumber) { case 0: return scaleFactors[0]; case 1: return scaleFactors[1]; case 2: return scaleFactors[2]; } break; } //Any other channel use the default value .2D return .2D; } public bool Equals(GroupChannel other) { if (HardwareChannel == null || other.HardwareChannel == null) { return base.Equals(other); } return HardwareChannel.GetParentDAS().SerialNumber == other.HardwareChannel.GetParentDAS().SerialNumber && HardwareChannel.ChannelNumber == other.HardwareChannel.ChannelNumber; } private InitialOffset[] _availableInitialOffsets = new InitialOffset[0]; /// /// available initial offsets for this channel /// dependent on a sensor w/ a sensor calibration being assigned /// public InitialOffset[] AvailableInitialOffsets { get => _availableInitialOffsets?.ToArray(); set { _availableInitialOffsets = value; OnPropertyChanged("AvailableInitialOffsets"); OnPropertyChanged("InitialOffset"); } } /// /// current support for IEPE by channel /// if there is a sensor assigned, value is depedent on sensor bridge /// if there is no sensor but hardware is assigned, is dependent on hardwarechannel support /// if neither is assigned, IEPE Is available to be assigned to the channel /// public string IEPESupport { get { if (null != SensorData) { if (SensorData.IsTestSpecificEmbedded) { return Strings.Strings.Embedded; } switch (SensorData.Bridge) { case SensorConstants.BridgeType.IEPE: return Strings.Strings.IEPE; case SensorConstants.BridgeType.SQUIB: return Strings.Strings.Squib; case SensorConstants.BridgeType.DigitalInput: return Strings.Strings.DigitalIn; case SensorConstants.BridgeType.TOMDigital: return Strings.Strings.DigitalOut; case SensorConstants.BridgeType.UART: return Strings.Strings.UART; case SensorConstants.BridgeType.StreamOut: return Strings.Strings.StreamOut; case SensorConstants.BridgeType.StreamIn: return Strings.Strings.StreamIn; case SensorConstants.BridgeType.Thermocoupler: return Strings.Strings.Thermocoupler; default: return Strings.Strings.Analog; } } if (null != DragAndDropItem) { if (DragAndDropItem is IAnalogSensor analogSensor) { if (SensorConstants.IsTestSpecificEmbedded(analogSensor.SerialNumber)) { return Strings.Strings.Embedded; } return analogSensor.IEPE ? Strings.Strings.IEPE : Strings.Strings.Analog; } else if (DragAndDropItem is ISquib) { return Strings.Strings.Squib; } else if (DragAndDropItem is IDigitalInputSetting) { return Strings.Strings.DigitalIn; } else if (DragAndDropItem is IDigitalOutputSetting) { return Strings.Strings.DigitalOut; } else if (DragAndDropItem is IUartIOSetting) { return Strings.Strings.UART; } else if (DragAndDropItem is IStreamOutputSetting) { return Strings.Strings.StreamOut; } else if (DragAndDropItem is IStreamInputSetting) { return Strings.Strings.StreamIn; } } if (null != HardwareChannel) { if (HardwareChannel.IsSquib) { return Strings.Strings.Squib; } else if (HardwareChannel.IsDigitalIn) { return Strings.Strings.DigitalIn; } else if (HardwareChannel.IsDigitalOut) { return Strings.Strings.DigitalOut; } else if (HardwareChannel.IsUart) { return Strings.Strings.UART; } else if (HardwareChannel.IsStreamOut) { return Strings.Strings.StreamOut; } else if (HardwareChannel.IsStreamIn) { return Strings.Strings.StreamIn; } else if (HardwareChannel.IsThermocoupler) { return Strings.Strings.Thermocoupler; } else if (HardwareChannel.IsSupportedBridgeType(SensorConstants.BridgeType.FullBridge)) { if (HardwareChannel.IsSupportedBridgeType(SensorConstants.BridgeType.IEPE)) { return $"{Strings.Strings.Analog}/{Strings.Strings.IEPE}"; } return Strings.Strings.Analog; } else { return Strings.Strings.IEPE; } } return Strings.Strings.Table_NA; } } //in case this object is held onto longer, make sure we clear all we can right away ~GroupChannel() { UnRegisterCommands(); ChannelSettings = new IChannelSetting[0]; _activeValue = null; //FB 13120 store filter class setting _filterClassSetting = null; _defaultValue = null; _digitalInputMode = null; _digitalOutDelay = null; _digitalOutDuration = null; _digitalOutLimitDuration = null; _digitalOutputMode = null; _group = null; _groupName = null; _hardware = null; _polaritySetting = null; _rangeSetting = null; _squibCurrent = null; _squibDelay = null; _squibDuration = null; _squibFireMode = null; _squibLimitDuration = null; _zeroMethodSetting = null; _zeroMethodStartSetting = null; _zeroMethodEndSetting = null; _uartBaudRate = null; _uartDataBits = null; _uartStopBits = null; _uartParity = null; _uartFlowControl = null; _uartDataFormat = null; _streamOutUDPProfile = null; _streamOutUDPAddress = null; _streamOutUDPTimeChannelId = null; _streamOutUDPDataChannelId = null; _streamOutUDPTmNSConfig = null; _streamOutIRIGTimeDataPacketIntervalMs = null; _streamOutTMATSIntervalMs = null; _streamInUDPAddress = null; _acCouplingSetting = null; _bridgeTypeSetting = null; } public int CompareTo(GroupChannel other) { var aBlank = IsBlank(); var bBlank = other.IsBlank(); if (aBlank) { if (bBlank) { return 0; } return 1; } if (bBlank) { return -1; } var ret = TestSetupOrder.CompareTo(other.TestSetupOrder); if (0 != ret) { return ret; } ret = GroupChannelOrder.CompareTo(other.GroupChannelOrder); if (0 != ret) { return ret; } ret = Id.CompareTo(other.Id); if (0 != ret) { return ret; } ret = IsoChannelName.CompareTo(other.IsoChannelName); if (0 != ret) { return ret; } ret = UserChannelName.CompareTo(other.UserChannelName); if (0 != ret) { return ret; } return GetHashCode().CompareTo(other.GetHashCode()); } public void Copy(IGroupChannel channel) { if (!(channel is GroupChannel groupChannel)) { throw new NotImplementedException("GroupChannel.Copy not implemented for generic"); } if (channel.GroupNameValid) { Group = channel.Group; GroupName = channel.GroupName; } if (channel.HardwareValid) { Hardware = groupChannel.Hardware; HardwareId = groupChannel.HardwareId; DASId = groupChannel.DASId; DASChannelIndex = groupChannel.DASChannelIndex; } if (channel.IsoChannelNameValid) { IsoChannelName = groupChannel.IsoChannelName; } if (channel.IsoCodeValid) { IsoCode = groupChannel.IsoCode; } if (channel.SensorValid) { SensorData = groupChannel.SensorData; DragAndDropItem = groupChannel.DragAndDropItem; SensorId = groupChannel.SensorId; } HardwareChannel = channel.HardwareChannel; if (channel.UserChannelNameValid) { UserChannelName = groupChannel.UserChannelName; } if (channel.UserCodeValid) { UserCode = groupChannel.UserCode; } } //decideSettings allows channel settings to be set when sensor is set public void SetSensor(ISensorData item, bool decideSettings = false) { DragAndDropItem = null; SensorData = item; if (null == item) { SensorId = -1; } else { SensorId = item.DatabaseId; if (string.IsNullOrWhiteSpace(IsoCode) && !string.IsNullOrWhiteSpace(item.ISOCode)) { IsoCode = item.ISOCode; } if (string.IsNullOrWhiteSpace(IsoChannelName) && !string.IsNullOrWhiteSpace(item.ISOChannelName)) { IsoChannelName = item.ISOChannelName; } if (string.IsNullOrWhiteSpace(UserCode) && !string.IsNullOrWhiteSpace(item.UserCode)) { UserCode = item.UserCode; } if (string.IsNullOrWhiteSpace(UserChannelName) && !string.IsNullOrWhiteSpace(item.UserChannelName)) { UserChannelName = item.UserChannelName; } } if (decideSettings) { SetSettingsFromSensor(item); } SensorPropertyChanged(); } /// /// whether AC couplign is enabled or not for the channel /// this is currently only valid for TSR AIR low g channels /// http://manuscript.dts.local/f/cases/29760/Implement-ACCoupleEnable-for-TSR-AIR /// public bool ACCouplingEnabled { get => _acCouplingSetting?.BoolValue ?? false; set { if (null != _acCouplingSetting) { _acCouplingSetting.BoolValue = value; } MarkPropertyChanged("ACCouplingEnabled"); } } private void HardwarePropertyChanged() { OnPropertyChanged("Hardware"); OnPropertyChanged("IEPESupport"); OnPropertyChanged("IsChannelComplete"); OnPropertyChanged("ChannelStatus"); OnPropertyChanged("SensorCalibrationOrUsageStatus"); OnPropertyChanged("EmbeddedSensor"); OnPropertyChanged("IsTSRAIRLowG"); OnPropertyChanged("ACCouplingEnabled"); } private void SensorPropertyChanged() { OnPropertyChanged("Sensor"); OnPropertyChanged("IEPESupport"); OnPropertyChanged("IsChannelComplete"); OnPropertyChanged("ChannelStatus"); OnPropertyChanged("SensorCalibrationOrUsageStatus"); OnPropertyChanged("EmbeddedSensor"); OnPropertyChanged("IsTSRAIRLowG"); OnPropertyChanged("ACCouplingEnabled"); } public void SetSensor(IDragAndDropItem sensor, IChannelSetting[] channelDefaults, bool applySensorDataToBlankChannels) { bool bAlreadyHasSensor = (null != SensorData) || (null != DragAndDropItem); SensorData = null; DragAndDropItem = sensor; if (null == sensor) { SensorId = -1; } else { SensorId = sensor.DatabaseId; SetChannelNameFieldsIfBlank(sensor.ISOCode, sensor.ISOChannelName, sensor.UserCode, sensor.UserChannelName); DecideSettings(sensor, channelDefaults, bAlreadyHasSensor, applySensorDataToBlankChannels); } SensorPropertyChanged(); } /// /// If one of the "name" fields in the channel which is having a sensor assigned is blank, /// set it to the corresponding value passed in. This may be due to a sensor being /// dragged onto a channel, or due to a Push/Pull of a sensor to update the channel. /// /// /// /// /// private void SetChannelNameFieldsIfBlank(string itemISOCode, string itemISOChannelName, string itemUserCode, string itemUserChannelName) { if (string.IsNullOrWhiteSpace(IsoCode) && !string.IsNullOrWhiteSpace(itemISOCode)) { IsoCode = itemISOCode; IsoCodeValid = true; } // FB13408: Use ISOCode filter of sensor iff channel is set to wildcard, sensor isn't, and we're dealing with full-length codes if (IsoCode.EndsWith("?") && !itemISOCode.EndsWith("?") && IsoCode.Length == itemISOCode.Length && IsoCode.Length == ChannelEnumsAndConstants.ISO_CODE_LENGTH) { IsoCode = IsoCode.Substring(0, ChannelEnumsAndConstants.ISO_CODE_LENGTH - 1) + itemISOCode.Substring(ChannelEnumsAndConstants.ISO_CODE_LENGTH - 1); } if (string.IsNullOrWhiteSpace(IsoChannelName) && !string.IsNullOrWhiteSpace(itemISOChannelName)) { IsoChannelName = itemISOChannelName; IsoChannelNameValid = true; } if (string.IsNullOrWhiteSpace(UserCode) && !string.IsNullOrWhiteSpace(itemUserCode)) { UserCode = itemUserCode; UserCodeValid = true; } if (string.IsNullOrWhiteSpace(UserChannelName) && !string.IsNullOrWhiteSpace(itemUserChannelName)) { UserChannelName = itemUserChannelName; UserChannelNameValid = true; } } private bool _canMoveUp = false; /// /// sets the channel settings from a sensor /// this only happens when creating new channels using a sensor /// other routes use DecideSettings instead /// /// public void SetSettingsFromSensor(ISensorData sd) { if (sd.IsSquib()) { SquibDelay = sd.SquibFireDelayMS; SquibDuration = sd.SquibFireDurationMS; SquibFireMode = sd.SquibFireMode; SquibLimitDuration = sd.LimitSquibFireDuration; SquibCurrent = sd.SquibOutputCurrent; } else if (sd.IsDigitalInput()) { DigitalInputMode = sd.InputMode; ActiveValue = sd.InputActiveValue.ToString(); DefaultValue = sd.InputDefaultValue.ToString(); } else if (sd.IsDigitalOutput()) { DigitalOutputMode = sd.DigitalOutputMode; DigitalOutDelay = sd.DigitalOutputDelayMS; DigitalOutLimitDuration = sd.DigitalOutputLimitDuration; DigitalOutDuration = sd.DigitalOutputDurationMS; } else if (sd.IsUart()) { UartBaudRate = sd.UartBaudRate; UartDataBits = sd.UartDataBits; UartStopBits = sd.UartStopBits; UartParity = sd.UartParity; UartDataFormat = sd.UartDataFormat; } else if (sd.IsStreamOutput()) { StreamOutUDPProfile = sd.StreamOutUDPProfile; StreamOutUDPAddress = sd.StreamOutUDPAddress; StreamOutUDPTimeChannelId = sd.StreamOutUDPTimeChannelId; StreamOutUDPDataChannelId = sd.StreamOutUDPDataChannelId; StreamOutUDPTmNSConfig = sd.StreamOutUDPTmNSConfig; StreamOutIRIGTimeDataPacketIntervalMs = sd.StreamOutIRIGTimeDataPacketIntervalMs; StreamOutTMATSIntervalMs = sd.StreamOutTMATSIntervalMs; } else if (sd.IsStreamInput()) { StreamInUDPAddress = sd.StreamInUDPAddress; } else { AssemblyName = sd.AssemblyName; //FB 13120 set filter class FilterClass = sd.FilterClass; Range = sd.Capacity; Polarity = sd.Invert ? "-" : "+"; //FB14606 var sc = sd.GetLatestCalibration(); if (null == sc) { //15642 ISF import fails with error //if a bunch of exceptions occur if sc is null //for now just don't set these properties //http://manuscript.dts.local/f/cases/44051/TSR-AIR-GO-ZeroMethod-was-AverageOverTime-in-level-trigger-recording-data-but-it-should-be-None //don't set this for TSRAIR if (sd.IsTestSpecificEmbedded && !IsTSRAIR) { ZeroMethod = sd.Calibration.ZeroMethods.Methods[0].Method; } } else { ZeroMethod = sd.GetLatestCalibration().LinearAdded ? sd.GetLatestCalibration().ZeroMethods.Methods.Last().Method : sd.GetLatestCalibration().ZeroMethods.Methods[0].Method; ZeroMethodStart = sd.GetLatestCalibration().LinearAdded ? sd.GetLatestCalibration().ZeroMethods.Methods.Last().Start : sd.GetLatestCalibration().ZeroMethods.Methods[0].Start; ZeroMethodEnd = sd.GetLatestCalibration().LinearAdded ? sd.GetLatestCalibration().ZeroMethods.Methods.Last().End : sd.GetLatestCalibration().ZeroMethods.Methods[0].End; AvailableInitialOffsets = sd.GetLatestCalibration().InitialOffsets.Offsets; var found = false; foreach (var offset in AvailableInitialOffsets) { if (offset.Form == InitialOffset.Form) { InitialOffset = offset; found = true; break; } } if (!found) { InitialOffset = sd.GetLatestCalibration().InitialOffsets.DefaultOffset; } } //FB 26950: Push/Pull of a sensor should assign values to blank "name" fields to be //consistent with removing/re-adding the sensor. SetChannelNameFieldsIfBlank(sd.ISOCode, sd.ISOChannelName, sd.UserCode, sd.UserChannelName); } } /// /// decides the channel settings for the channel /// 1) if there's already a sensor on the channel, then we don't change settings at all /// 2) if the settings on the channel are NOT default, then we use those /// otherwise /// 3) we use the settings from the "sensor" /// /// /// /// /// private void DecideSettings(IDragAndDropItem sensor, IChannelSetting[] defaults, bool bAlreadyHasSensor, bool applySensorDataToBlankChannels) { if (bAlreadyHasSensor) { return; } _ = defaults.ToDictionary(d => d.SettingName); if (applySensorDataToBlankChannels) { if (sensor is IAnalogSensor analogSensor) { //cfc //polarity //FB 13120 set filter class FilterClass = analogSensor.FilterClass; Range = analogSensor.Capacity; Polarity = analogSensor.Polarity ? "+" : "-"; ZeroMethod = analogSensor.ZeroMethod; ZeroMethodStart = analogSensor.ZeroMethodStart; ZeroMethodEnd = analogSensor.ZeroMethodEnd; UserValue1 = analogSensor.UserValue1; UserValue2 = analogSensor.UserValue2; UserValue3 = analogSensor.UserValue3; if (null != analogSensor.InitialOffsets && analogSensor.InitialOffsets.Any()) { //30442 Don't default InitialOffset to None if other options exist if ((analogSensor.InitialOffsets.Count() > 1) && (analogSensor.InitialOffsets[0].Form == InitialOffsetTypes.None)) { InitialOffset = analogSensor.InitialOffsets[1]; } else { InitialOffset = analogSensor.InitialOffsets[0]; } } } else if (sensor is ISquib squib) { SquibDelay = squib.SQDelay; SquibDuration = squib.SQDuration; SquibFireMode = squib.Mode; SquibLimitDuration = squib.LimitDuration; SquibCurrent = squib.SQCurrent; } else if (sensor is IDigitalInputSetting digitalInput) { DigitalInputMode = digitalInput.Mode; ActiveValue = digitalInput.ActiveValue; DefaultValue = digitalInput.DefaultValue; } else if (sensor is IDigitalOutputSetting digitalOut) { DigitalOutputMode = digitalOut.DOMode; DigitalOutDelay = digitalOut.DODelay; DigitalOutLimitDuration = digitalOut.LimitDuration; DigitalOutDuration = digitalOut.DODuration; } else if (sensor is IUartIOSetting uart) { UartBaudRate = uart.BaudRate; UartDataBits = uart.DataBits; UartStopBits = uart.StopBits; UartParity = uart.Parity; UartDataFormat = uart.DataFormat; } else if (sensor is IStreamOutputSetting streamOut) { StreamOutUDPProfile = streamOut.UDPProfile; StreamOutUDPAddress = streamOut.UDPAddress; StreamOutUDPTimeChannelId = streamOut.UDPTimeChannelId; StreamOutUDPDataChannelId = streamOut.UDPDataChannelId; StreamOutUDPTmNSConfig = streamOut.UDPTmNSConfig; StreamOutIRIGTimeDataPacketIntervalMs = streamOut.IRIGTimeDataPacketIntervalMs; StreamOutTMATSIntervalMs = streamOut.TMATSIntervalMs; } else if (sensor is IStreamInputSetting streamIn) { StreamInUDPAddress = streamIn.UDPAddress; } } } public bool CanMoveUp { get => _canMoveUp; set => SetProperty(ref _canMoveUp, value, "CanMoveUp"); } private bool _canMoveDown = false; public bool CanMoveDown { get => _canMoveDown; set => SetProperty(ref _canMoveDown, value, "CanMoveDown"); } private bool _deleteShouldBeEnabled = true; public bool DeleteShouldBeEnabled { get => _deleteShouldBeEnabled; set => SetProperty(ref _deleteShouldBeEnabled, value, "DeleteShouldBeEnabled"); } private Visibility _removeSensorVisibility = Visibility.Visible; public System.Windows.Visibility RemoveSensorVisibility { get => _removeSensorVisibility; set => SetProperty(ref _removeSensorVisibility, value, "RemoveSensorVisibility"); } private const int INVALID_SENSOR_ID = -1; private const int INVALID_DAS_ID = -1; //14357 Extra blank channel added when creating group using ctrl-V //channels were being marked as not blank when they really were because of the iso code autofill ... public const string BLANK_FULL_ISO = "????????????????"; public bool IsBlank() { return (SensorId == INVALID_SENSOR_ID || SensorData?.SerialNumber == SensorConstants.TEST_SPECIFIC_ANALOG_SERIAL || SensorData?.SerialNumber == SensorConstants.TEST_SPECIFIC_CLOCK_SERIAL) && DASId == INVALID_DAS_ID && string.IsNullOrWhiteSpace(IsoChannelName) && string.IsNullOrWhiteSpace(UserChannelName) && string.IsNullOrEmpty(UserCode) && (string.IsNullOrEmpty(IsoCode) || BLANK_FULL_ISO.Equals(IsoCode)); } public void SetSensorData(ISensorData sensorData, IDragAndDropItem dragAndDropItem, bool decideSettings = false) { SensorData = sensorData; //14571 Creating a group using ctrl v sets range CAC to 2400 for all channels. if (decideSettings) { SetSettingsFromSensor(sensorData); } if (null != sensorData && !sensorData.IsSquib() && !sensorData.IsDigitalInput() && !sensorData.IsDigitalOutput() && !sensorData.IsUart() && !sensorData.IsStreamInput() && !sensorData.IsStreamOutput()) { var sc = sensorData.GetLatestCalibration(); if (null != sc) { AvailableInitialOffsets = sc.InitialOffsets.Offsets; } } DragAndDropItem = dragAndDropItem; SensorPropertyChanged(); HardwarePropertyChanged(); } public void Clear() { SensorId = -1; SetSensorData(null, null); HardwareChannel = null; DASId = -1; DASChannelIndex = -1; Hardware = ""; HardwareId = ""; HardwarePropertyChanged(); } /// /// this could be passed into the constructors in the future, but since it's only used in one place right now, I'll just put it here /// public const string PASTE_ID = "GroupChannel"; private static bool _registered = false; private void RegisterCommands() { PasteCommand = new PasteCommandClass(PASTE_ID); if (!_registered) { //this register is for the entire class, not just this one instance, so //it only needs to be registered once CommandManager.RegisterClassCommandBinding(GetType(), new CommandBinding(PasteCommand, Paste)); _registered = true; } } private void UnRegisterCommands() { PasteCommand = null; } private void Paste(object sender, ExecutedRoutedEventArgs e) { } public bool Filter(string term) { if (string.IsNullOrWhiteSpace(term)) { return true; } if (null != Sensor) { if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(Sensor, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0) { return true; } } if (null != Hardware) { if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(Hardware, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0) { return true; } } if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(IsoChannelName, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0) { return true; } if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(IsoCode, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0) { return true; } if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(UserCode, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0) { return true; } if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(UserChannelName, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0) { return true; } if (System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(GroupName, term, System.Globalization.CompareOptions.OrdinalIgnoreCase) >= 0) { return true; } return false; } private IChannelSetting[] GetApplicableSettings() { var list = new List(); if (null != _activeValue && IsDigitalIn) { list.Add(_activeValue); } if (null != _defaultValue && IsDigitalIn) { list.Add(_defaultValue); } if (null != _digitalInputMode && IsDigitalIn) { list.Add(_digitalInputMode); } //FB 13120 get filter class setting if (null != _filterClassSetting && IsAnalog) { list.Add(_filterClassSetting); } if (null != _polaritySetting && IsAnalog) { list.Add(_polaritySetting); } if (null != _rangeSetting && IsAnalog) { list.Add(_rangeSetting); } if (null != _zeroMethodSetting && IsAnalog) { list.Add(_zeroMethodSetting); } if (null != _zeroMethodStartSetting && IsAnalog) { list.Add(_zeroMethodStartSetting); } if (null != _zeroMethodEndSetting && IsAnalog) { list.Add(_zeroMethodEndSetting); } if (null != _initialOffsetSetting && IsAnalog) { list.Add(_initialOffsetSetting); } if (null != _userValue1Setting && IsAnalog) { list.Add(_userValue1Setting); } if (null != _userValue2Setting && IsAnalog) { list.Add(_userValue2Setting); } if (null != _userValue3Setting && IsAnalog) { list.Add(_userValue3Setting); } if (null != _acCouplingSetting) { list.Add(_acCouplingSetting); } if (null != _digitalOutDelay && IsDigitalOut) { list.Add(_digitalOutDelay); } if (null != _digitalOutputMode && IsDigitalOut) { list.Add(_digitalOutputMode); } if (null != _digitalOutDuration && IsDigitalOut) { list.Add(_digitalOutDuration); } if (null != _digitalOutLimitDuration && IsDigitalOut) { list.Add(_digitalOutLimitDuration); } if (null != _squibDelay && IsSquib) { list.Add(_squibDelay); } if (null != _squibFireMode && IsSquib) { list.Add(_squibFireMode); } if (null != _squibDuration && IsSquib) { list.Add(_squibDuration); } if (null != _squibLimitDuration && IsSquib) { list.Add(_squibLimitDuration); } if (null != _squibCurrent && IsSquib) { list.Add(_squibCurrent); } if (null != _uartBaudRate && IsUart) { list.Add(_uartBaudRate); } if (null != _uartDataBits && IsUart) { list.Add(_uartDataBits); } if (null != _uartStopBits && IsUart) { list.Add(_uartStopBits); } if (null != _uartParity && IsUart) { list.Add(_uartParity); } if (null != _uartFlowControl && IsUart) { list.Add(_uartFlowControl); } if (null != _uartDataFormat && IsUart) { list.Add(_uartDataFormat); } if (null != _streamOutUDPProfile && IsStreamOut) { list.Add(_streamOutUDPProfile); } if (null != _streamOutUDPAddress && IsStreamOut) { list.Add(_streamOutUDPAddress); } if (null != _streamOutUDPTimeChannelId && IsStreamOut) { list.Add(_streamOutUDPTimeChannelId); } if (null != _streamOutUDPDataChannelId && IsStreamOut) { list.Add(_streamOutUDPDataChannelId); } if (null != _streamOutUDPTmNSConfig && IsStreamOut) { list.Add(_streamOutUDPTmNSConfig); } if (null != _streamOutIRIGTimeDataPacketIntervalMs && IsStreamOut) { list.Add(_streamOutIRIGTimeDataPacketIntervalMs); } if (null != _streamOutTMATSIntervalMs && IsStreamOut) { list.Add(_streamOutTMATSIntervalMs); } if (null != _streamInUDPAddress && IsStreamIn) { list.Add(_streamInUDPAddress); } //33415 Voltage insertion channel should be half bridge if (null != _bridgeTypeSetting && IsAnalog && SensorConstants.TEST_SPECIFIC_ANALOG_SERIAL == SensorData?.SerialNumber) { list.Add(_bridgeTypeSetting); } return list.ToArray(); } public ICommand PasteCommand { get; set; } public IChannelSetting[] ChannelSettings { get => GetApplicableSettings(); set => SetSettings(value); } /// /// removes the zero method setting /// done as part of /// 15262 Absolute zero sensors in test setup change to ave over time after import. /// the FixZeroMethodSetting only works when the setting is not set, and the default setting can get set /// this allows import to unset it again /// public void RemoveZeroMethodSetting() { _zeroMethodSetting = null; } /// /// 15236 Initial offset parameter not set after test setup import /// InitialOffset may not be defined in older test setups, when this happens /// just use the sensor calibration's default initial offset. /// /// /// public void FixInitialOffsetIfNeeded(IChannelSetting defaultInitialOffset, ISensorCalibration sensorCalibration) { //16319 User must set init offset for all channels in a test setup //if initial offset value is null, it's invalid, we have to set it anyhow if (null != _initialOffsetSetting && !string.IsNullOrWhiteSpace(_initialOffsetSetting.Value)) { return; } //already defined _initialOffsetSetting = new ChannelSettingBase(defaultInitialOffset.SettingTypeId, defaultInitialOffset.SettingName, defaultInitialOffset.DefaultValue); InitialOffset = sensorCalibration.InitialOffsets.DefaultOffset; } /// /// 15262 Absolute zero sensors in test setup change to ave over time after import. /// if zero method is defined will return naturally, if it's undefined it will /// define it using the relevant sensor calibration /// the default are used to create new settings prior to setting the value /// /// /// /// /// public void FixZeroMethodIfNeeded(IChannelSetting defaultZeroMethod, IChannelSetting defaultZeroStart, IChannelSetting defaultZeroEnd, ISensorCalibration sensorCalibration) { if (defaultZeroMethod == null) { return; } if (null != _zeroMethodSetting) { return; } //already defined _zeroMethodSetting = new ChannelSettingBase(defaultZeroMethod.SettingTypeId, defaultZeroMethod.SettingName, defaultZeroMethod.DefaultValue); _zeroMethodStartSetting = new ChannelSettingBase(defaultZeroStart.SettingTypeId, defaultZeroStart.SettingName, defaultZeroStart.DefaultValue); _zeroMethodEndSetting = new ChannelSettingBase(defaultZeroEnd.SettingTypeId, defaultZeroEnd.SettingName, defaultZeroEnd.DefaultValue); ZeroMethod = sensorCalibration?.ZeroMethods.Methods.FirstOrDefault()?.Method ?? ZeroMethodType.None; ZeroMethodStart = sensorCalibration?.ZeroMethods.Methods.FirstOrDefault()?.Start ?? 0.0; ZeroMethodEnd = sensorCalibration?.ZeroMethods.Methods.FirstOrDefault()?.End ?? 0.0; } private void SetSettings(IChannelSetting[] settings) { foreach (var setting in settings) { var copy = setting.Clone(); switch (setting.SettingName) { case ChannelSettingBase.ACTIVE_VALUE: _activeValue = copy; break; case ChannelSettingBase.DEFAULT_VALUE: _defaultValue = copy; break; case ChannelSettingBase.DIMODE: _digitalInputMode = copy; break; //FB 13120 & 15523 replaced _cfcSetting with _filterClassSetting case ChannelSettingBase.FilterClass: _filterClassSetting = copy; break; case ChannelSettingBase.POLARITY: _polaritySetting = copy; break; case ChannelSettingBase.RANGE: _rangeSetting = copy; break; case ChannelSettingBase.ZEROMETHOD: _zeroMethodSetting = copy; break; case ChannelSettingBase.ZEROMETHODSTART: _zeroMethodStartSetting = copy; break; case ChannelSettingBase.ZEROMETHODEND: _zeroMethodEndSetting = copy; break; case ChannelSettingBase.USERVALUE1: _userValue1Setting = copy; break; case ChannelSettingBase.USERVALUE2: _userValue2Setting = copy; break; case ChannelSettingBase.USERVALUE3: _userValue3Setting = copy; break; case ChannelSettingBase.INITIAL_OFFSET: SetInitialOffsetSetting(copy); break; case ChannelSettingBase.ACCouplingEnabled: _acCouplingSetting = copy; break; case ChannelSettingBase.DIGITALOUT_DELAY: _digitalOutDelay = copy; break; case ChannelSettingBase.DIGITALOUT_DURATION: _digitalOutDuration = copy; break; case ChannelSettingBase.DIGITALOUT_LIMIT_DURATION: _digitalOutLimitDuration = copy; break; case ChannelSettingBase.OUTPUT_MODE: _digitalOutputMode = copy; break; case ChannelSettingBase.SQUIB_DELAY: _squibDelay = copy; break; case ChannelSettingBase.SQUIB_DURATION: _squibDuration = copy; break; case ChannelSettingBase.SQUIB_LIMIT_DURATION: _squibLimitDuration = copy; break; case ChannelSettingBase.SQMODE: _squibFireMode = copy; break; case ChannelSettingBase.SQUIB_CURRENT: _squibCurrent = copy; break; case ChannelSettingBase.POSITION: break; //ignore, this should be stored in ISOCode case "LimitDuration": //deprecated, only needed for migrating to current version xml? _squibLimitDuration = new ChannelSettingBase((int)SensorConstants.SensorSettings.SquibLimitDuration + 1, ChannelSettingBase.SQUIB_LIMIT_DURATION, setting.Value); _squibLimitDuration.Value = setting.Value; _digitalOutLimitDuration = new ChannelSettingBase((int)SensorConstants.SensorSettings.DigitalOutLimitDuration + 1, ChannelSettingBase.DIGITALOUT_LIMIT_DURATION, setting.Value); _digitalOutLimitDuration.Value = setting.Value; break; case "Delay"://deprecated, only needed for migrating to current version xml? _squibDelay = new ChannelSettingBase((int)SensorConstants.SensorSettings.SquibDelay + 1, ChannelSettingBase.SQUIB_DELAY, setting.Value); _squibDelay.Value = setting.Value; _digitalOutDelay = new ChannelSettingBase((int)SensorConstants.SensorSettings.DigitalOutDelay + 1, ChannelSettingBase.DIGITALOUT_DELAY, setting.Value); _digitalOutDelay.Value = setting.Value; break; case "Duration": //deprecated, only needed for migrating to current version xml? _squibDuration = new ChannelSettingBase((int)SensorConstants.SensorSettings.SquibDuration + 1, ChannelSettingBase.SQUIB_DURATION, setting.Value); _squibDuration.Value = setting.Value; _digitalOutDuration = new ChannelSettingBase((int)SensorConstants.SensorSettings.DigitalOutDuration + 1, ChannelSettingBase.DIGITALOUT_DURATION, setting.Value); _digitalOutDuration.Value = setting.Value; break; case ChannelSettingBase.BAUD_RATE: _uartBaudRate = copy; break; case ChannelSettingBase.DATA_BITS: _uartDataBits = copy; break; case ChannelSettingBase.STOP_BITS: _uartStopBits = copy; break; case ChannelSettingBase.PARITY: _uartParity = copy; break; case ChannelSettingBase.FLOW_CONTROL: _uartFlowControl = copy; break; case ChannelSettingBase.DATA_FORMAT: _uartDataFormat = copy; break; case ChannelSettingBase.UDP_PROFILE: _streamOutUDPProfile = copy; break; case ChannelSettingBase.UDP_ADDRESS: _streamOutUDPAddress = copy; break; case ChannelSettingBase.UDP_DATA_CHID: _streamOutUDPDataChannelId = copy; break; case ChannelSettingBase.UDP_TIME_CHID: _streamOutUDPTimeChannelId = copy; break; case ChannelSettingBase.UDP_TMNS_CONFIG: _streamOutUDPTmNSConfig = copy; break; case ChannelSettingBase.TMATS_INTERVAL_MS: _streamOutTMATSIntervalMs = copy; break; case ChannelSettingBase.IRIG_TDP_INTERVAL_MS: _streamOutIRIGTimeDataPacketIntervalMs = copy; break; case ChannelSettingBase.UDP_ADDRESS_IN: _streamInUDPAddress = copy; break; //33415 Voltage insertion channel should be half bridge case ChannelSettingBase.BRIDGE_TYPE: _bridgeTypeSetting = copy; break; default: throw new NotImplementedException("unknown setting: " + setting.SettingName); } } } public static string GetString(IAnalogSensor sensor) { if (string.IsNullOrWhiteSpace(sensor.Description)) { return sensor.SerialNumber; } return $"{sensor.Description} ({sensor.SerialNumber})"; } public static string GetString(IDigitalInputSetting digitalInputSetting) { return digitalInputSetting.SerialNumber; } public static string GetString(IUartIOSetting uartIOSetting) { return uartIOSetting.SerialNumber; } public static string GetString(IStreamOutputSetting streamOutSetting) { return streamOutSetting.SerialNumber; } public static string GetString(IStreamInputSetting streamInSetting) { return streamInSetting.SerialNumber; } /// /// this property links to a function to coerce iso code values /// originally part of /// 14033 finish/clean up from removing CFC filter from digital input on sensor db /// this lets incoming isocodes from the UI be coerced to new values if needed /// public CoerceISOCodeDelegate CoerceISOCodeFunc => CoerceFunc; private string CoerceFunc(string val, bool uniqueISOCodesRequired, bool useISOCodeFilterMapping) { //if we don't require unique isocodes, then the isocode is unbounded if (!uniqueISOCodesRequired) { return val; } val = val.ToUpper().PadRight(ChannelEnumsAndConstants.ISO_CODE_LENGTH, '?'); if (useISOCodeFilterMapping && IsDigitalIn && !IsAnalog && !IsDigitalOut && !IsSquib && !IsUart && !IsStreamOut) { //digital in will always have 0 for filter var iso = new ISO.IsoCode(val); iso.FilterClass = "0"; val = iso.StringRepresentation; } return val; } /// /// FB 15574 FB 13120 /// This method replaces the SetFilterFromISOCode to let us retrieve the filter based on iso and set it explicitly /// /// available filteres /// the isoCode which we want to get the filter class for /// public IFilterClass GetFilterClassFromISOCode(ISoftwareFilter[] filters, string isoCode) { IFilterClass filterClass = null; var iso = new ISO.IsoCode(isoCode); var filter = iso.FilterClass; if (IsDigitalIn && !IsAnalog && !IsSquib && !IsDigitalOut && !IsUart && !IsStreamOut) { //digital in is always filter class 0 when isocode filter mapping is on filter = "0"; } switch (filter) { case "A": case "B": case "C": case "D": case "0": case "P": //FB 15523 set the filter class based on iso code filterClass = new FilterClass(Sensors.FilterClass.GetFilterClassFromIsoCode(filter).FClass); break; case "S": //FB 15523 use first adhoc , if there is no adhoc switch back to CFC1000 (A) filter var adhocFilter = Array.Find(filters, p => p.ISOCode == 'S'); if (adhocFilter == null) { filterClass = new FilterClass(FilterClassType.CFC1000); } else { filterClass = new FilterClass(adhocFilter.Frequency); } break; default: filterClass = new FilterClass(FilterClassType.CFC1000); break; } //digital ins should always be unfiltered //we use IsAnalog just as a quick check to make sure it's not a sensor less channel if (IsDigitalIn && !IsAnalog) { //FB 15523 replaced _cfcSetting with _filterClassSetting filterClass = new FilterClass(FilterClassType.Unfiltered); } return filterClass; } public static string GetString(IDigitalOutputSetting digitalOutputSetting) { if (digitalOutputSetting.SerialNumber.StartsWith(SensorConstants.TEST_SPECIFIC_DOUT)) { return Strings.Strings.DigitalOutputSetting; } return digitalOutputSetting.SerialNumber; } public static string GetString(ISquib squib) { if (squib.SerialNumber.StartsWith(SensorConstants.TEST_SPECIFIC_SQUIB)) { return Strings.Strings.SquibSetting; } return squib.SerialNumber; } public static string GetString(ISensorData sensor) { if (sensor.IsTestSpecificDigitalOutput) { return Strings.Strings.DigitalOutputSetting; } if (sensor.IsTestSpecificSquib) { return Strings.Strings.SquibSetting; } if (sensor.IsTestSpecificDigitalIn) { return Strings.Strings.DigitalIn; } if (sensor.IsTestSpecificUart) { return Strings.Strings.UART; } if (sensor.IsTestSpecificStreamOutput) { return Strings.Strings.StreamOut; } if (sensor.IsTestSpecificStreamInput) { return Strings.Strings.StreamIn; } if (sensor.IsDigitalInput()) { return sensor.SerialNumber; } if (sensor.IsDigitalOutput()) { return sensor.IsTestSpecificDigitalOutput ? Strings.Strings.DigitialOutput : sensor.SerialNumber; } if (sensor.IsSquib()) { return sensor.SerialNumber; } if (sensor.IsUart()) { return sensor.SerialNumber; } if (sensor.IsStreamOutput()) { return sensor.SerialNumber; } if (string.IsNullOrWhiteSpace(sensor.Comment)) { return sensor.SerialNumber; } return $"{sensor.Comment} ({sensor.SerialNumber})"; } public static string GetString(ISensorData sensor, IHardwareChannel hardwarechannel) { if (hardwarechannel != null && sensor.IsTestSpecificEmbedded) { if (hardwarechannel.IsAnalog && !hardwarechannel.IsTSRAIR) { return Strings.Strings.VoltageInput; } var serial = !string.IsNullOrWhiteSpace(hardwarechannel.ModuleSerialNumber) ? hardwarechannel.ModuleSerialNumber : hardwarechannel.GetParentDAS().SerialNumber; var tokens = serial.Split(new[] { "-" }, StringSplitOptions.RemoveEmptyEntries); switch (tokens[tokens.Length-1]) { case DFConstantsAndEnums.ARS_SERIAL_APPEND: //case Enums.Hardware.HardwareTypes.EMB_ANG_ARS: switch (hardwarechannel.ChannelNumber % 3) { case DFConstantsAndEnums.CHANNEL_X: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_ARS1}"; case DFConstantsAndEnums.CHANNEL_Y: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_ARS2}"; case DFConstantsAndEnums.CHANNEL_Z: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_ARS3}"; default: return string.Empty; } case DFConstantsAndEnums.ANGACCEL_SERIAL_APPEND: //case Enums.Hardware.HardwareTypes.EMB_ANG_ARS: switch (hardwarechannel.ChannelNumber % 3) { case DFConstantsAndEnums.CHANNEL_X: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_Angular1}"; case DFConstantsAndEnums.CHANNEL_Y: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_Angular2}"; case DFConstantsAndEnums.CHANNEL_Z: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_Angular3}"; default: return string.Empty; } case "ATM": case DFConstantsAndEnums.ATMOSPHERIC_SERIAL_APPEND: //case Enums.Hardware.HardwareTypes.EMB_ATM: switch (hardwarechannel.ChannelNumber % 3) { case DFConstantsAndEnums.CHANNEL_TEMPERATURE: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_Temperature}"; case DFConstantsAndEnums.CHANNEL_HUMIDITY: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_Humidity}"; case DFConstantsAndEnums.CHANNEL_PRESSURE: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_Atmosphere}"; default: return string.Empty; } case DFConstantsAndEnums.HIGHG_SERIAL_APPEND: //case Enums.Hardware.HardwareTypes.EMB_LIN_ACC_HI: switch (hardwarechannel.ChannelNumber % 3) { case DFConstantsAndEnums.CHANNEL_X: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_HighGLinear1}"; case DFConstantsAndEnums.CHANNEL_Y: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_HighGLinear2}"; case DFConstantsAndEnums.CHANNEL_Z: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_HighGLinear3}"; default: return string.Empty; } case DFConstantsAndEnums.LOWG_SERIAL_APPEND: //case Enums.Hardware.HardwareTypes.EMB_LIN_ACC_LO: switch (hardwarechannel.ChannelNumber % 3) { case DFConstantsAndEnums.CHANNEL_X: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_LowGLinear1}"; case DFConstantsAndEnums.CHANNEL_Y: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_LowGLinear2}"; case DFConstantsAndEnums.CHANNEL_Z: return $"{tokens[0]}-{Strings.Strings.TSA_Embedded_LowGLinear3}"; default: return string.Empty; } } return string.Empty; } else { return GetString(sensor); } } private string GetString(IDragAndDropItem item) { if (item is IAnalogSensor analog) { if (string.IsNullOrWhiteSpace(analog.Description)) { return $"{analog.SerialNumber}"; } return $"{analog.Description} ({analog.SerialNumber})"; } if (item is IDigitalInputSetting digitalIn) { return $"{digitalIn.SerialNumber}"; } if (item is IDigitalOutputSetting digitalOut) { return $"{digitalOut.SerialNumber}"; } if (item is ISquib squib) { return $"{squib.SerialNumber}"; } if (item is IUartIOSetting uart) { return $"{uart.SerialNumber}"; } if (item is IStreamOutputSetting streamOut) { return $"{streamOut.SerialNumber}"; } if (item is IStreamInputSetting streamIn) { return $"{streamIn.SerialNumber}"; } return "---"; } public IHardwareChannel HardwareChannel { get; private set; } public void SetHardwareChannel(IHardwareChannel hardwareChannel) { HardwareChannel = hardwareChannel; if (null == hardwareChannel) { DASId = -1; DASChannelIndex = -1; TestSampleRate = 0; Hardware = ""; HardwareId = ""; HardwarePropertyChanged(); } else { DASId = hardwareChannel.GetParentDAS().DASId; DASChannelIndex = hardwareChannel.ChannelNumber; Hardware = hardwareChannel.ToString(); HardwareId = hardwareChannel.GetId(); HardwarePropertyChanged(); } } private IGroup _group; public IGroup Group { get => _group; set { _group = value; OnPropertyChanged("IsoCode"); } } private string _groupName = ""; public string GroupName { get => _groupName; set { _groupName = value; OnPropertyChanged("GroupName"); } } public double TestSampleRate { get; set; } private string _hardware = ""; public string Hardware { get { if (HasEID) { if (string.IsNullOrWhiteSpace(_hardware)) { return Strings.Strings.AssignedByID; } return $"{Strings.Strings.AssignedByID} \\ {_hardware}"; } return _hardware; } set => _hardware = value; } public bool IsChannelComplete => HardwareValid && SensorValid; public string HardwareId { get; set; } public string Sensor { get { if (null != SensorData) { return GetString(SensorData, HardwareChannel); } if (null != DragAndDropItem) { return GetString(DragAndDropItem); } return ""; } } /// /// returns true if the sensor on the channel is an embedded sensor or not /// 18248 Disable link-to-SensorDB for Embedded Sensors /// public bool EmbeddedSensor { get { if (null != SensorData) { return SensorData.IsTestSpecificEmbedded; } if (null != HardwareChannel) { return HardwareChannel.GetParentDAS().IsTSRAIR(); } return false; } } /// /// returns true if the sensor on the channel does not allow the Range to be modified /// (a TSR AIR sensor that is not LowG nor ARS). /// 29759 Allow Adjustable Channel Ranges in Parameters for TSR AIR /// public bool NonRangeModifiableSensor { get { if (EmbeddedSensor) { if (VoltageInsertionSensor) { return false; } if (RangeModifiableSensorARS || RangeModifiableSensorLowG) { return false; } return true; } return false; } } /// /// whether the channel has a calibration less voltage measurement channel /// public bool VoltageInsertionSensor { get { if (EmbeddedSensor) { return !HardwareChannel.IsTSRAIR; } return false; } } /// /// returns true the sensor on the channel is a TSR AIR LowG. /// 29759 Allow Adjustable Channel Ranges in Parameters for TSR AIR /// public bool RangeModifiableSensorLowG { get { if (EmbeddedSensor) { return HardwareChannel.ModuleSerialNumber.EndsWith("Low g"); } return false; } } /// /// returns true the sensor on the channel is a TSR AIR ARS. /// 29759 Allow Adjustable Channel Ranges in Parameters for TSR AIR /// public bool RangeModifiableSensorARS { get { if (EmbeddedSensor) { return HardwareChannel.ModuleSerialNumber.EndsWith("ARS"); } return false; } } public bool GroupNameEditable { get; set; } public bool GroupNameValid { get; set; } = true; public bool IsoCodeValid { get; set; } = true; public bool IsoChannelNameValid { get; set; } = true; public bool UserCodeValid { get; set; } = true; public bool UserChannelNameValid { get; set; } = true; public bool BorderShouldShowOutOfDate { get; set; } = false; public double EmbeddedCapacity { get; set; } = 0.0D; public double EmbeddedCapacityDisplay { get; set; } = 0D; public long ChannelId { get; set; } public bool IsAnalog { get { if (IsBlank()) { return false; } if (null != SensorData) { return !(SensorData.IsSquib() || SensorData.IsDigitalInput() || SensorData.IsDigitalOutput() || SensorData.IsUart() || SensorData.IsStreamInput() || SensorData.IsStreamOutput()); } if (null != DragAndDropItem) { return DragAndDropItem is IAnalogSensor; } if (null != HardwareChannel) { return HardwareChannel.IsAnalog; } return true; } } public bool NonLinearAndNotPolynomial { get { return NonLinear && (SensorData.GetLatestCalibration().IRTraccCalculationType != NonLinearStyles.Polynomial); } } //FB14606 Don't show ZeroMethod parameters for NonLinear & Linear Added Sensors public bool NonLinear { get { if (IsBlank() || !IsAnalog) { return false; } if (null != SensorData && SensorData.SerialNumber != SensorConstants.TEST_SPECIFIC_ANALOG_SERIAL && SensorData.SerialNumber != SensorConstants.TEST_SPECIFIC_CLOCK_SERIAL) { return SensorData.GetLatestCalibration()?.NonLinear ?? false; } if (null != DragAndDropItem) { return !(DragAndDropItem as IAnalogSensor)?.NonLinearCalculationType?.Equals(string.Empty) ?? false; } return false; } } public bool IsSquib { get { if (IsBlank()) { return false; } if (null != SensorData) { return SensorData.IsSquib(); } if (null != DragAndDropItem) { return DragAndDropItem is ISquib; } if (null != HardwareChannel) { return HardwareChannel.IsSquib; } return true; } } public bool IsDigitalIn { get { if (IsBlank()) { return false; } if (null != SensorData) { return SensorData.IsDigitalInput(); } if (null != DragAndDropItem) { return DragAndDropItem is IDigitalInputSetting; } if (null != HardwareChannel) { return HardwareChannel.IsDigitalIn; } return true; } } public bool IsDigitalOut { get { if (IsBlank()) { return false; } if (null != SensorData) { return SensorData.IsDigitalOutput(); } if (null != DragAndDropItem) { return DragAndDropItem is IDigitalOutputSetting; } if (null != HardwareChannel) { return HardwareChannel.IsDigitalOut; } return true; } } public bool IsClock { get { if (IsBlank()) { return false; } if (null != HardwareChannel) { return HardwareChannel.IsClock; } return false; } } /// /// returns true if this group channel has a hardware channel assigned and it belongs to a TSR AIR /// public bool IsTSRAIR { get { if (IsBlank()) { return false; } if (null == HardwareChannel) { return false; } return HardwareChannel.IsTSRAIR; } } /// /// returns true if group channel has a hardware channel assigned and that hardware channel is a TSR AIR low g /// embedded hardware channel /// public bool IsTSRAIRLowG { get { if (!IsTSRAIR) { return false; } return SensorConstants.IsTSRAirLowGChannel(HardwareChannel.ModuleSerialNumber); } } public bool IsUart { get { if (IsBlank()) { return false; } if (null != SensorData) { return SensorData.IsUart(); } if (null != DragAndDropItem) { return DragAndDropItem is IUartIOSetting; } if (null != HardwareChannel) { return HardwareChannel.IsUart; } return false; } } public bool IsStreamOut { get { if (IsBlank()) { return false; } if (null != SensorData) { return SensorData.IsStreamOutput(); } if (null != DragAndDropItem) { return DragAndDropItem is IStreamOutputSetting; } if (null != HardwareChannel) { return HardwareChannel.IsStreamOut; } return false; } } public bool IsStreamIn { get { if (IsBlank()) { return false; } if (null != SensorData) { return SensorData.IsStreamInput(); } if (null != DragAndDropItem) { return DragAndDropItem is IStreamInputSetting; } if (null != HardwareChannel) { return HardwareChannel.IsStreamIn; } return false; } } public bool IsCH10 => TMNSConfig.IsCh10(StreamOutUDPProfile); public bool IsTMNS => TMNSConfig.IsTMNS(StreamOutUDPProfile); public bool IsIENA => TMNSConfig.IsIENA(StreamOutUDPProfile); public bool IsUARTStream => TMNSConfig.IsUART(StreamOutUDPProfile); public delegate int GetMaxDisplayOrderDelegate(); public delegate void AddChannelsToGroupDelegate(IGroupChannel[] channels); /// /// sorts the channels into the channel order they should be by default when adding new hardware to a test /// 18245 Order the TSR-Air channels a more desirable way /// /// /// /// private static int TSRAirSort(IHardwareChannel left, IHardwareChannel right) { GetTSRAppendString(left, out var leftSerial, out var leftModuleName, out var leftChannelNumber, out var leftHardware); GetTSRAppendString(right, out var rightSerial, out var rightModuleName, out var rightChannelNumber, out var rightHardware); if (leftModuleName.Equals(rightModuleName)) { return leftChannelNumber.CompareTo(rightChannelNumber); } return GetTSROrder(leftModuleName).CompareTo(GetTSROrder(rightModuleName)); } /// /// gets the order of TSR modules relative to each other when adding channels to a new group or test setup /// /// /// private static int GetTSROrder(string moduleName) { /* Low G Linear 1, 2, 3, High G Linear 1, 2, 3, Angular Rate 1, 2, 3, Angular Acc 1, 2, 3, Temp, Pressure, Humidity*/ switch (moduleName) { case DFConstantsAndEnums.LOWG_SERIAL_APPEND: return 0; case DFConstantsAndEnums.HIGHG_SERIAL_APPEND: return 1; case DFConstantsAndEnums.ARS_SERIAL_APPEND: return 2; case DFConstantsAndEnums.ANGACCEL_SERIAL_APPEND: return 3; case DFConstantsAndEnums.ATMOSPHERIC_SERIAL_APPEND: return 4; //these aren't actually channels we use currently .. case DFConstantsAndEnums.OPTICAL_SERIAL_APPEND: return 5; case DFConstantsAndEnums.MAGNETIC_SERIAL_APPEND: return 6; case DFConstantsAndEnums.MAGNETICSWITCH_SERIAL_APPEND: return 7; case DFConstantsAndEnums.MICROPHONE_SERIAL_APPEND: return 8; case DFConstantsAndEnums.RTCSECONDANDMARKER_SERIAL_APPEND: return 9; case DFConstantsAndEnums.RTCCLOCKNANOPAD_SERIAL_APPEND: return 10; default: return 11; } } private static void EliminateVariantChannels(IDASHardware h, ref List channels) { if (h.DASTypeEnum != Enums.Hardware.HardwareTypes.DIR && h.DASTypeEnum != Enums.Hardware.HardwareTypes.DKR) { return; } for (var i = channels.Count - 1; i >= 0; i--) { var channel = channels[i]; GetTSRAppendString(channel, out var serial, out var moduleName, out var channelNumber, out var hardware); if (!HardwareConstants.HasEmbeddedChannelType(h.DASTypeEnum, moduleName)) { channels.RemoveAt(i); } } } /// /// creates a new group channel for display in the Parameters step /// public static GroupChannel CreateTSRAirChannel(IGroup group, ISensorData sd, IChannelSetting[] channelDefaults) { var groupChannel = new GroupChannel(true, group.DisplayName, group, channelDefaults); return groupChannel; } /// /// creates a new group channel given an embedded hardware channel /// public static GroupChannel CreateTSRAirChannel(IHardwareChannel channel, IGroup group, ISensorData sd, IChannelSetting[] channelDefaults) { var sensorId = sd.DatabaseId; var groupChannel = new GroupChannel(true, group.DisplayName, group, channelDefaults) { DASId = channel.GetParentDAS().DASId, DASChannelIndex = channel.ChannelNumber, Hardware = channel.ToString(), SensorId = sensorId, IsoCode = "???????????????A" }; groupChannel.SetHardwareChannel(channel); groupChannel.RemoveSensorVisibility = Visibility.Hidden; groupChannel.SensorData = sd; //29759 Allow Adjustable Channel Ranges in Parameters for TSR AIR //Set the Capacity here so that the Range will be set correctly in SetSensor below. var moduleSN = channel.ModuleSerialNumber; if (SensorConstants.IsTSRAirLowGChannel(moduleSN)) { sd.Capacity = SensorConstants.DefaultRangeLowG; groupChannel.InitializeLowG(); } else if (SensorConstants.IsTSRAirHighGChannel(moduleSN)) { sd.Capacity = SensorConstants.DefaultRangeHiG; groupChannel.InitializeHighG(); } else if (SensorConstants.IsTSRAirARSChannel(moduleSN)) { sd.Capacity = SensorConstants.DefaultRangeARS; groupChannel.InitializeAngular(); } else if (SensorConstants.IsTSRAirAtmChannel(moduleSN)) { switch (channel.ChannelNumber) { case SensorConstants.TSRAirTemperatureChannel: sd.Capacity = SensorConstants.DefaultRangeTemperature; groupChannel.InitializeTemperature(); break; case SensorConstants.TSRAirHumidityChannel: sd.Capacity = SensorConstants.DefaultRangeHumidity; groupChannel.InitializeHumidity(); break; case SensorConstants.TSRAirPressureChannel: sd.Capacity = SensorConstants.DefaultRangePressure; groupChannel.InitializePressure(); break; default: //Shouldn't get here sd.Capacity = 2400; break; } } else { sd.Capacity = 2400; } if (groupChannel.SensorCalibration != null) { groupChannel.SensorCalibration.SerialNumber = sd.SerialNumber; } groupChannel.SetSensor(sd, true); //all the TSR AIR channels should use none //MS30446 and MS31788 groupChannel.ZeroMethod = ZeroMethodType.None; groupChannel.IsoChannelName = GetEmbeddedSensorString(channel); groupChannel.UserChannelName = GetEmbeddedSensorString(channel); return groupChannel; } /// /// creates a new group channel given a thermocoupler hardware channel /// public static GroupChannel CreateSLICETCChannel(IHardwareChannel channel, IGroup group, ISensorData sd, IChannelSetting[] channelDefaults) { var sensorId = sd.DatabaseId; var groupChannel = new GroupChannel(true, group.DisplayName, group, channelDefaults) { DASId = channel.GetParentDAS().DASId, DASChannelIndex = channel.ChannelNumber, Hardware = channel.ToString(), SensorId = sensorId, IsoCode = "???????????????A" }; groupChannel.SetHardwareChannel(channel); groupChannel.RemoveSensorVisibility = Visibility.Hidden; groupChannel.SensorData = sd; groupChannel.SetSensor(sd, true); groupChannel.ZeroMethod = ZeroMethodType.None; return groupChannel; } /// /// creates a new group channel given an embedded hardware channel /// public static GroupChannel CreateVoltageInsertionChannel(IHardwareChannel channel, IGroup group, ISensorData sd, IChannelSetting[] channelDefaults) { var sensorId = sd.DatabaseId; var groupChannel = new GroupChannel(true, group.DisplayName, group, channelDefaults) { DASId = channel.GetParentDAS().DASId, DASChannelIndex = channel.ChannelNumber, Hardware = channel.ToString(), SensorId = sensorId, IsoCode = "???????????????A" }; groupChannel.SetHardwareChannel(channel); groupChannel.RemoveSensorVisibility = Visibility.Hidden; groupChannel.SensorData = sd; sd.Capacity = VOLTAGE_INSERTION_CAPACITY; sd.BridgeResistance = -1; //33145: Voltage insertion channel defaults per Nate sd.Bridge = SensorConstants.BridgeType.HalfBridge; sd.Calibration.Records.Records[0].Sensitivity = 1D; sd.FilterClass = new FilterClass(FilterClassType.None); groupChannel.InitializeVoltageInsertion(); if (groupChannel.SensorCalibration != null) { groupChannel.SensorCalibration.RemoveOffset = false; groupChannel.SensorCalibration.SerialNumber = sd.SerialNumber; } groupChannel.SetSensor(sd, true); groupChannel.IsoChannelName = $"{channel} {Strings.Strings.Voltage}"; groupChannel.UserChannelName = $"{channel} {Strings.Strings.Voltage}"; return groupChannel; } /// /// Creates TSR Air channels for a given hardware and adds them to the test /// /// public static void CreateTSRAirChannels(IDASHardware h, IGroup group, AddChannelsToGroupDelegate addChannelsToGroup, GetMaxDisplayOrderDelegate getMaxDisplayOrder, IChannelSetting[] channelDefaults, ISensorData analog, ISensorData clock, ISensorData streamout, ISensorData uart, bool bEditGroup) { var channels = h.GetIHardwareChannels().ToList(); channels.Sort(TSRAirSort); EliminateVariantChannels(h, ref channels); var channelsToAdd = new List(); foreach (var channel in channels) { //these are channels which are being added to the db, but aren't shown on the screen, which causes some confusion //when you then delete the hardware and suddenly the channels appear again ... //27002 streamout will be set to null if we don't have Streaming mode selected, so don't auto-add if (ExcludeChannelFromCount(channel) || (channel.IsStreamOut && null == streamout) || (channel.IsUart && null == uart)) { continue; } var sd = channel.IsClock ? clock : channel.IsStreamOut ? streamout : channel.IsUart ? uart : analog; var groupChannel = CreateTSRAirChannel(channel, group, sd, channelDefaults); channelsToAdd.Add(groupChannel); } AddChannelsToGroup(group, addChannelsToGroup, getMaxDisplayOrder, bEditGroup, channelsToAdd); } /// /// Creates SLICE6 AIR-TC channels for a given hardware and adds them to the test /// /// public static void CreateSLICETCChannels( IDASHardware h, IGroup group, AddChannelsToGroupDelegate addChannelsToGroup, GetMaxDisplayOrderDelegate getMaxDisplayOrder, IChannelSetting[] channelDefaults, ISensorData thermocoupler, ISensorData streamout, bool bEditGroup) { var channels = h.GetIHardwareChannels().ToList(); var channelsToAdd = new List(); foreach (var channel in channels) { var sd = channel.IsStreamOut ? streamout : thermocoupler; var groupChannel = CreateSLICETCChannel(channel, group, sd, channelDefaults); channelsToAdd.Add(groupChannel); } AddChannelsToGroup(group, addChannelsToGroup, getMaxDisplayOrder, bEditGroup, channelsToAdd); } /// /// Adds channels to a Group /// /// /// /// /// /// private static void AddChannelsToGroup( IGroup group, AddChannelsToGroupDelegate addChannelsToGroup, GetMaxDisplayOrderDelegate getMaxDisplayOrder, bool bEditGroup, List channelsToAdd) { var existingCount = 1 + getMaxDisplayOrder(); for (var i = 0; i < channelsToAdd.Count; i++) { if (bEditGroup) { channelsToAdd[i].GroupChannelOrder = existingCount; } else { channelsToAdd[i].TestSetupOrder = existingCount; } existingCount++; } group.GroupChannelList.AddRange(channelsToAdd.ToArray()); addChannelsToGroup(channelsToAdd.ToArray()); } public bool HardwareValid => DASId > 0 && DASChannelIndex >= 0; public bool SensorValid => SensorId > 0; public GroupChannel(bool bGroupNameEditable, string groupName, IGroup group, IChannelSetting[] channelDefaults, bool borderShouldShowOutOfDate = false) { ChannelSettings = channelDefaults; RegisterCommands(); Group = group; SetSensorData(null, null); HardwareChannel = null; Hardware = ""; HardwareId = ""; LastModified = DateTime.Now; LastModifiedBy = ""; SensorId = -1; TestSetupOrder = -1; GroupChannelOrder = -1; DASChannelIndex = -1; DASId = -1; UserChannelName = ""; UserCode = ""; IsoChannelName = ""; IsoCode = ""; GroupName = groupName; GroupNameEditable = bGroupNameEditable; BorderShouldShowOutOfDate = borderShouldShowOutOfDate; } /// /// allows turning off the "SetPageModified" event /// I determined that this was causing the page to get modified in some unexpected situations like loading a test setup ... /// http://manuscript.dts.local/f/cases/36875/DataPro-randomly-goes-back-to-test-setup-list-when-hit-the-run-test-button-and-popup-save /// This is now used to turn off those page modified when loading a channel from the database /// private readonly bool _notifyOff = false; public GroupChannel(IChannelDbRecord channel, IGroup group, bool groupNameEditable, IDictionary sensorLookup, IDictionary hardwareLookup, IChannelSetting[] channelDefaults, bool borderShouldShowOutOfDate = false) { try { _notifyOff = true; ChannelSettings = channelDefaults; RegisterCommands(); Group = group; HardwareChannel = null; Id = Convert.ToInt32(channel.Id); var oSensorId = channel.SensorId; if (DBNull.Value.Equals(oSensorId)) { SetSensorData(null, null); SensorId = -1; } else { SensorId = Convert.ToInt32(oSensorId); if (sensorLookup.ContainsKey(SensorId)) { SetSensorData(sensorLookup[SensorId], null); } else { SetSensorData(null, null); } } DASChannelIndex = Convert.ToInt32(channel.DASChannelIndex); var oDASId = channel.DASId; if (DBNull.Value.Equals(oDASId)) { DASId = -1; Hardware = ""; HardwareId = ""; } else { DASId = Convert.ToInt32(oDASId); if (hardwareLookup.ContainsKey(DASId)) { var hardware = hardwareLookup[DASId]; var channels = hardware.GetIHardwareChannels(); for (var i = 0; i < channels.Length; i++) { if (channels[i].ChannelNumber == DASChannelIndex) { Hardware = channels[i].ToString(hardwareLookup.Values.ToArray()); HardwareId = channels[i].GetId(); HardwareChannel = channels[i]; break; } } } else { //if we didn't find the hardware, but the sensor is test specific embedded, remove the sensor assignment //18250 Empty channels with embedded sensors remain in Test Setup after deleting TSR-AIR DAS if (null != SensorData && (SensorData.IsTestSpecificEmbedded || SensorData.IsTestSpecificEmbeddedClock)) { SetSensorData(null, null); } } } // 29916 & 29917 Display Capacity and Units for TSR AIR // in the Parameters nav step of Edit Test Setup if (SensorData != null && SensorData.IsTestSpecificEmbedded && !string.IsNullOrWhiteSpace(Hardware)) { SetCapacityAndUnits(Hardware); } LastModified = Convert.ToDateTime(channel.LastModified); LastModifiedBy = channel.LastModifiedBy; TestSetupOrder = Convert.ToInt32(channel.TestSetupOrder); GroupChannelOrder = Convert.ToInt32(channel.GroupChannelOrder); UserChannelName = channel.UserChannelName; UserCode = channel.UserCode; IsoChannelName = channel.IsoChannelName; IsoCode = channel.IsoCode; IsDisabled = Convert.ToBoolean(channel.Disabled); GroupName = group.DisplayName; GroupNameEditable = groupNameEditable; BorderShouldShowOutOfDate = borderShouldShowOutOfDate; } finally { _notifyOff = false; } } /// /// sets up a channel with embedded calibration units requested /// (if SensorData is defined) /// /// private void SetEmbeddedCalIfPossible(string eu) { if (null == SensorData) { return; } SensorCalibration = SensorData.NewEmbeddedSC(eu); } private const double VOLTAGE_INSERTION_CAPACITY = 2400D; public void InitializeVoltageInsertion() { EmbeddedCapacity = VOLTAGE_INSERTION_CAPACITY; EmbeddedCapacityDisplay = VOLTAGE_INSERTION_CAPACITY; if (null != SensorData) { BridgeType = SensorData.Bridge; } SetEmbeddedCalIfPossible(SensorConstants.VOLTAGE_INSERTION_UNIT); } /// /// sets up a channel embedded capacity/display/EU for TSR AIR low g /// public void InitializeLowG() { EmbeddedCapacity = SensorConstants.DefaultRangeLowG; EmbeddedCapacityDisplay = SensorConstants.DefaultRangeLowGDisplay; //33415 Voltage insertion channel should be half bridge, but make sure we init TSRAIR too to full bridge if (null != SensorData) { BridgeType = SensorData.Bridge; } SetEmbeddedCalIfPossible(SensorConstants.TSRAIR_ACCEL_UNIT); //all the TSR AIR channels should use none //MS30446 and MS31788 ZeroMethod = ZeroMethodType.None; } /// /// sets up a channel embedded capacity/display/eu for TSR AIR high g /// public void InitializeHighG() { EmbeddedCapacity = SensorConstants.DefaultRangeHiG; //400 g EmbeddedCapacityDisplay = EmbeddedCapacity; //33415 Voltage insertion channel should be half bridge, but make sure we init TSRAIR too to full bridge if (null != SensorData) { BridgeType = SensorData.Bridge; } SetEmbeddedCalIfPossible(SensorConstants.TSRAIR_ACCEL_UNIT); //all the TSR AIR channels should use none //MS30446 and MS31788 ZeroMethod = ZeroMethodType.None; } /// /// sets up a channel embedded capacity/display/eu for TSR Air Angular /// public void InitializeAngular() { EmbeddedCapacity = SensorConstants.DefaultRangeARS; // 2000 deg/s EmbeddedCapacityDisplay = EmbeddedCapacity; //33415 Voltage insertion channel should be half bridge, but make sure we init TSRAIR too to full bridge if (null != SensorData) { BridgeType = SensorData.Bridge; } SetEmbeddedCalIfPossible(SensorConstants.TSRAIR_ARS_UNIT); //all the TSR AIR channels should use none //MS30446 and MS31788 ZeroMethod = ZeroMethodType.None; } /// /// sets up a channel for TSR AIR temperature /// public void InitializeTemperature() { EmbeddedCapacity = SensorConstants.DefaultRangeTemperature; // 85 degees C EmbeddedCapacityDisplay = EmbeddedCapacity; //33415 Voltage insertion channel should be half bridge, but make sure we init TSRAIR too to full bridge if (null != SensorData) { BridgeType = SensorData.Bridge; } SetEmbeddedCalIfPossible(SensorConstants.TSRAIR_TEMPERATURE_UNIT); //all the TSR AIR channels should use none //MS30446 and MS31788 ZeroMethod = ZeroMethodType.None; } /// /// sets up a channel for TSR AIR humidity /// public void InitializeHumidity() { EmbeddedCapacity = SensorConstants.DefaultRangeHumidity; // 100% EmbeddedCapacityDisplay = EmbeddedCapacity; //33415 Voltage insertion channel should be half bridge, but make sure we init TSRAIR too to full bridge if (null != SensorData) { BridgeType = SensorData.Bridge; } SetEmbeddedCalIfPossible(SensorConstants.TSRAIR_HUMIDITY_UNIT); //all the TSR AIR channels should use none //MS30446 and MS31788 ZeroMethod = ZeroMethodType.None; } /// /// sets up a channel for TSR AIR pressure /// public void InitializePressure() { EmbeddedCapacity = SensorConstants.DefaultRangePressure; //Actually 15.95 PSI (1100 hPa x 0.0145) EmbeddedCapacityDisplay = EmbeddedCapacity; //33415 Voltage insertion channel should be half bridge, but make sure we init TSRAIR too to full bridge if (null != SensorData) { BridgeType = SensorData.Bridge; } SetEmbeddedCalIfPossible(SensorConstants.TSRAIR_PRESSURE_UNIT); //all the TSR AIR channels should use none //MS30446 and MS31788 ZeroMethod = ZeroMethodType.None; } private void SetCapacityAndUnits(string userChannelName) { if (userChannelName.Contains(DFConstantsAndEnums.USER_CHANNEL_NAME_LOWG)) { InitializeLowG(); } else if (userChannelName.Contains(DFConstantsAndEnums.USER_CHANNEL_NAME_HIGHG)) { InitializeHighG(); } else if (userChannelName.Contains(DFConstantsAndEnums.USER_HARDWARE_NAME_ANGULAR_RATE)) { InitializeAngular(); } else if (userChannelName.Contains(DFConstantsAndEnums.USER_HARDWARE_NAME_TEMPERATURE)) { InitializeTemperature(); } else if (userChannelName.Contains(DFConstantsAndEnums.USER_HARDWARE_NAME_HUMIDITY)) { InitializeHumidity(); } else if (userChannelName.Contains(DFConstantsAndEnums.USER_HARDWARE_NAME_PRESSURE)) { InitializePressure(); } else if (null != SensorData && SensorData.IsTestSpecificEmbedded) { InitializeVoltageInsertion(); } SensorCalibration.SerialNumber = SensorData.SerialNumber; } public GroupChannel(IChannelDbRecord channel, IGroup group, bool groupNameEditable, IDictionary sensorLookup, bool borderShouldShowOutOfDate = false) { Group = group; Id = channel.Id; var oSensorId = channel.SensorId; if (DBNull.Value.Equals(oSensorId)) { SensorId = -1; SetSensorData(null, null); } else { SensorId = Convert.ToInt32(oSensorId); if (sensorLookup.ContainsKey(SensorId)) { SetSensorData(sensorLookup[SensorId], null); } } DASChannelIndex = channel.DASChannelIndex; var oDASId = channel.DASId; if (DBNull.Value.Equals(oDASId)) { DASId = -1; Hardware = ""; HardwareId = "-1"; } else { DASId = Convert.ToInt32(oDASId); } HardwareChannel = null; LastModified = channel.LastModified; LastModifiedBy = channel.LastModifiedBy; TestSetupOrder = channel.TestSetupOrder; GroupChannelOrder = channel.GroupChannelOrder; UserChannelName = channel.UserChannelName; UserCode = channel.UserCode; IsoChannelName = channel.IsoChannelName; IsoCode = channel.IsoCode; IsDisabled = channel.Disabled; GroupName = group.DisplayName; GroupNameEditable = groupNameEditable; BorderShouldShowOutOfDate = borderShouldShowOutOfDate; } public int CompareTo(IGroupChannel other) { var aBlank = IsBlank(); var bBlank = other.IsBlank(); if (aBlank) { if (bBlank) { return 0; } return 1; } if (bBlank) { return -1; } var ret = TestSetupOrder.CompareTo(other.TestSetupOrder); if (0 != ret) { return ret; } if (null == Group) { if (null != other.Group) { return -1; } return 1; } ret = Group.DisplayOrder.CompareTo(other.Group.DisplayOrder); if (0 != ret) { return ret; } ret = GroupChannelOrder.CompareTo(other.GroupChannelOrder); if (0 != ret) { return ret; } ret = Id.CompareTo(other.Id); if (0 != ret) { return ret; } ret = string.Compare(IsoChannelName, other.IsoChannelName, StringComparison.Ordinal); if (0 != ret) { return ret; } return string.Compare(UserChannelName, other.UserChannelName, StringComparison.Ordinal); } private IsoViewMode _isoViewMode; public void SetIsoViewMode(IsoViewMode isoViewMode) { _isoViewMode = isoViewMode; OnPropertyChanged("ChannelName"); OnPropertyChanged("Code"); } public string ChannelName { get { switch (_isoViewMode) { case IsoViewMode.ISOOnly: return IsoChannelName; case IsoViewMode.ISOAndUserCode: return $"{UserChannelName}/{IsoChannelName}"; case IsoViewMode.UserCodeOnly: case IsoViewMode.ChannelNameOnly: return UserChannelName; } return Strings.Strings.Table_NA; } } public string Code { get { switch (_isoViewMode) { case IsoViewMode.ISOOnly: return IsoCode; case IsoViewMode.ISOAndUserCode: return $"{UserCode}/{IsoCode}"; case IsoViewMode.UserCodeOnly: return UserCode; case IsoViewMode.ChannelNameOnly: return string.Empty; } return Strings.Strings.Table_NA; } } public ISensorData SensorData { get; set; } public ISensorCalibration SensorCalibration { get; set; } public void SetSensorCalibration(ISensorCalibration calibration) { SensorCalibration = calibration; } public IDragAndDropItem DragAndDropItem { get; set; } public bool HasEID { get { if (null != SensorData) { return !string.IsNullOrWhiteSpace(SensorData.EID); } if (null != DragAndDropItem) { if (DragAndDropItem is IAnalogSensor analogSensor) { return !string.IsNullOrWhiteSpace(analogSensor.EID); } if (DragAndDropItem is IDigitalInputSetting digitalInput) { return !string.IsNullOrWhiteSpace(digitalInput.EID); } if (DragAndDropItem is ISquib squib) { return !string.IsNullOrWhiteSpace(squib.ID); } } return false; } } public override string ToString() { var channelName = GetChannelName(IsoViewModeStatic.ViewMode); var iso = GetChannelCode(IsoViewModeStatic.ViewMode); if (IsoViewModeStatic.ViewMode == IsoViewMode.UserCodeOnly || IsoViewModeStatic.ViewMode == IsoViewMode.ChannelNameOnly) { return channelName.Contains(Sensor) ? channelName : $"{channelName} / {Sensor}"; } return $"{ChannelName} / {iso} [{Sensor}]"; } public string GetChannelName(IsoViewMode isoViewMode) { var sensorSerial = SensorData?.SerialNumber ?? DragAndDropItem?.SerialNumber ?? string.Empty; if (sensorSerial == SensorConstants.TEST_SPECIFIC_ANALOG_SERIAL) { sensorSerial = Strings.Strings.Table_NA; } if (IsStreamIn) { sensorSerial = Strings.Strings.StreamIn; } if (IsStreamOut) { sensorSerial = Strings.Strings.StreamOut; } if (IsUart) { sensorSerial = Strings.Strings.UART; } switch (isoViewMode) { case IsoViewMode.ISOOnly: return !string.IsNullOrWhiteSpace(IsoChannelName) ? IsoChannelName : sensorSerial; case IsoViewMode.ChannelNameOnly: case IsoViewMode.UserCodeOnly: return !string.IsNullOrWhiteSpace(UserChannelName) ? UserChannelName : sensorSerial; case IsoViewMode.ISOAndUserCode: default: if (string.IsNullOrWhiteSpace(IsoChannelName)) { return UserChannelName; } if (string.IsNullOrWhiteSpace(UserChannelName)) { return IsoChannelName; } if (string.IsNullOrWhiteSpace(IsoChannelName) && string.IsNullOrWhiteSpace(UserChannelName)) { return SensorData?.SerialNumber ?? string.Empty; } return $"{UserChannelName}\\{IsoChannelName}"; } } public string GetChannelCode(IsoViewMode isoViewMode) { switch (isoViewMode) { case IsoViewMode.ChannelNameOnly: return string.Empty; case IsoViewMode.ISOOnly: return IsoCode; case IsoViewMode.UserCodeOnly: return UserCode; case IsoViewMode.ISOAndUserCode: default: if (string.IsNullOrWhiteSpace(IsoCode)) { return UserCode; } if (string.IsNullOrWhiteSpace(UserCode)) { return IsoCode; } return $"{UserCode}\\{IsoCode}"; } } // holds the ac coupling setting for the channel // only valid for TSR AIR // http://manuscript.dts.local/f/cases/29760/Implement-ACCoupleEnable-for-TSR-AIR private IChannelSetting _acCouplingSetting; private IChannelSetting _rangeSetting; /// /// gets/sets the value for the channel setting range /// public double Range { get => _rangeSetting.DoubleValue; set { _rangeSetting.DoubleValue = value; MarkPropertyChanged("Range"); } } private IChannelSetting _bridgeTypeSetting; public SensorConstants.BridgeType BridgeType { get { if (null == _bridgeTypeSetting.Value) { _bridgeTypeSetting.Value = _bridgeTypeSetting.DefaultValue; } return (SensorConstants.BridgeType)Enum.Parse(typeof(SensorConstants.BridgeType), _bridgeTypeSetting.Value); } set { if (null == _bridgeTypeSetting) { _bridgeTypeSetting = new ChannelSettingBase((int)SensorConstants.SensorSettings.BridgeType + 1, ChannelSettingBase.BRIDGE_TYPE, value.ToString()); } _bridgeTypeSetting.Value = value.ToString(); MarkPropertyChanged("BridgeType"); } } public double Capacity { get { if (null != SensorData) { return SensorData.Capacity; } if (DragAndDropItem is IAnalogSensor analogSensor) { return analogSensor.Capacity; } return double.NaN; } } public SensorConstants.AvailableRangesLowG RangeLowG { get { var enumValues = Enum.GetValues(typeof(SensorConstants.AvailableRangesLowG)).Cast().ToArray(); var match = Array.Find(enumValues, ev => (int)ev == Convert.ToInt32(Range)); return match; } set { Range = (int)value; OnPropertyChanged("RangeLowG"); } } private string _assemblyName = string.Empty; public string AssemblyName { get => _assemblyName; set => SetProperty(ref _assemblyName, value, "AssemblyName"); } //FB 13120 get and set filter class private IChannelSetting _filterClassSetting; public IFilterClass FilterClass { get { if (null == _filterClassSetting.Value) { _filterClassSetting.Value = _filterClassSetting.DefaultValue; } //FB 13120 first part is filterClassType and second part is frequency string[] setting = _filterClassSetting.Value.Split(','); if (Enum.TryParse(setting[0], out FilterClassType filterClassType)) { if (filterClassType == FilterClassType.AdHoc) { if (DragAndDropItem is IAnalogSensor analogSensor) { analogSensor.FilterClass = Sensors.FilterClass.CreateFilterClass(filterClassType, Convert.ToDouble(setting[1])); return analogSensor.FilterClass; } return Sensors.FilterClass.CreateFilterClass(filterClassType, Convert.ToDouble(setting[1])); } else { if (DragAndDropItem is IAnalogSensor analogSensor) { analogSensor.FilterClass = Sensors.FilterClass.CreateFilterClass(filterClassType); return analogSensor.FilterClass; } return Sensors.FilterClass.CreateFilterClass(filterClassType, 0); } } //FB 13120 we should never get here , return null will not crash just not selecting anything in combo box return null; } set { if (value == null) return; //FB 13120 store value for setting _filterClassSetting.Value = $"{value.FClass},{value.Frequency}"; //FB 13120 calculate iso code as well this was done in CFC property before if (SensorConstants.UseISOCodeFilterMapping && IsoCode.Length >= 16) { var chars = IsoCode.ToCharArray(); chars[15] = FilterClassTypeToISO(value.FClass); IsoCode = new string(chars); } //FB 13120 property changed for both CFC and FilterClass MarkPropertyChanged("FilterClass"); } } private char FilterClassTypeToISO(FilterClassType filter) { switch (filter) { case FilterClassType.None: return 'P'; case FilterClassType.Unfiltered: return '0'; case FilterClassType.CFC60: return 'D'; case FilterClassType.CFC180: return 'C'; case FilterClassType.CFC600: return 'B'; case FilterClassType.CFC1000: return 'A'; case FilterClassType.AdHoc: return 'S'; default: return 'A'; } } private IChannelSetting _polaritySetting; public string Units { get { if (null != SensorData) { if (null == SensorCalibration) { SensorCalibration = SensorData.GetLatestCalibration(); } if (null == SensorCalibration) { return Strings.Strings.Table_NA; } return SensorCalibration.EngineeringUnits; } if (DragAndDropItem is IAnalogSensor analogSensor) { return analogSensor.Units; } return Strings.Strings.Table_NA; } } //FB14606: Need ability to edit zero method in Test Setup Parameters // Test-setup-specific-ize the 3 Zero Method settings (Type, AvgStart, AvgEnd) // a la CFC, Range private IChannelSetting _zeroMethodSetting; public ZeroMethodType ZeroMethod { get { if (null == _zeroMethodSetting.Value) { _zeroMethodSetting.Value = _zeroMethodSetting.DefaultValue; } return (ZeroMethodType)Enum.Parse(typeof(ZeroMethodType), _zeroMethodSetting.Value); } set { _zeroMethodSetting.Value = value.ToString(); MarkPropertyChanged("ZeroMethod"); } } private IChannelSetting _zeroMethodStartSetting; public double ZeroMethodStart { get { if (null == _zeroMethodStartSetting.Value) { _zeroMethodStartSetting.DoubleValue = double.Parse(_zeroMethodStartSetting.DefaultValue); } return _zeroMethodStartSetting.DoubleValue; } set { _zeroMethodStartSetting.DoubleValue = value; MarkPropertyChanged("ZeroMethodStart"); } } private IChannelSetting _initialOffsetSetting; private void SetInitialOffsetSetting(IChannelSetting channelSetting) { _initialOffsetSetting = channelSetting; //16319 User must set init offset for all channels in a test setup //if initial offset value is null, it's invalid and needs to be set anyway ... if (string.IsNullOrWhiteSpace(channelSetting.Value)) { var offset = new InitialOffset(); channelSetting.Value = offset.ToDbSerializeString(); } var list = new List(); var selected = new InitialOffset(channelSetting.Value); list.Add(selected); //_availableInitialOffsets is populated by the latest calibration //however the selected could have been populated by a different calibration //we use a union of the available and the current with the current overriding one with //the same form as an available foreach (var available in _availableInitialOffsets) { if (available.Form == selected.Form) { continue; } list.Add(available); } AvailableInitialOffsets = list.ToArray(); SetInitialOffset(selected); OnPropertyChanged("InitialOffset"); } /// /// FB 23354 - Test Setup incorrectly marked as Modified when Channels step is entered. /// Setting InitialOffset directly causes a call to MarkPropertyChanged which marks /// the Test Setup as Modified, and we don't want to do that until/unless modifications are done /// (a call to OnPropertyChanged doesn't mark the page as Modified). /// /// private void SetInitialOffset(InitialOffset value) { //FB 18006 Prevent null reference exception if (value == null) { var defaultInitialOffset = new InitialOffset(); _initialOffset = defaultInitialOffset; _initialOffsetSetting.Value = defaultInitialOffset.ToDbSerializeString(); } else { _initialOffset = value; _initialOffsetSetting.Value = value.ToDbSerializeString(); } } private InitialOffset _initialOffset; public InitialOffset InitialOffset { get => _initialOffset; set { SetInitialOffset(value); MarkPropertyChanged("InitialOffset"); } } private IChannelSetting _zeroMethodEndSetting; public double ZeroMethodEnd { get { if (null == _zeroMethodEndSetting.Value) { _zeroMethodEndSetting.DoubleValue = double.Parse(_zeroMethodEndSetting.DefaultValue); } return _zeroMethodEndSetting.DoubleValue; } set { _zeroMethodEndSetting.DoubleValue = value; MarkPropertyChanged("ZeroMethodEnd"); } } private IChannelSetting _userValue1Setting; /// /// gets/sets the value for the channel setting UserValue1 /// public string UserValue1 { get { if (null == _userValue1Setting.Value) { _userValue1Setting.Value = _userValue1Setting.DefaultValue; } return _userValue1Setting.Value; } set { _userValue1Setting.Value = value; MarkPropertyChanged("UserValue1"); } } private IChannelSetting _userValue2Setting; /// /// gets/sets the value for the channel setting UserValue2 /// public string UserValue2 { get { if (null == _userValue2Setting.Value) { _userValue2Setting.Value = _userValue2Setting.DefaultValue; } return _userValue2Setting.Value; } set { _userValue2Setting.Value = value; MarkPropertyChanged("UserValue2"); } } private IChannelSetting _userValue3Setting; /// /// gets/sets the value for the channel setting UserValue3 /// public string UserValue3 { get { if (null == _userValue3Setting.Value) { _userValue3Setting.Value = _userValue3Setting.DefaultValue; } return _userValue3Setting.Value; } set { _userValue3Setting.Value = value; MarkPropertyChanged("UserValue3"); } } public string Sensitivity { get { if (null != SensorData) { if (null == SensorCalibration || (SensorCalibration.SerialNumber != SensorData.SerialNumber)) { SensorCalibration = SensorData.GetLatestCalibration(); } if (null == SensorCalibration) { return Strings.Strings.Table_NA; } return SensorCalibration.ToDisplayString(ExcitationVoltageOptions.ExcitationVoltageOption.Undefined, "N8", "N8", SensorData.Bridge == SensorConstants.BridgeType.IEPE); } if (DragAndDropItem is IAnalogSensor analogSensor) { return analogSensor.Sensitivity; } return Strings.Strings.Table_NA; } } /// /// gets/sets the value for the channel setting polarity /// public string Polarity { get { if (null == _polaritySetting.Value) { _polaritySetting.Value = _polaritySetting.DefaultValue; } return _polaritySetting.Value; } set { _polaritySetting.Value = value; MarkPropertyChanged("Polarity"); } } private IChannelSetting _squibLimitDuration; public bool SquibLimitDuration { get => _squibLimitDuration.BoolValue; set { _squibLimitDuration.BoolValue = value; MarkPropertyChanged("SquibLimitDuration"); } } private IChannelSetting _squibDuration; public double SquibDuration { get => _squibDuration.DoubleValue; set { _squibDuration.DoubleValue = value; MarkPropertyChanged("SquibDuration"); } } private IChannelSetting _squibDelay; //FB14623 SquibDelay is nullable value now, if the _squibDelay saved as -1 in database then return null so UI shows it empty ask the user for value public double? SquibDelay { get { //FB14623 if updating -1 , please update the DEFAULT_DEFINEINTEST_FIRE_DELAY_FLAG as well if (_squibDelay.DoubleValue == -1) return null; else return _squibDelay.DoubleValue; } set { //14623 The set will be never called with null value but check it anyway. if (value.HasValue) { _squibDelay.DoubleValue = value.Value; } MarkPropertyChanged("SquibDelay"); } } private IChannelSetting _digitalOutDuration; public double DigitalOutDuration { get => _digitalOutDuration.DoubleValue; set { if (_digitalOutDuration.DoubleValue == value) { return; } _digitalOutDuration.DoubleValue = value; MarkPropertyChanged("DigitalOutDuration"); } } //FB 28107 Define max value for DigitalOutDuration //1600 is the max value supported by TDAS TOM for others set to a large number public double DigitalOutDurationMax { get; set; } = double.MaxValue; private IChannelSetting _digitalOutLimitDuration; public bool DigitalOutLimitDuration { get => _digitalOutLimitDuration.BoolValue; set { if (_digitalOutLimitDuration.BoolValue == value) { return; } _digitalOutLimitDuration.BoolValue = value; MarkPropertyChanged("DigitalOutLimitDuration"); } } private IChannelSetting _digitalOutDelay; public double DigitalOutDelay { get => _digitalOutDelay.DoubleValue; set { if (_digitalOutDelay.DoubleValue == value) { return; } _digitalOutDelay.DoubleValue = value; MarkPropertyChanged("DigitalOutDelay"); } } private IChannelSetting _digitalOutputMode; /// /// gets/sets the value for the channel setting digital output mode /// public DigitalOutputModes DigitalOutputMode { get => (DigitalOutputModes)_digitalOutputMode.IntValue; set { if (_digitalOutputMode.IntValue == (int)value) { return; } _digitalOutputMode.IntValue = (int)value; MarkPropertyChanged("DigitalOutputMode"); } } private IChannelSetting _squibFireMode; /// /// gets/sets the value for the channel setting squib fire mode /// public SquibFireMode SquibFireMode { get => (SquibFireMode)_squibFireMode.IntValue; set { if (_squibFireMode.IntValue == (int)value) { return; } _squibFireMode.IntValue = (int)value; MarkPropertyChanged("SquibFireMode"); OnPropertyChanged("IsConstantCurrent"); } } public bool IsConstantCurrent => SquibFireMode == SquibFireMode.CONSTANT; private IChannelSetting _squibCurrent; /// /// gets/sets the value for the channel setting squib fire mode /// public double SquibCurrent { get => _squibCurrent.DoubleValue; set { if (_squibCurrent.DoubleValue == value) { return; } _squibCurrent.DoubleValue = value; MarkPropertyChanged("SquibCurrent"); } } private IChannelSetting _digitalInputMode; /// /// gets/sets the value for the channel setting digital input mode /// public DigitalInputModes DigitalInputMode { get => (DigitalInputModes)_digitalInputMode.IntValue; set { if (_digitalInputMode.IntValue == (int)value) { return; } _digitalInputMode.IntValue = (int)value; MarkPropertyChanged("DigitalInputMode"); } } private IChannelSetting _uartBaudRate; /// /// gets/sets the value for the channel setting uart baud rate /// public uint UartBaudRate { get => (uint)_uartBaudRate.IntValue; set { if (_uartBaudRate.IntValue == (int)value) { return; } _uartBaudRate.IntValue = (int)value; MarkPropertyChanged("UartBaudRate"); } } private IChannelSetting _uartDataBits; /// /// gets/sets the value for the channel setting uart data bits /// public uint UartDataBits { get => (uint)_uartDataBits.IntValue; set { if (_uartDataBits.IntValue == (int)value) { return; } _uartDataBits.IntValue = (int)value; MarkPropertyChanged("UartDataBits"); } } private IChannelSetting _uartStopBits; /// /// gets/sets the value for the channel setting uart stop bits /// public StopBits UartStopBits { get { if (null == _uartStopBits.Value) { _uartStopBits.Value = _uartStopBits.DefaultValue; } return (StopBits)Enum.Parse(typeof(StopBits), _uartStopBits.Value); } set { if (_uartStopBits.Value == value.ToString()) { return; } _uartStopBits.Value = value.ToString(); MarkPropertyChanged("UartStopBits"); } } private IChannelSetting _uartParity; /// /// gets/sets the value for the channel setting uart parity /// public Parity UartParity { get { if (null == _uartParity.Value) { _uartParity.Value = _uartParity.DefaultValue; } return (Parity)Enum.Parse(typeof(Parity), _uartParity.Value); } set { if (_uartParity.Value == value.ToString()) { return; } _uartParity.Value = value.ToString(); MarkPropertyChanged("UartParity"); } } private IChannelSetting _uartFlowControl; /// /// gets/sets the value for the channel setting uart stop bits /// public Handshake UartFlowControl { get { //FB 30486 Hardcode FlowControl to NONE for UART sensor type return Handshake.None; } } private IChannelSetting _uartDataFormat; /// /// gets/sets the value for the channel setting uart stop bits /// public UartDataFormat UartDataFormat { get { if (null == _uartDataFormat.Value) { _uartDataFormat.Value = _uartDataFormat.DefaultValue; } return (UartDataFormat)Enum.Parse(typeof(UartDataFormat), _uartDataFormat.Value); } set { if (_uartDataFormat.Value == value.ToString()) { return; } _uartDataFormat.Value = value.ToString(); MarkPropertyChanged("UartDataFormat"); } } private IChannelSetting _activeValue; /// /// gets/sets the value for the channel setting active value /// public string ActiveValue { get { if (null == _activeValue.Value) { _activeValue.Value = _activeValue.DefaultValue; } return _activeValue.Value; } set { _activeValue.Value = value; MarkPropertyChanged("ActiveValue"); } } private IChannelSetting _defaultValue; /// /// gets/sets the value for the channel setting default value /// public string DefaultValue { get { if (null == _defaultValue.Value) { _defaultValue.Value = _defaultValue.DefaultValue; } return _defaultValue.Value; } set { _defaultValue.Value = value; MarkPropertyChanged("DefaultValue"); } } private IChannelSetting _streamInUDPAddress; /// /// udp address setting value for the channel /// public string StreamInUDPAddress { get { if (null == _streamInUDPAddress.Value) { _streamInUDPAddress.Value = _streamInUDPAddress.DefaultValue; } return _streamInUDPAddress.Value; } set { if (_streamInUDPAddress.Value == value) { return; } _streamInUDPAddress.Value = value; MarkPropertyChanged("StreamInUDPAddress"); } } private IChannelSetting _streamOutUDPProfile; /// /// udp profile setting value for the channel /// public UDPStreamProfile StreamOutUDPProfile { get { if (null == _streamOutUDPProfile.Value) { _streamOutUDPProfile.Value = _streamOutUDPProfile.DefaultValue; } return (UDPStreamProfile)Enum.Parse(typeof(UDPStreamProfile), _streamOutUDPProfile.Value); } set { if (_streamOutUDPProfile.Value == value.ToString()) { return; } _streamOutUDPProfile.Value = value.ToString(); MarkPropertyChanged("StreamOutUDPProfile"); OnPropertyChanged("IsCH10"); OnPropertyChanged("IsIENA"); OnPropertyChanged("IsTMNS"); OnPropertyChanged("IsUARTStream"); } } private IChannelSetting _streamOutUDPAddress; /// /// udp address setting value for the channel /// public string StreamOutUDPAddress { get { if (null == _streamOutUDPAddress.Value) { _streamOutUDPAddress.Value = _streamOutUDPAddress.DefaultValue; } return _streamOutUDPAddress.Value; } set { if (_streamOutUDPAddress.Value == value) { return; } _streamOutUDPAddress.Value = value; MarkPropertyChanged("StreamOutUDPAddress"); } } private IChannelSetting _streamOutUDPTimeChannelId; /// /// time channel id setting value for the channel /// public ushort StreamOutUDPTimeChannelId { get => (ushort)_streamOutUDPTimeChannelId.IntValue; set { if (_streamOutUDPTimeChannelId.IntValue == value) { return; } _streamOutUDPTimeChannelId.IntValue = value; MarkPropertyChanged("StreamOutUDPTimeChannelId"); } } private IChannelSetting _streamOutUDPDataChannelId; /// /// data channel id setting value for the channel /// public ushort StreamOutUDPDataChannelId { get => (ushort)_streamOutUDPDataChannelId.IntValue; set { if (_streamOutUDPDataChannelId.IntValue == value) { return; } _streamOutUDPDataChannelId.IntValue = value; MarkPropertyChanged("StreamOutUDPDataChannelId"); OnPropertyChanged("IENA_Key"); } } private IChannelSetting _streamOutUDPTmNSConfig; /// /// tmns config setting value for the channel /// public string StreamOutUDPTmNSConfig { get { if (null == _streamOutUDPTmNSConfig.Value) { _streamOutUDPTmNSConfig.Value = _streamOutUDPTmNSConfig.DefaultValue; } return _streamOutUDPTmNSConfig.Value; } set { if (_streamOutUDPTmNSConfig.Value == value) { return; } _streamOutUDPTmNSConfig.Value = value; MarkPropertyChanged("StreamOutUDPTmNSConfig"); } } /// /// TMNS sub frame id for output streaming /// public uint TMNS_SubFrameId { get { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); return tmns.TMNS_PCMSubFrameId; } set { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); tmns.TMNS_PCMSubFrameId = value; StreamOutUDPTmNSConfig = tmns.ToCSVString(); MarkPropertyChanged("TMNS_SubFrameId"); } } /// /// TMNS message id for output streaming /// public uint TMNS_MsgId { get { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); return tmns.TMNS_MsgId; } set { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); tmns.TMNS_MsgId = value; StreamOutUDPTmNSConfig = tmns.ToCSVString(); MarkPropertyChanged("TMNS_MsgId"); } } /// /// tmns PCM minor per major setting for output streaming /// public uint TMNS_MinorPerMajor { get { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); return tmns.TMNS_PCMMinorPerMajor; } set { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); tmns.TMNS_PCMMinorPerMajor = value; StreamOutUDPTmNSConfig = tmns.ToCSVString(); MarkPropertyChanged("TMNS_MinorPerMajor"); } } /// /// TMNS TMATs port for output streaming /// public uint TMNS_TMATSPort { get { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); return tmns.TMNS_TMATSPortNumber; } set { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); tmns.TMNS_TMATSPortNumber = value; StreamOutUDPTmNSConfig = tmns.ToCSVString(); MarkPropertyChanged("TMNS_TMATSPort"); } } /// /// IENA key for output streaming /// public ushort IENA_Key { get { return StreamOutUDPDataChannelId; } set { StreamOutUDPDataChannelId = value; MarkPropertyChanged("IENA_Key"); } } /// /// IENA source port for streaming /// public uint IENA_SourcePort { get { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); return tmns.IENAUDP_PortNumber; } set { var tmns = new TMNSConfig(StreamOutUDPTmNSConfig); tmns.IENAUDP_PortNumber = value; StreamOutUDPTmNSConfig = tmns.ToCSVString(); MarkPropertyChanged("IENA_SourcePort"); } } private IChannelSetting _streamOutIRIGTimeDataPacketIntervalMs; /// /// irig data packet interval setting value for the channel /// public ushort StreamOutIRIGTimeDataPacketIntervalMs { get => (ushort)_streamOutIRIGTimeDataPacketIntervalMs.IntValue; set { if (_streamOutIRIGTimeDataPacketIntervalMs.IntValue == value) { return; } _streamOutIRIGTimeDataPacketIntervalMs.IntValue = value; MarkPropertyChanged("StreamOutIRIGTimeDataPacketIntervalMs"); } } private IChannelSetting _streamOutTMATSIntervalMs; /// /// time in ms between sending tmats information while streaming /// http://manuscript.dts.local/f/cases/29987/Add-CG-DP-TMATS-interval-UI-support /// public ushort StreamOutTMATSIntervalMs { get => null == _streamOutTMATSIntervalMs ? StreamOutputRecord.DEFAULT_TMATS_INTERVAL_MS : Convert.ToUInt16(_streamOutTMATSIntervalMs.IntValue); set { if (null == _streamOutTMATSIntervalMs) { return; } if (_streamOutTMATSIntervalMs.IntValue == value) { return; } _streamOutTMATSIntervalMs.IntValue = value; MarkPropertyChanged("StreamOutTMATSIntervalMs"); } } private bool isRangeDifferent; public bool IsRangeDifferent { get => isRangeDifferent; set { isRangeDifferent = value; OnPropertyChanged("IsRangeDifferent"); } } private bool isFilterClassDifferent; public bool IsFilterClassDifferent { get => isFilterClassDifferent; set { isFilterClassDifferent = value; OnPropertyChanged("IsFilterClassDifferent"); } } private bool isPolarityDifferent; public bool IsPolarityDifferent { get => isPolarityDifferent; set { isPolarityDifferent = value; OnPropertyChanged("IsPolarityDifferent"); } } private bool isZeroMethodDifferent; public bool IsZeroMethodDifferent { get => isZeroMethodDifferent; set { isZeroMethodDifferent = value; OnPropertyChanged("IsZeroMethodDifferent"); } } private bool isZeroMethodStartDifferent; public bool IsZeroMethodStartDifferent { get => isZeroMethodStartDifferent; set { isZeroMethodStartDifferent = value; OnPropertyChanged("IsZeroMethodStartDifferent"); } } private bool isZeroMethodEndDifferent; public bool IsZeroMethodEndDifferent { get => isZeroMethodEndDifferent; set { isZeroMethodEndDifferent = value; OnPropertyChanged("IsZeroMethodEndDifferent"); } } private bool isInitialOffsetDifferent; public bool IsInitialOffsetDifferent { get => isInitialOffsetDifferent; set { isInitialOffsetDifferent = value; OnPropertyChanged("IsInitialOffsetDifferent"); } } private bool isSquibFireModeDifferent; public bool IsSquibFireModeDifferent { get => isSquibFireModeDifferent; set { isSquibFireModeDifferent = value; OnPropertyChanged("IsSquibFireModeDifferent"); } } private bool isSquibDelayDifferent; public bool IsSquibDelayDifferent { get => isSquibDelayDifferent; set { isSquibDelayDifferent = value; OnPropertyChanged("IsSquibDelayDifferent"); } } private bool isSquibLimitDurationDifferent; public bool IsSquibLimitDurationDifferent { get => isSquibLimitDurationDifferent; set { isSquibLimitDurationDifferent = value; OnPropertyChanged("IsSquibLimitDurationDifferent"); } } private bool isSquibDurationDifferent; public bool IsSquibDurationDifferent { get => isSquibDurationDifferent; set { isSquibDurationDifferent = value; OnPropertyChanged("IsSquibDurationDifferent"); } } private bool isSquibCurrentDifferent; public bool IsSquibCurrentDifferent { get => isSquibCurrentDifferent; set { isSquibCurrentDifferent = value; OnPropertyChanged("IsSquibCurrentDifferent"); } } private bool isDigitalOutputModeDifferent; public bool IsDigitalOutputModeDifferent { get => isDigitalOutputModeDifferent; set { isDigitalOutputModeDifferent = value; OnPropertyChanged("IsDigitalOutputModeDifferent"); } } private bool isDigitalOutDelayDifferent; public bool IsDigitalOutDelayDifferent { get => isDigitalOutDelayDifferent; set { isDigitalOutDelayDifferent = value; OnPropertyChanged("IsDigitalOutDelayDifferent"); } } private bool isDigitalOutLimitDurationDifferent; public bool IsDigitalOutLimitDurationDifferent { get => isDigitalOutLimitDurationDifferent; set { isDigitalOutLimitDurationDifferent = value; OnPropertyChanged("IsDigitalOutLimitDurationDifferent"); } } private bool isDigitalOutDurationDifferent; public bool IsDigitalOutDurationDifferent { get => isDigitalOutDurationDifferent; set { isDigitalOutDurationDifferent = value; OnPropertyChanged("IsDigitalOutDurationDifferent"); } } private bool isDigitalInputModeDifferent; public bool IsDigitalInputModeDifferent { get => isDigitalInputModeDifferent; set { isDigitalInputModeDifferent = value; OnPropertyChanged("IsDigitalInputModeDifferent"); } } private bool isDefaultValueDifferent; public bool IsDefaultValueDifferent { get => isDefaultValueDifferent; set { isDefaultValueDifferent = value; OnPropertyChanged("IsDefaultValueDifferent"); } } private bool isActiveValueDifferent; public bool IsActiveValueDifferent { get => isActiveValueDifferent; set { isActiveValueDifferent = value; OnPropertyChanged("IsActiveValueDifferent"); } } //UART private bool isUartBaudRateDifferent; public bool IsUartBaudRateDifferent { get => isUartBaudRateDifferent; set { isUartBaudRateDifferent = value; OnPropertyChanged("IsUartBaudRateDifferent"); } } private bool isUartDataBitsDifferent; public bool IsUartDataBitsDifferent { get => isUartDataBitsDifferent; set { isUartDataBitsDifferent = value; OnPropertyChanged("IsUartDataBitsDifferent"); } } private bool isUartDataFormatDifferent; public bool IsUartDataFormatDifferent { get => isUartDataFormatDifferent; set { isUartDataFormatDifferent = value; OnPropertyChanged("IsUartDataFormatDifferent"); } } private bool isUartFlowControlDifferent; public bool IsUartFlowControlDifferent { get => isUartFlowControlDifferent; set { isUartFlowControlDifferent = value; OnPropertyChanged("IsUartFlowControlDifferent"); } } private bool isUartParityDifferent; public bool IsUartParityDifferent { get => isUartParityDifferent; set { isUartParityDifferent = value; OnPropertyChanged("IsUartParityDifferent"); } } private bool isUartStopBitsDifferent; public bool IsUartStopBitsDifferent { get => isUartStopBitsDifferent; set { isUartStopBitsDifferent = value; OnPropertyChanged("IsUartStopBitsDifferent"); } } //Stream Out private bool isStreamOutUDPProfileDifferent; public bool IsStreamOutUDPProfileDifferent { get => isStreamOutUDPProfileDifferent; set { isStreamOutUDPProfileDifferent = value; OnPropertyChanged("IsStreamOutUDPProfileDifferent"); } } private bool isStreamOutUDPAddressDifferent; public bool IsStreamOutUDPAddressDifferent { get => isStreamOutUDPAddressDifferent; set { isStreamOutUDPAddressDifferent = value; OnPropertyChanged("IsStreamOutUDPAddressDifferent"); } } private bool isStreamOutUDPTimeChannelIdDifferent; public bool IsStreamOutUDPTimeChannelIdDifferent { get => isStreamOutUDPTimeChannelIdDifferent; set { isStreamOutUDPTimeChannelIdDifferent = value; OnPropertyChanged("IsStreamOutUDPTimeChannelIdDifferent"); } } private bool isStreamOutUDPDataChannelIdDifferent; public bool IsStreamOutUDPDataChannelIdDifferent { get => isStreamOutUDPDataChannelIdDifferent; set { isStreamOutUDPDataChannelIdDifferent = value; OnPropertyChanged("IsStreamOutUDPDataChannelIdDifferent"); } } private bool isStreamOutIRIGTimeDataPacketIntervalMsDifferent; public bool IsStreamOutIRIGTimeDataPacketIntervalMsDifferent { get => isStreamOutIRIGTimeDataPacketIntervalMsDifferent; set { isStreamOutIRIGTimeDataPacketIntervalMsDifferent = value; OnPropertyChanged("IsStreamOutIRIGTimeDataPacketIntervalMsDifferent"); } } private bool isStreamOutUDPTmNSConfigDifferent; public bool IsStreamOutUDPTmNSConfigDifferent { get => isStreamOutUDPTmNSConfigDifferent; set { isStreamOutUDPTmNSConfigDifferent = value; OnPropertyChanged("IsStreamOutUDPTmNSConfigDifferent"); } } private bool isStreamOutTMATSIntervalMsDifferent; public bool IsStreamOutTMATSIntervalMsDifferent { get => isStreamOutTMATSIntervalMsDifferent; set { isStreamOutTMATSIntervalMsDifferent = value; OnPropertyChanged("IsStreamOutTMATSIntervalMsDifferent"); } } //Stream In private bool isStreamInUDPAddressDifferent; public bool IsStreamInUDPAddressDifferent { get => isStreamInUDPAddressDifferent; set { isStreamInUDPAddressDifferent = value; OnPropertyChanged("IsStreamInUDPAddressDifferent"); } } private void MarkPropertyChanged(string property) { OnPropertyChanged(property); if (!_notifyOff) { var eventAggregator = ContainerLocator.Container.Resolve(); eventAggregator.GetEvent().Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, null)); } SetDifferent(property); } /// /// Set all of the channel's properties to False /// public void SetNotDifferent() { IsRangeDifferent = false; IsFilterClassDifferent = false; IsPolarityDifferent = false; IsZeroMethodDifferent = false; IsZeroMethodStartDifferent = false; IsZeroMethodEndDifferent = false; IsInitialOffsetDifferent = false; IsSquibFireModeDifferent = false; IsSquibDelayDifferent = false; IsSquibLimitDurationDifferent = false; IsSquibDurationDifferent = false; IsSquibCurrentDifferent = false; IsDigitalOutputModeDifferent = false; IsDigitalOutDelayDifferent = false; IsDigitalOutLimitDurationDifferent = false; IsDigitalOutDurationDifferent = false; IsDigitalInputModeDifferent = false; IsDefaultValueDifferent = false; IsActiveValueDifferent = false; IsUartBaudRateDifferent = false; IsUartDataBitsDifferent = false; IsUartDataFormatDifferent = false; IsUartFlowControlDifferent = false; IsUartParityDifferent = false; IsUartStopBitsDifferent = false; IsStreamOutUDPProfileDifferent = false; IsStreamOutUDPAddressDifferent = false; IsStreamOutUDPTimeChannelIdDifferent = false; IsStreamOutUDPDataChannelIdDifferent = false; IsStreamOutIRIGTimeDataPacketIntervalMsDifferent = false; IsStreamOutTMATSIntervalMsDifferent = false; IsStreamOutUDPTmNSConfigDifferent = false; IsStreamInUDPAddressDifferent = false; } /// /// Return True if the value is the same, or False if it is different /// /// /// public bool CompareValue(string property) { if (!BorderShouldShowOutOfDate) return true; if (SensorData == null) { return true; } var sc = SensorData.GetLatestCalibration(); if (sc == null) return true; var unChanged = true; switch (property) { case "Range": unChanged = SensorData.Capacity.Equals(Range); break; case "FilterClass": unChanged = SensorData.FilterClass.Equals(FilterClass); break; case "Polarity": unChanged = SensorData.Polarity.Equals(Polarity); break; case "ZeroMethod": unChanged = sc.ZeroMethods.Methods[0].Method.Equals(ZeroMethod); break; case "ZeroMethodStart": unChanged = sc.ZeroMethods.Methods[0].Start.Equals(ZeroMethodStart); break; case "ZeroMethodEnd": unChanged = sc.ZeroMethods.Methods[0].End.Equals(ZeroMethodEnd); break; case "InitialOffset": unChanged = SensorData.InitialOffset.Equals(InitialOffset); break; case "SquibFireMode": unChanged = SensorData.SquibFireMode.Equals(SquibFireMode); break; case "SquibDelay": unChanged = SensorData.SquibFireDelayMS.Equals(SquibDelay); break; case "SquibLimitDuration": unChanged = SensorData.LimitSquibFireDuration.Equals(SquibLimitDuration); break; case "SquibDuration": unChanged = SensorData.SquibFireDurationMS.Equals(SquibDuration); break; case "SquibCurrent": unChanged = SensorData.SquibOutputCurrent.Equals(SquibCurrent); break; case "DigitalOutputMode": unChanged = SensorData.DigitalOutputMode.Equals(DigitalOutputMode); break; case "DigitalOutDelay": unChanged = SensorData.DigitalOutputDelayMS.Equals(DigitalOutDelay); break; case "DigitalOutLimitDuration": unChanged = SensorData.DigitalOutputLimitDuration.Equals(DigitalOutLimitDuration); break; case "DigitalOutDuration": unChanged = SensorData.DigitalOutputDurationMS.Equals(DigitalOutDuration); break; case "DigitalInputMode": unChanged = SensorData.InputMode.Equals(DigitalInputMode); break; case "DefaultValue": unChanged = SensorData.InputDefaultValue.ToString().Equals(DefaultValue); break; case "ActiveValue": unChanged = SensorData.InputActiveValue.ToString().Equals(ActiveValue); break; default: return true; } return unChanged; } /// /// Set the "IsChanged" property to True if different, False if not /// /// /// public bool SetDifferent(string property) { if (!BorderShouldShowOutOfDate) return false; if (SensorData == null) { SetNotDifferent(); return false; } ISensorCalibration sc = null; //If different than sensor database, mark it; if not, clear any marking var changed = false; switch (property) { case "Range": changed = !SensorData.Capacity.Equals(Range); IsRangeDifferent = changed; break; //FB 13120 Use filter class instead of CFC case "FilterClass": changed = !SensorData.FilterClass.Equals(FilterClass); IsFilterClassDifferent = changed; break; case "Polarity": changed = !SensorData.Polarity.Equals(Polarity); IsPolarityDifferent = changed; break; case "ZeroMethod": sc = SensorData.GetLatestCalibration(); if (sc == null) return true; changed = !sc.ZeroMethods.Methods[0].Method.Equals(ZeroMethod); IsZeroMethodDifferent = changed; break; case "ZeroMethodStart": sc = SensorData.GetLatestCalibration(); if (sc == null) return true; changed = !sc.ZeroMethods.Methods[0].Start.Equals(ZeroMethodStart); IsZeroMethodStartDifferent = changed; break; case "ZeroMethodEnd": sc = SensorData.GetLatestCalibration(); if (sc == null) return true; changed = !sc.ZeroMethods.Methods[0].End.Equals(ZeroMethodEnd); IsZeroMethodEndDifferent = changed; break; case "InitialOffset": sc = SensorData.GetLatestCalibration(); if (null != sc && null != sc.InitialOffsets && null != sc.InitialOffsets.DefaultOffset) { if (!CheckMatchInitialOffset(sc)) { changed = true; } } IsInitialOffsetDifferent = changed; break; case "SquibFireMode": changed = !SensorData.SquibFireMode.Equals(SquibFireMode); IsSquibFireModeDifferent = changed; break; case "SquibDelay": changed = !SensorData.SquibFireDelayMS.Equals(SquibDelay); IsSquibDelayDifferent = changed; break; case "SquibLimitDuration": changed = !SensorData.LimitSquibFireDuration.Equals(SquibLimitDuration); IsSquibLimitDurationDifferent = changed; break; case "SquibDuration": changed = !SensorData.SquibFireDurationMS.Equals(SquibDuration); IsSquibDurationDifferent = changed; break; case "SquibCurrent": changed = !SensorData.SquibOutputCurrent.Equals(SquibCurrent); IsSquibCurrentDifferent = changed; break; case "DigitalOutputMode": changed = !SensorData.DigitalOutputMode.Equals(DigitalOutputMode); IsDigitalOutputModeDifferent = changed; break; case "DigitalOutDelay": changed = !SensorData.DigitalOutputDelayMS.Equals(DigitalOutDelay); IsDigitalOutDelayDifferent = changed; break; case "DigitalOutLimitDuration": changed = !SensorData.DigitalOutputLimitDuration.Equals(DigitalOutLimitDuration); IsDigitalOutLimitDurationDifferent = changed; break; case "DigitalOutDuration": changed = !SensorData.DigitalOutputDurationMS.Equals(DigitalOutDuration); IsDigitalOutDurationDifferent = changed; break; case "DigitalInputMode": changed = !SensorData.InputMode.Equals(DigitalInputMode); IsDigitalInputModeDifferent = changed; break; case "DefaultValue": changed = !SensorData.InputDefaultValue.ToString().Equals(DefaultValue); IsDefaultValueDifferent = changed; break; case "ActiveValue": changed = !SensorData.InputActiveValue.ToString().Equals(ActiveValue); IsActiveValueDifferent = changed; break; //UART case "UartBaudRate": changed = !SensorData.UartBaudRate.Equals(UartBaudRate); IsUartBaudRateDifferent = changed; break; case "UartDataBits": changed = !SensorData.UartDataBits.Equals(UartDataBits); IsUartDataBitsDifferent = changed; break; case "UartDataFormat": changed = !SensorData.UartDataFormat.Equals(UartDataFormat); IsUartDataFormatDifferent = changed; break; case "UartFlowControl": changed = !SensorData.UartFlowControl.Equals(UartFlowControl); IsUartFlowControlDifferent = changed; break; case "UartParity": changed = !SensorData.UartParity.Equals(UartParity); IsUartParityDifferent = changed; break; case "UartStopBits": changed = !SensorData.UartStopBits.Equals(UartStopBits); IsUartStopBitsDifferent = changed; break; //Stream Out case "StreamOutUDPProfile": changed = !SensorData.StreamOutUDPProfile.Equals(StreamOutUDPProfile); IsStreamOutUDPProfileDifferent = changed; break; case "StreamOutUDPAddress": changed = !SensorData.StreamOutUDPAddress.ToString().Equals(StreamOutUDPAddress); IsStreamOutUDPAddressDifferent = changed; break; case "StreamOutUDPTimeChannelId": changed = !SensorData.StreamOutUDPTimeChannelId.Equals(StreamOutUDPTimeChannelId); IsStreamOutUDPTimeChannelIdDifferent = changed; break; case "StreamOutUDPDataChannelId": changed = !SensorData.StreamOutUDPDataChannelId.Equals(StreamOutUDPDataChannelId); IsStreamOutUDPDataChannelIdDifferent = changed; break; case "StreamOutIRIGTimeDataPacketIntervalMs": changed = !SensorData.StreamOutIRIGTimeDataPacketIntervalMs.Equals(StreamOutIRIGTimeDataPacketIntervalMs); IsStreamOutIRIGTimeDataPacketIntervalMsDifferent = changed; break; case "StreamOutUDPTmNSConfig": changed = !SensorData.StreamOutUDPTmNSConfig.ToString().Equals(StreamOutUDPTmNSConfig); IsStreamOutUDPTmNSConfigDifferent = changed; break; case "StreamOutTMATSIntervalMs": changed = !SensorData.StreamOutTMATSIntervalMs.Equals(StreamOutTMATSIntervalMs); IsStreamOutTMATSIntervalMsDifferent = changed; break; //Stream In case "StreamInUDPAddress": changed = !SensorData.StreamInUDPAddress.ToString().Equals(StreamInUDPAddress); IsStreamInUDPAddressDifferent = changed; break; default: return false; } return changed; } /// /// returns true if the initial offset match /// /// /// private bool CheckMatchInitialOffset(ISensorCalibration sc) { //no information to compare if (null == sc || null == sc.InitialOffsets || null == sc.InitialOffsets.Offsets) { return true; } switch (InitialOffset.Form) { case InitialOffsetTypes.None: return Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.None); case InitialOffsetTypes.EU: return Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.EU && o.EU == InitialOffset.EU); case InitialOffsetTypes.EUAtMV: return Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.EUAtMV && o.EU == InitialOffset.EU && o.MV == InitialOffset.MV); case InitialOffsetTypes.LHS: return Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.LHS && o.EU == InitialOffset.EU); case InitialOffsetTypes.RHS: return Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.RHS && o.EU == InitialOffset.EU); case InitialOffsetTypes.FRONTAL: return Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.FRONTAL && o.EU == InitialOffset.EU); } return false; } public void SetRange(CACOption option) { if (!IsAnalog || SensorId < 0) { return; } if (null != SensorData) { switch (option) { case CACOption.Manual: return; case CACOption.Capacity: Range = SensorData.Capacity; break; case CACOption.RangeHigh: Range = SensorData.RangeHigh; break; case CACOption.RangeMedium: Range = SensorData.RangeMedium; break; case CACOption.RangeLow: Range = SensorData.RangeLow; break; } } else if (null != DragAndDropItem) { if (!(DragAndDropItem is IAnalogSensor analogSensor)) { return; } switch (option) { case CACOption.Manual: return; case CACOption.Capacity: Range = analogSensor.Capacity; break; case CACOption.RangeHigh: Range = analogSensor.RangeHigh; break; case CACOption.RangeMedium: Range = analogSensor.RangeMedium; break; case CACOption.RangeLow: Range = analogSensor.RangeLow; break; } } } /// /// this is included to reduce some binding errors; /// System.Windows.Data Error: 40 : BindingExpression path error: 'Disabled' property not found on 'object' ''GroupChannel' (HashCode=59703596)'. BindingExpression:Path=Disabled; DataItem='GroupChannel' (HashCode=59703596); target element is 'ListViewItem' (Name=''); target property is 'NoTarget' (type 'Object') /// public new bool Disabled => false; private void CheckSensorUsage(int usageCount, int maximumUsage, ref UIItemStatus itemStatus) { //Also check for sensor usage, if appropriate if (SensorConstants.DontAllowDataCollectionIfOverused) { if (usageCount >= maximumUsage) { itemStatus = UIItemStatus.Error; } else { var threshold = maximumUsage - SensorConstants.UsageRemainingForWarning; itemStatus = usageCount >= threshold ? UIItemStatus.Warning : UIItemStatus.None; } } } /// /// returns the status of the channel considering "IsComplete" and sensor cal status /// 9724 Sensor cal policy needs to match hardware cal policy /// public UIItemStatus ChannelStatus { get { if (IsAnalog) { if (HardwareChannel != null && HardwareChannel.IsTSRAIR) { return UIItemStatus.Success; } if ((null != SensorData && SensorData.SerialNumber != SensorConstants.TEST_SPECIFIC_ANALOG_SERIAL && SensorData.SerialNumber != SensorConstants.TEST_SPECIFIC_CLOCK_SERIAL) || null != DragAndDropItem) { DateTime dueDate = DateTime.MinValue; DateTime warningDate = DateTime.MinValue; var bridge = SensorConstants.BridgeType.FullBridge; var sensorCalibrationOrUsageStatus = UIItemStatus.None; if (null != SensorData) { var cal = SensorData.GetLatestCalibration(); // 13065 Sensor "First Use" Date dueDate = SensorData.GetDueDate(cal); if (dueDate == DateTime.MinValue) { warningDate = dueDate; } else { warningDate = dueDate.AddDays(-1D * SensorConstants.SensorCalOutOfDateWarningPeriodDays).Date; } bridge = SensorData.Bridge; //43920 No need to check the Usage Count if there's no calibration if (cal != null) { CheckSensorUsage(cal.UsageCount, SensorData.MaximumUsage, ref sensorCalibrationOrUsageStatus); } } else if (DragAndDropItem is IAnalogSensor analogSensor) { dueDate = analogSensor.CalDueDate; if (dueDate == DateTime.MinValue) { warningDate = dueDate; } else { warningDate = analogSensor.CalDueDate.AddDays(-1D * SensorConstants.SensorCalOutOfDateWarningPeriodDays).Date; } bridge = analogSensor.Bridge; //Also check for sensor usage, if appropriate if (SensorConstants.DontAllowDataCollectionIfOverused) { sensorCalibrationOrUsageStatus = analogSensor.SensorCalibrationOrUsageStatus; } } else if (DragAndDropItem is ISquib) { return UIItemStatus.Error; } else if (DragAndDropItem is IDigitalInputSetting) { return UIItemStatus.Error; } else if (DragAndDropItem is IDigitalOutputSetting) { return UIItemStatus.Error; } if (null != HardwareChannel && !HardwareChannel.IsSupportedBridgeType(bridge)) { return UIItemStatus.Error; } if (dueDate != DateTime.MinValue) { if (dueDate < DateTime.Today.Date) { //Also check for sensor usage, if appropriate if ((SensorConstants.SensorCalPolicyCurrent == SensorConstants.SensorCalPolicy.DONT_ALLOW) || (SensorConstants.DontAllowDataCollectionIfOverused && (sensorCalibrationOrUsageStatus == UIItemStatus.Error))) { return UIItemStatus.Error; } else { return UIItemStatus.Warning; } } if (warningDate <= DateTime.Today.Date) { //Also check for sensor usage, if appropriate if (SensorConstants.DontAllowDataCollectionIfOverused && (sensorCalibrationOrUsageStatus == UIItemStatus.Error)) { return UIItemStatus.Error; } else { return UIItemStatus.Warning; } } } //Also check for sensor usage, if appropriate if (SensorConstants.DontAllowDataCollectionIfOverused && (sensorCalibrationOrUsageStatus != UIItemStatus.None)) { return sensorCalibrationOrUsageStatus; } } } else if (IsDigitalIn) { if (null != HardwareChannel && !HardwareChannel.IsDigitalIn) { return UIItemStatus.Error; } } else if (IsDigitalOut) { if (null != HardwareChannel && !HardwareChannel.IsDigitalOut) { return UIItemStatus.Error; } } else if (IsSquib) { if (null != HardwareChannel && !HardwareChannel.IsSquib) { return UIItemStatus.Error; } } else if (IsUart) { if (null != HardwareChannel) { if (!HardwareChannel.IsUart) { return UIItemStatus.Error; } } } else if (IsStreamOut) { if (null != HardwareChannel) { if (!HardwareChannel.IsStreamOut) { return UIItemStatus.Error; } } } else if (IsStreamIn && null != HardwareChannel && !HardwareChannel.IsStreamIn) { return UIItemStatus.Error; } if (IsBlank()) { return UIItemStatus.None; } if (!IsChannelComplete) { return UIItemStatus.None; } return UIItemStatus.Success; } } /// /// returns a list of sensor parameter differences from sensor vs channel /// returns empty string if there aren't any /// /// /// public string GetChangeList(ISensorData sensor) { if (sensor.IsDigitalInput()) { return GetChangeListDigitalInput(sensor); } else if (sensor.IsDigitalOutput()) { return GetChangeListDigitalOutput(sensor); } else if (sensor.IsSquib()) { return GetChangeListSquib(sensor); } else if (sensor.IsUart()) { return GetChangeListUart(sensor); } else if (sensor.IsStreamOutput()) { return GetChangeListStreamOutput(sensor); } else if (sensor.IsStreamInput()) { return GetChangeListStreamInput(sensor); } else return GetChangeListAnalog(sensor); } /// /// returns a string describing differences from sensor vs channel wrt to digital input settings /// /// /// /// private string GetChangeListDigitalInput(ISensorData sensor) { var sb = new StringBuilder(); var needComma = DoCheck(false, (int)DigitalInputMode, (int)sensor.InputMode, Strings.Strings.InputMode, ref sb); needComma = DoCheck(needComma, ActiveValue, sensor.InputActiveValue, Strings.Strings.ActiveValue, ref sb); needComma = DoCheck(needComma, DefaultValue, sensor.InputDefaultValue, Strings.Strings.DefaultValue, ref sb); if (needComma) { return $"{sensor.SerialNumber}: {sb.ToString()}"; } return string.Empty; } /// /// returns a string describing differences from channel settings to sensor wrt digital output settings /// /// /// /// private string GetChangeListDigitalOutput(ISensorData sensor) { var sb = new StringBuilder(); var needComma = DoCheck(false, (int)DigitalOutputMode, (int)sensor.DigitalOutputMode, Strings.Strings.OutputMode, ref sb); needComma = DoCheck(needComma, DigitalOutDelay, sensor.DigitalOutputDelayMS, Strings.Strings.Delay, ref sb); needComma = DoCheck(needComma, DigitalOutDuration, sensor.DigitalOutputDurationMS, Strings.Strings.Duration, ref sb); needComma = DoCheck(needComma, DigitalOutLimitDuration, sensor.DigitalOutputLimitDuration, Strings.Strings.LimitDuration, ref sb); if (needComma) { return $"{sensor.SerialNumber}: {sb.ToString()}"; } return string.Empty; } /// /// returns a string describing differences from channel settings to sensor wrt uart settings /// /// /// /// private string GetChangeListUart(ISensorData sensor) { var sb = new StringBuilder(); var needComma = DoCheck(false, UartBaudRate, sensor.UartBaudRate, Strings.Strings.BaudRate, ref sb); needComma = DoCheck(needComma, UartDataBits, sensor.UartDataBits, Strings.Strings.DataBits, ref sb); needComma = DoCheck(needComma, UartStopBits, sensor.UartStopBits, Strings.Strings.StopBits, ref sb); needComma = DoCheck(needComma, UartParity, sensor.UartParity, Strings.Strings.Parity, ref sb); needComma = DoCheck(needComma, UartFlowControl, sensor.UartFlowControl, Strings.Strings.FlowControl, ref sb); needComma = DoCheck(needComma, UartDataFormat, sensor.UartDataFormat, Strings.Strings.DataFormat, ref sb); if (needComma) { return $"{sensor.SerialNumber}: {sb}"; } return string.Empty; } /// /// returns a string describing differences from channel settings to sensor wrt stream output settings /// /// /// /// private string GetChangeListStreamOutput(ISensorData sensor) { var sb = new StringBuilder(); var needComma = DoCheck(false, StreamOutUDPProfile, sensor.StreamOutUDPProfile, Strings.Strings.StreamProfile, ref sb); needComma = DoCheck(needComma, StreamOutUDPAddress, sensor.StreamOutUDPAddress, Strings.Strings.UDPAddress, ref sb); needComma = DoCheck(needComma, StreamOutUDPTimeChannelId, sensor.StreamOutUDPTimeChannelId, Strings.Strings.TimeChannelId, ref sb); needComma = DoCheck(needComma, StreamOutUDPDataChannelId, sensor.StreamOutUDPDataChannelId, Strings.Strings.DataChannelId, ref sb); needComma = DoCheck(needComma, StreamOutUDPTmNSConfig, sensor.StreamOutUDPTmNSConfig, Strings.Strings.TmNSConfig, ref sb); needComma = DoCheck(needComma, StreamOutIRIGTimeDataPacketIntervalMs, sensor.StreamOutIRIGTimeDataPacketIntervalMs, Strings.Strings.IRIGTimeDataPacketIntervalMs, ref sb); needComma = DoCheck(needComma, StreamOutTMATSIntervalMs, sensor.StreamOutTMATSIntervalMs, Strings.Strings.TMATSIntervalMs, ref sb); if (needComma) { return $"{sensor.SerialNumber}: {sb}"; } return string.Empty; } /// /// returns a string describing differences from channel settings to sensor wrt stream output settings /// /// /// /// private string GetChangeListStreamInput(ISensorData sensor) { var sb = new StringBuilder(); var needComma = DoCheck(false, StreamInUDPAddress, sensor.StreamInUDPAddress, Strings.Strings.UDPAddress, ref sb); if (needComma) { return $"{sensor.SerialNumber}: {sb.ToString()}"; } return string.Empty; } private bool DoCheck(bool needComma, object left, object right, string info, ref StringBuilder sb) { if (!left.Equals(right)) { if (needComma) { sb.Append(", "); } sb.Append(info); return true; } return needComma; } private bool DoCheckForBlank(bool needComma, object left, object right, string info, ref StringBuilder sb) { //26950 Only set the "name" fields if replacing a blank (don't stomp on a non-blank value) if ((string)left == "" && (string)right != "") { if (needComma) { sb.Append(", "); } sb.Append(info); return true; } return needComma; } /// /// returns a string describing differences from channel settings to sensor wrt squib settings /// /// /// /// private string GetChangeListSquib(ISensorData sensor) { var sb = new StringBuilder(); var needComma = DoCheck(false, (int)SquibFireMode, (int)sensor.SquibFireMode, Strings.Strings.FireMode, ref sb); var delay = SquibDelay ?? -1; needComma = DoCheck(needComma, delay, sensor.SquibFireDelayMS, Strings.Strings.Delay, ref sb); needComma = DoCheck(needComma, SquibDuration, sensor.SquibFireDurationMS, Strings.Strings.Duration, ref sb); needComma = DoCheck(needComma, SquibLimitDuration, sensor.LimitDuration, Strings.Strings.LimitDuration, ref sb); needComma = DoCheck(needComma, SquibCurrent, sensor.SquibOutputCurrent, Strings.Strings.OutputCurrent, ref sb); if (needComma) { return $"{sensor.SerialNumber}: {sb.ToString()}"; } return string.Empty; } /// /// returns a string describing differences from channel settings to sensor wrt analog settings /// /// /// /// private string GetChangeListAnalog(ISensorData sensor) { var sb = new StringBuilder(); //26950 var needComma = DoCheckForBlank(false, UserCode, sensor.UserCode, Strings.Strings.UserCode, ref sb); needComma = DoCheckForBlank(needComma, UserChannelName, sensor.UserChannelName, Strings.Strings.UserChannelName, ref sb); needComma = DoCheckForBlank(needComma, IsoCode, sensor.ISOCode, Strings.Strings.ISO13499Code, ref sb); needComma = DoCheckForBlank(needComma, IsoChannelName, sensor.ISOChannelName, Strings.Strings.ISOChannelName, ref sb); needComma = DoCheck(needComma, FilterClass, sensor.FilterClass, Strings.Strings.Filter, ref sb); needComma = DoCheck(needComma, Range, sensor.Capacity, Strings.Strings.Range, ref sb); needComma = DoCheck(needComma, Polarity, sensor.Invert ? "-" : "+", Strings.Strings.Polarity, ref sb); //now zeromethods are harder to compare since apparently a calibration can have multiple... var sc = sensor.GetLatestCalibration(); if (null != sc) { var bZeroDifferent = false; foreach (var zm in sc.ZeroMethods.Methods) { if (zm.End != ZeroMethodEnd) { bZeroDifferent = true; break; } if (zm.Start != ZeroMethodStart) { bZeroDifferent = true; break; } if (zm.Method != ZeroMethod) { bZeroDifferent = true; break; } } if (bZeroDifferent) { if (needComma) { sb.Append(", "); } sb.Append(Strings.Strings.ZeroMethod); needComma = true; } var initialOffsetChanged = true; if (null != sc.InitialOffsets && null != sc.InitialOffsets.Offsets) { switch (InitialOffset.Form) { case InitialOffsetTypes.None: initialOffsetChanged = !Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.None); break; case InitialOffsetTypes.EU: initialOffsetChanged = !Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.EU && o.EU == InitialOffset.EU); break; case InitialOffsetTypes.EUAtMV: initialOffsetChanged = !Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.EUAtMV && o.EU == InitialOffset.EU && o.MV == InitialOffset.MV); break; case InitialOffsetTypes.LHS: initialOffsetChanged = !Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.LHS && o.EU == InitialOffset.EU); break; case InitialOffsetTypes.RHS: initialOffsetChanged = !Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.RHS && o.EU == InitialOffset.EU); break; case InitialOffsetTypes.FRONTAL: initialOffsetChanged = !Array.Exists(sc.InitialOffsets.Offsets, o => o.Form == InitialOffsetTypes.FRONTAL && o.EU == InitialOffset.EU); break; } } if (initialOffsetChanged) { if (needComma) { sb.Append(", "); } needComma = true; sb.Append(Strings.Strings.InitialOffset); } } if (needComma) { return $"{sensor.SerialNumber}: {sb.ToString()}"; } return string.Empty; } private bool IsEqual(InitialOffset left, InitialOffset right) { return left.Form == right.Form && left.EU == right.EU && left.MV == right.MV; } /// /// returns true if this channel should be excluded from available channel counts /// 18271 Channel count issues in groups /// /// /// public static bool ExcludeChannelFromCount(IHardwareChannel channel) { var excludeChannel = false; var moduleType = channel.ModuleSerialNumber.Split(new[] { DFConstantsAndEnums.SERIAL_SEPARATOR }, StringSplitOptions.RemoveEmptyEntries).Last(); switch (moduleType) { case DFConstantsAndEnums.RTCCLOCKNANOPAD_SERIAL_APPEND: case DFConstantsAndEnums.RTCSECONDANDMARKER_SERIAL_APPEND: case DFConstantsAndEnums.OPTICAL_SERIAL_APPEND: case DFConstantsAndEnums.MAGNETIC_SERIAL_APPEND: case DFConstantsAndEnums.MAGNETICSWITCH_SERIAL_APPEND: case DFConstantsAndEnums.MICROPHONE_SERIAL_APPEND: excludeChannel = true; break; case DFConstantsAndEnums.ATMOSPHERIC_SERIAL_APPEND: excludeChannel = (channel.ChannelNumber % 3) == DFConstantsAndEnums.CHANNEL_HUMIDITY; break; default: break; } return excludeChannel; } } public class PasteCommandClass : ICommand { public string Id { get; } public bool CanExecute(object parameter) { return true; } public void Execute(object parameter) { var eventAggregator = ContainerLocator.Container.Resolve(); try { if (!(parameter is TextBox tb)) { return; } object tag = null; if (!(tb.DataContext is IGroupChannel groupChannel)) { IGroupChannel temp = null; if (tb.DataContext is Control control) { if (!(control.DataContext is IGroupChannel tmp)) { return; } temp = tmp; tag = control.Tag; } else { return; } groupChannel = temp; } else { tag = tb.Tag; } if (!Clipboard.ContainsText()) { return; } var text = Clipboard.GetText(); var lines = text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); if (1 == lines.Length) { var line = lines[0]; if (line.IndexOfAny(new[] { ',', ';', '\t' }) < 0) { //this is a single field paste, don't do any further processing, let textchanged take care of it eventAggregator.GetEvent().Publish(new PageModifiedArg(PageModifiedArg.Status.Modified, null)); return; } } //wipe out the built in effect of the paste groupChannel.GroupName = groupChannel.GroupName; groupChannel.IsoChannelName = groupChannel.IsoChannelName; groupChannel.IsoCode = groupChannel.IsoCode; groupChannel.UserChannelName = groupChannel.UserChannelName; groupChannel.UserCode = groupChannel.UserCode; eventAggregator.GetEvent().Publish(new TextPastedArgs(text, groupChannel, Id, tag)); } catch (Exception ex) { eventAggregator.GetEvent().Publish(new PageErrorArg(new[] { ex.Message }, null)); } } public event EventHandler CanExecuteChanged; public PasteCommandClass(string id) { Id = id; } } public class TextPastedArgs : ITextPastedEventArgs { public TextPastedArgs(string text, IGroupChannel channel, string id, object tag) { Text = text; Sender = channel; Id = id; Tag = tag; } public string Text { get; } public object Sender { get; } public string Id { get; } public object Tag { get; } } }