// UNCLASSIFIED
/*-------------------------------------------------------------------------
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
COMPANY.
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using NLog;
using Raytheon.Common;
using Raytheon.Instruments;
using Raytheon.Instruments.Dmm;
using Raytheon.Units;
namespace MeasurementManagerLib
{
///
/// The interface to the instruments contained in the vsu test station.
/// This class reads in test station configuration ini file that contains:
/// - DMM measurement definitions
/// The host of this class can invoke those measurements by commanding the this class with the ini file string names
/// which insulates the caller from having to know the details of that measurement
///
public class SwitchMeasurementManager : IDisposable
{
#region PublicMembers
///
/// Type of DMM Resistance Measurements
///
public enum DMMResistanceType
{
TWO,
FOUR,
};
public enum DMMVoltageType
{
DC,
AC,
};
public Dictionary _dmmResistancePseudoTypeToTrueTypeMap = new Dictionary() {
{ DMMResistanceType.TWO, MeasurementFunction.TwoWireResistance } ,
{ DMMResistanceType.FOUR, MeasurementFunction.FourWireResistance }
};
///
/// Struct for holding on to DMM measurement definitions
///
public struct DMMFrequencyMeasurementFields
{
public readonly double _range;
public readonly double _resolution;
public readonly double _scaleFactor;
public readonly int _delay;
public List _relays;
public readonly double _voltRange;
public readonly double _numReads;
public DMMFrequencyMeasurementFields(double range, double resolution, int delay, double scaleFactor, List relays, double voltRange, double numReads)
{
_range = range;
_resolution = resolution;
_delay = delay;
_scaleFactor = scaleFactor;
_relays = relays;
_voltRange = voltRange;
_numReads = numReads;
}
}
///
/// Struct for holding on to DMM measurement definitions
///
public struct DMMVoltageMeasurementFields
{
public readonly double _range;
public readonly double _resolution;
public readonly double _scaleFactor;
public readonly int _delay;
public List _relays;
public DMMVoltageType _voltageType;
public DMMVoltageMeasurementFields(double range, double resolution, int delay, double scaleFactor, List relays, DMMVoltageType voltageType)
{
_range = range;
_resolution = resolution;
_delay = delay;
_scaleFactor = scaleFactor;
_relays = relays;
_voltageType = voltageType;
}
}
///
/// Struct for holding on to DMM measurement definitions
///
public struct DMMResistanceMeasurementFields
{
public readonly string _pcode;
public readonly double _range;
public readonly double _resolution;
public readonly double _scaleFactor;
public readonly int _minDelay;
public readonly int _maxDelay;
public string _relayPath;
public Raytheon.Instruments.Dmm.MeasurementFunction _dmmResistanceType;
public readonly string _cableAndPinId;
public readonly double _lowerLimit;
public readonly double _upperLimit;
public DMMResistanceMeasurementFields(string pcode, double range, double resolution, int minDelay, int maxDelay, double scaleFactor, string relayPath, Raytheon.Instruments.Dmm.MeasurementFunction type, string cableAndPinId, double lowerLimit, double upperLimit)
{
_pcode = pcode;
_range = range;
_resolution = resolution;
_minDelay = minDelay;
_maxDelay = maxDelay;
_scaleFactor = scaleFactor;
_relayPath = relayPath;
_dmmResistanceType = type;
_cableAndPinId = cableAndPinId;
_lowerLimit = lowerLimit;
_upperLimit = upperLimit;
}
}
///
/// State for a trigger edge.
///
public enum ScopeEdge
{
FALLING = 0,
RISING,
HOLDING
};
public readonly struct ScopePulseWidthMeasurementFields
{
public readonly List _relays;
public readonly int _channelNumber;
public readonly ScopeEdge _edge;
public readonly double _timePerDivision;
public readonly double _timeOffset;
public readonly double _triggerLevel;
public readonly double _voltageOffset;
public readonly double _voltageScale;
public readonly string _inputImpedance;
//public readonly double m_measurementTime;
public readonly int _delay;
public readonly bool _shallWeSaveImage;
public readonly int _maxTriggerWaitTime;
public ScopePulseWidthMeasurementFields(List relays, int channelNumber, ScopeEdge edge, double timePerDivision, double timeOffset, double triggerLevel, double voltageOffset, double voltageScale, string inputImpedance, int delay, bool shallWeSaveImage, int maxTriggerWaitTime)
{
_relays = relays;
_channelNumber = channelNumber;
_edge = edge;
_inputImpedance = inputImpedance;
_timePerDivision = timePerDivision;
_timeOffset = timeOffset;
_triggerLevel = triggerLevel;
_voltageOffset = voltageOffset;
_voltageScale = voltageScale;
_delay = delay;
_shallWeSaveImage = shallWeSaveImage;
_maxTriggerWaitTime = maxTriggerWaitTime;
}
}
public readonly struct ScopeFrequencyMeasurementFields
{
public readonly List _relays;
public readonly int _channelNumber;
public readonly ScopeEdge _edge;
public readonly double _timePerDivision;
public readonly double _timeOffset;
public readonly double _triggerLevel;
public readonly double _voltageOffset;
public readonly double _voltageScale;
public readonly string _inputImpedance;
//public readonly double m_measurementTime;
public readonly int _delay;
public readonly bool _shallWeSaveImage;
public readonly int _maxTriggerWaitTime;
public ScopeFrequencyMeasurementFields(List relays, int channelNumber, ScopeEdge edge, double timePerDivision, double timeOffset, double triggerLevel, double voltageOffset, double voltageScale, string inputImpedance, int delay, bool shallWeSaveImage, int maxTriggerWaitTime)
{
_relays = relays;
_channelNumber = channelNumber;
_edge = edge;
_inputImpedance = inputImpedance;
_timePerDivision = timePerDivision;
_timeOffset = timeOffset;
_triggerLevel = triggerLevel;
_voltageOffset = voltageOffset;
_voltageScale = voltageScale;
_delay = delay;
_shallWeSaveImage = shallWeSaveImage;
_maxTriggerWaitTime = maxTriggerWaitTime;
}
}
public Dictionary DmmFrequencyMeasurements { get; private set; }
public Dictionary DmmResistanceMeasurements { get; private set; }
public Dictionary DmmVoltageMeasurements { get; private set; }
public Dictionary ScopeFreqMeasurements { get; private set; }
public Dictionary ScopePulseWidthMeasurements { get; private set; }
public Dictionary RelayMap { get; private set; }
#endregion
#region PrivateClassMembers
///
/// private class members
///
private readonly IDmm _dmm;
private readonly IOscilloScope _scope;
private readonly Dictionary _switchCards;
private static readonly object _syncObj = new Object();
private static NLog.ILogger _logger;
#endregion
#region PrivateFunctions
///
/// The Finalizer
///
~SwitchMeasurementManager()
{
}
///
/// Check configuration information is correct
///
private void CheckForDmmResistanceConfigValidity()
{
foreach (KeyValuePair entry in DmmResistanceMeasurements)
{
string[] relayInfo = entry.Value._relayPath.Split(':');
if (relayInfo.Length != 2)
{
throw new Exception("Relay format is not correct: " + relayInfo[0]);
}
if (_switchCards.ContainsKey(relayInfo[0].ToUpper()) == false)
{
throw new Exception("Switch card does not exist: " + relayInfo[0]);
}
}
}
///
/// Check configuration information is correct
///
private void CheckForDmmFrequencyConfigValidity()
{
foreach (KeyValuePair entry in DmmFrequencyMeasurements)
{
string[] relayInfo = entry.Value._relays[0].Split(':');
if (relayInfo.Length != 2)
{
throw new Exception("Relay format is not correct: " + relayInfo[0]);
}
if (_switchCards.ContainsKey(relayInfo[0].ToUpper()) == false)
{
throw new Exception("Switch card does not exist: " + relayInfo[0]);
}
}
}
///
/// Check configuration information is correct
///
private void CheckForDmmVoltageConfigValidity()
{
foreach (KeyValuePair entry in DmmVoltageMeasurements)
{
string[] relayInfo = entry.Value._relays[0].Split(':');
if (relayInfo.Length != 2)
{
throw new Exception("Relay format is not correct: " + relayInfo[0]);
}
if (_switchCards.ContainsKey(relayInfo[0].ToUpper()) == false)
{
throw new Exception("Switch card does not exist: " + relayInfo[0]);
}
}
}
///
/// Check configuration information is correct
///
private void CheckForScopeFrequencyConfigValidity()
{
foreach (KeyValuePair entry in ScopeFreqMeasurements)
{
string[] relayInfo = entry.Value._relays[0].Split(':');
if (relayInfo.Length != 2)
{
throw new Exception("Relay format is not correct: " + relayInfo[0]);
}
if (_switchCards.ContainsKey(relayInfo[0].ToUpper()) == false)
{
throw new Exception("Switch card does not exist: " + relayInfo[0]);
}
}
}
///
/// Check configuration information is correct
///
private void CheckForScopePulseWidthConfigValidity()
{
foreach (KeyValuePair entry in ScopePulseWidthMeasurements)
{
string[] relayInfo = entry.Value._relays[0].Split(':');
if (relayInfo.Length != 2)
{
throw new Exception("Relay format is not correct: " + relayInfo[0]);
}
if (_switchCards.ContainsKey(relayInfo[0].ToUpper()) == false)
{
throw new Exception("Switch card does not exist: " + relayInfo[0]);
}
}
}
///
/// Dispose of this objects resources
///
///
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_dmm != null)
{
_dmm.Shutdown();
}
if (_switchCards != null)
{
foreach (KeyValuePair switchCard in _switchCards)
{
if (_switchCards[switchCard.Key] != null)
{
_switchCards[switchCard.Key].Shutdown();
}
}
}
if (_scope != null)
{
_scope.Shutdown();
}
}
}
///
/// Will command the switch cards close a specified list of relays
///
///
public void SwitchRelayClose(List relayList)
{
string cardName = String.Empty;
string path = String.Empty;
foreach (string item in relayList)
{
//break out the card and relay
if (item.Contains(":"))
{
string[] itemArray = item.Split(':');
cardName = itemArray[0].Trim();
path = itemArray[1].Trim();
}
else
path = item.Trim();
if (!String.IsNullOrEmpty(cardName))
{
//close the relays
_switchCards[cardName.ToUpper()].Connect(path);
}
}
}
///
/// Will command the switch cards close a specified list of relays
///
///
public void SwitchRelayClose(string relayPath)
{
string cardName = String.Empty;
string path = String.Empty;
string[] itemArray = relayPath.Split(':');
//break out the card and relay
if (itemArray.Length == 2)
{
cardName = itemArray[0].Trim();
path = itemArray[1].Trim();
}
else
{
throw new Exception($"Invalid relay path: {relayPath}. Expected format: [Switch_Instance_Name]:[RelayPath]");
}
if (!String.IsNullOrEmpty(cardName))
{
//close the relays
_switchCards[cardName.ToUpper()].Connect(path);
}
}
///
/// Will command the switch card open all relays or the specified list of relays
///
/// Optional list of relays to open
public void SwitchRelayOpen(List relayList)
{
string cardName = String.Empty;
string path = String.Empty;
foreach (string item in relayList)
{
//break out the card and relay
if (item.Contains(":"))
{
string[] itemArray = item.Split(':');
cardName = itemArray[0].Trim();
path = itemArray[1].Trim();
}
else
path = item.Trim();
if (!String.IsNullOrEmpty(cardName))
{
//close the relays
_switchCards[cardName.ToUpper()].Disconnect(path);
}
}
}
///
/// Will command the switch cards close a specified list of relays
///
///
public void SwitchRelayOpen(string relayPath)
{
string cardName = String.Empty;
string path = String.Empty;
string[] itemArray = relayPath.Split(':');
//break out the card and relay
if (itemArray.Length == 2)
{
cardName = itemArray[0].Trim();
path = itemArray[1].Trim();
}
else
{
throw new Exception($"Invalid relay path: {relayPath}. Expected format: [Switch_Instance_Name]:[RelayPath]");
}
if (!String.IsNullOrEmpty(cardName))
{
//close the relays
_switchCards[cardName.ToUpper()].Disconnect(path);
}
}
///
/// Opens all relays on all switch cards
///
private void SwitchRelayOpenAll()
{
foreach (KeyValuePair switchCard in _switchCards)
{
_switchCards[switchCard.Key].DisconnectAll();
}
}
#endregion
#region PublicFunctions
///
/// constructor that uses instrument manager for creating an instrument
///
///
///
/// Skip DMM initialzation, since we want to initialize it separately like the SquibMeter
public SwitchMeasurementManager(IInstrumentManager instrumentManager, string switchMeasurementManagerConfigFullPath, bool skipDmmInitialization = false)
{
_logger = LogManager.GetCurrentClassLogger();
_switchCards = new Dictionary();
ICollection