// 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. -------------------------------------------------------------------------*/ // Ignore Spelling: ocp ovp using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using NLog; using Raytheon.Common; using Raytheon.Instruments.PowerSupply; using Raytheon.Units; namespace Raytheon.Instruments { /// /// A class to control a power supply system. /// public class PowerSupplySystemKeysight : IPowerSupplySystem, IDisposable { #region PrivateClassMembers private byte[] _readBuffer; private NetworkStream _tcpStream; private readonly SortedDictionary _powerModuleMap; private Dictionary _powerModuleInfoDict = new Dictionary(); //@@@ Don't want this here, but until the interface can change..this is the only option private readonly SortedDictionary _powerModuleInitialVoltageSetpoint; private string _name; private object _syncObj = new Object(); private const int _READ_TIMEOUT = 5000; private readonly List _moduleNumbersThatHaveBeenAdded; private readonly PowerScpiCommands _scpiCommands; private State _state; private readonly string _address; private readonly int _port; private SelfTestResult _selfTestResult; private readonly bool _shallWeCoupleOutputProtection; private List _groupedModules; private List _coupledModules; private readonly ILogger _logger; private readonly IConfigurationManager _configurationManager; private readonly IConfiguration _configuration; private IConfigurationFile _powerSupplySystemConfig; #endregion #region PublicFuctions /// /// PowerSupplySystemKeysight factory constructor /// /// /// /// public PowerSupplySystemKeysight(string deviceName, IConfigurationManager configurationManager) { const int READ_BUFFER_SIZE = 512; Name = deviceName; _logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}"); _configurationManager = configurationManager; _configuration = _configurationManager.GetConfiguration(Name); string powerSupplySystemDefPath = _configuration.GetConfigurationValue(deviceName, PowerSupply.ConfigXml.POWER_SUPPLY_SYSTEM_DEF_FILEPATH.ToString()); if (!Path.IsPathRooted(powerSupplySystemDefPath)) powerSupplySystemDefPath = Path.GetFullPath(Path.Combine(_configurationManager.ConfigurationStoragePath, powerSupplySystemDefPath)); _powerSupplySystemConfig = new ConfigurationFile(powerSupplySystemDefPath); _address = _powerSupplySystemConfig.ReadValue(deviceName, PowerSupply.ConfigIni.ETHERNET_ADDRESS.ToString()); Int32.TryParse(_powerSupplySystemConfig.ReadValue(deviceName, PowerSupply.ConfigIni.ETHERNET_PORT.ToString()), out _port); _port = _powerSupplySystemConfig.ReadValue(deviceName, PowerSupply.ConfigIni.ETHERNET_PORT.ToString(), 1); _shallWeCoupleOutputProtection = _powerSupplySystemConfig.ReadValue(deviceName, PowerSupply.ConfigIni.ENABLE_OUTPUT_COUPLING_PROTECTION.ToString(), false); _readBuffer = new byte[READ_BUFFER_SIZE]; _powerModuleInitialVoltageSetpoint = new SortedDictionary(StringComparer.InvariantCultureIgnoreCase); _moduleNumbersThatHaveBeenAdded = new List(); _powerModuleMap = new SortedDictionary(StringComparer.InvariantCultureIgnoreCase); var scpiDefPath = _powerSupplySystemConfig.ReadValue(deviceName, PowerSupply.ConfigIni.SCPI_DEF_FILEPATH.ToString()); if (!Path.IsPathRooted(scpiDefPath)) scpiDefPath = Path.GetFullPath(Path.Combine(_configurationManager.ConfigurationStoragePath, scpiDefPath)); _scpiCommands = new PowerScpiCommands(scpiDefPath); _state = State.Uninitialized; _selfTestResult = SelfTestResult.Unknown; } /// /// /// /// public bool ClearErrors() { throw new NotImplementedException(); } /// /// /// public string DetailedStatus { get { return "This is a Keysight Scpi Power Supply System called " + _name; } } /// /// /// public bool DisplayEnabled { get { throw new NotImplementedException(); } set { lock (_syncObj) { if (value == true) { // send the command string command = _scpiCommands._SET_FRONTPANEL_ENABLE_CMD + "\n"; IOWrite(command); } else { string command = _scpiCommands._SET_FRONTPANEL_DISABLE_CMD + "\n"; IOWrite(command); } } } } /// /// Dispose of this object. /// public void Dispose() { try { lock (_syncObj) { Dispose(true); GC.SuppressFinalize(this); } } catch (Exception ex) { _logger.Error(ex, ex.Message); } } /// /// /// public bool FrontPanelEnabled { get { throw new NotImplementedException(); } set { lock (_syncObj) { if (value == true) { // send the command string command = _scpiCommands._SET_FRONTPANEL_ENABLE_CMD + "\n"; IOWrite(command); } else { string command = _scpiCommands._SET_FRONTPANEL_DISABLE_CMD + "\n"; IOWrite(command); } } } } /// /// Get the error code. /// /// The error code. /// The error description. public string GetErrorCode(out int errorCode) { lock (_syncObj) { // not calling IOQuery() here so IOQuery() can call GetErrorCode() after each query string command = _scpiCommands._READ_ERROR_CODE_CMD + "\n"; byte[] commandBuffer = Encoding.ASCII.GetBytes(command); // send the data out CommInterfaceWrite(commandBuffer); // clear our buffer Array.Clear(_readBuffer, 0, _readBuffer.Length); // read the response string rspStr = GetResponse(); // parse the response string[] tokens = rspStr.Split(','); errorCode = Util.ConvertStringToInt32(tokens[0]); // it should always be 2 if (tokens.Length >= 2) { return tokens[1]; } else { return ""; } } } /// /// Get the names of the modules in this system /// /// public List GetModuleNames() { lock (_syncObj) { List moduleNames = new List(); foreach (KeyValuePair modules in _powerModuleMap) { moduleNames.Add(modules.Key); } return moduleNames; } } /// /// Get the dictionary that contains configuration information for each module /// /// public Dictionary GetPowerSupplyModuleInfoDict(string powerSystem) { lock (_syncObj) { return _powerModuleInfoDict; } } /// /// Get the overcurrent protection setting. /// /// The module to get the overcurrent protection setting. /// The current (Amps). public double GetOverCurrentSetting(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::GetOverCurrentSetting() - could not find supply: " + name.ToUpper() + " in System " + _name); } return _powerModuleMap[name.ToUpper()].CurrentLimit.Amps; } } /// /// Get the overvoltage protection setting. /// /// The module to get the overvoltage protection setting. /// The voltage (Volts). public double GetOverVoltageSetting(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::GetOverVoltageSetting() - could not find supply: " + name.ToUpper() + " in System " + _name); } return _powerModuleMap[name.ToUpper()].OverVoltageProtection.Volts; } } /// /// /// /// public double GetSlewRate(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::GetSlewRate() - could not find supply: " + name.ToUpper() + " in System " + _name); } throw new NotImplementedException(); //return _powerModuleMap[name.ToUpper()].GetSlewRate(); } } /// /// Get the voltage setpoint. /// /// The module to get the voltage setpoint setting. /// the voltage setpoint (Volts). public double GetVoltageSetting(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::GetVoltageSetting() - could not find supply: " + name.ToUpper() + " In System " + _name); } return _powerModuleMap[name.ToUpper()].OutputVoltage.Volts; } } /// /// /// public InstrumentMetadata Info { get { throw new NotImplementedException(); } } /// /// /// public void Initialize() { // if we have not yet been initialized, go ahead and create the socket if (_state == State.Uninitialized) { try { TcpClient powerSupplySocketConn = null; if (_tcpStream == null) { powerSupplySocketConn = new TcpClient(_address, _port); // connect to the supply and setup stream _tcpStream = powerSupplySocketConn.GetStream(); _tcpStream.ReadTimeout = _READ_TIMEOUT; Reset(); } string coupledModules = _powerSupplySystemConfig.ReadValue(Name, PowerSupply.ConfigIni.COUPLED_MODULES.ToString()); string groupedModules = _powerSupplySystemConfig.ReadValue(Name, PowerSupply.ConfigIni.GROUPED_MODULES.ToString()); string moduleDef = _powerSupplySystemConfig.ReadValue(Name, PowerSupply.ConfigIni.MODULE_DEFINITION.ToString()); _coupledModules = coupledModules.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries).ToList(); _groupedModules = groupedModules.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries).ToList(); List powerModules = moduleDef.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries).ToList(); bool systemRebooted = false; if (_groupedModules.Count() > 1) GroupModules(_groupedModules, out systemRebooted); else if (_coupledModules.Count() > 1) CoupleModules(_coupledModules); if (systemRebooted) { _tcpStream.Close(); powerSupplySocketConn.Close(); powerSupplySocketConn = new TcpClient(_address, _port); _tcpStream = powerSupplySocketConn.GetStream(); _tcpStream.ReadTimeout = _READ_TIMEOUT; } if (_groupedModules.Count() > 1) { powerModules.Clear(); // since modules are grouped, we pick the first module as the representative module powerModules.Add(_groupedModules[0]); } double overCurrentProtection; double overVoltageProtection; double voltageSetpoint; double maxVoltageSetpoint; double minVoltageSetpoint; double slewRateVoltsPerSecond; double inRushDelaySecs; int moduleNumber = -1; for (int i = 0; i < powerModules.Count(); i++) { string moduleName = powerModules[i]; int.TryParse(_powerSupplySystemConfig.ReadValue($"{Name}.{moduleName}", PowerSupply.ConfigIni.INDEX.ToString()), out moduleNumber); Double.TryParse(_powerSupplySystemConfig.ReadValue($"{Name}.{moduleName}", PowerSupply.ConfigIni.OCP.ToString()), out overCurrentProtection); Double.TryParse(_powerSupplySystemConfig.ReadValue($"{Name}.{moduleName}", PowerSupply.ConfigIni.OVP.ToString()), out overVoltageProtection); Double.TryParse(_powerSupplySystemConfig.ReadValue($"{Name}.{moduleName}", PowerSupply.ConfigIni.VOLTAGE_SETPOINT.ToString()), out voltageSetpoint); Double.TryParse(_powerSupplySystemConfig.ReadValue($"{Name}.{moduleName}", PowerSupply.ConfigIni.MIN_VOLTAGE.ToString()), out minVoltageSetpoint); Double.TryParse(_powerSupplySystemConfig.ReadValue($"{Name}.{moduleName}", PowerSupply.ConfigIni.MAX_VOLTAGE.ToString()), out maxVoltageSetpoint); try { if (!Double.TryParse(_powerSupplySystemConfig.ReadValue($"{Name}.{moduleName}", PowerSupply.ConfigIni.VOLTAGE_SLEW_RATE.ToString()), out slewRateVoltsPerSecond)) slewRateVoltsPerSecond = -1.0; } catch { slewRateVoltsPerSecond = -1.0; } try { if (!Double.TryParse(_powerSupplySystemConfig.ReadValue($"{Name}.{moduleName}", PowerSupply.ConfigIni.IN_RUSH_DELAY_SECS.ToString()), out inRushDelaySecs)) inRushDelaySecs = -1.0; } catch { inRushDelaySecs = -1.0; } _powerModuleInfoDict[moduleName] = new PowerSupplyModuleInfo(moduleNumber, overCurrentProtection, overVoltageProtection, voltageSetpoint, slewRateVoltsPerSecond, minVoltageSetpoint, maxVoltageSetpoint); // create and initialize the power module IDCPwr powerSupply = new PowerSupplyKeysight(moduleName, _scpiCommands, overCurrentProtection, overVoltageProtection, voltageSetpoint, maxVoltageSetpoint, minVoltageSetpoint, inRushDelaySecs, slewRateVoltsPerSecond, _tcpStream, moduleNumber); // remember that we have added this module _moduleNumbersThatHaveBeenAdded.Add(moduleNumber); // remember the module name _powerModuleMap.Add(moduleName.ToUpper(), powerSupply); // remember the initial voltage setpoint _powerModuleInitialVoltageSetpoint.Add(moduleName.ToUpper(), voltageSetpoint); powerSupply.Initialize(); } if (_shallWeCoupleOutputProtection == true) { EnableOutputProtectionCoupling(); } _state = State.Ready; } catch (Exception) { throw; } } else { throw new Exception("PowerSupplySystemKeysight::Initialize() - expected the state of System " + _name + " to be Uninitialized, state was: " + _state.ToString()); } } /// /// Query the output state. /// /// The module to query. /// The output state. True = On, False = Off. public bool IsOutputOn(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::IsOutputOn() - could not find supply: " + name.ToUpper() + " In System " + _name); } return _powerModuleMap[name.ToUpper()].Enabled; } } /// /// Send a command to the power supply and get the response. /// /// The command to send. /// The power supply response. public string IOQuery(string commandString) { lock (_syncObj) { // not calling IOWrite() so IOWrite() can check for errors after each write // convert to a byte array byte[] commandBuffer = Encoding.ASCII.GetBytes(commandString); // send the data out CommInterfaceWrite(commandBuffer); // clear our buffer Array.Clear(_readBuffer, 0, _readBuffer.Length); // read from the response string rspStr = GetResponse(); // check for errors int errorCode = -1; string err = GetErrorCode(out errorCode); if (errorCode != 0) { throw new Exception("PowerSupplySystemKeysight::IOQuery() - System " + _name + " returned error: " + err); } return rspStr; } } /// /// Sends a SCPI Command to the instrument. /// /// The SCPI Command to be sent to the instrument. public void IOWrite(string commandString) { lock (_syncObj) { // convert to a byte array byte[] commandBuffer = Encoding.ASCII.GetBytes(commandString); // send the data out CommInterfaceWrite(commandBuffer); // check for errors int errorCode = -1; string err = GetErrorCode(out errorCode); if (errorCode != 0) { throw new Exception("PowerSupplySystemKeysight::IOWrite() - System " + _name + " returned error: " + err); } } } /// /// Control the power supply internal mechanical relay state /// /// The module to act on /// True to connect, false to disconnect public void MechanicalRelayOutputControl(string name, bool shallWeConnect) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::MechanicalRelayOutputControl() - could not find supply: " + name.ToUpper() + " In System " + _name); } _powerModuleMap[name.ToUpper()].MechanicalRelayOutputControl(shallWeConnect); } } /// /// Read the current. /// /// The name of the module. /// The current (Amps). public double MeasureCurrent(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::MeasureCurrent() - could not find supply: " + name.ToUpper() + " In System " + _name); } return _powerModuleMap[name.ToUpper()].MeasureCurrent().Amps; } } /// /// Read the voltage. /// /// The name of the module. /// The voltage (Volts). public double MeasureVoltage(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::MeasureVoltage() - could not find supply: " + name.ToUpper() + " In System " + _name); } return _powerModuleMap[name.ToUpper()].MeasureVoltage().Volts; } } /// /// /// public string Name { get { return _name; } set { _name = value; } } /// /// Turn the output off. /// /// The name of the module. public void Off(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::Off() - could not find supply: " + name.ToUpper() + " In System " + _name); } _powerModuleMap[name.ToUpper()].Enabled = false; _powerModuleInfoDict[name].isOn_ = false; } } /// /// Turn the output on. /// /// The name of the module. public void On(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::On() - could not find supply: " + name.ToUpper() + " In System " + _name); } _powerModuleMap[name.ToUpper()].Enabled = true; _powerModuleInfoDict[name].isOn_ = true; } } /// /// /// /// public SelfTestResult PerformSelfTest() { TcpClient powerSupplySocketConn = null; try { lock (_syncObj) { if (_tcpStream == null) { powerSupplySocketConn = new TcpClient(_address, _port); // connect to the supply and setup stream _tcpStream = powerSupplySocketConn.GetStream(); _tcpStream.ReadTimeout = _READ_TIMEOUT; Reset(); } // change the timeout to account for the long self test CommSetReadTimeout(30000); // send the command and get the response string command = _scpiCommands._SELFTEST_CMD + "\n"; string rspStr = IOQuery(command); // parse the response string[] tokens = rspStr.Split('\n'); int rsp = Util.ConvertStringToInt32(tokens[0]); if (rsp != 0) { _selfTestResult = SelfTestResult.Fail; string errorMsg = "PowerSupplySystemKeysight::PerformSelfTest() - System " + _name + " returned an error: " + rsp.ToString(); throw new Exception(errorMsg); } _selfTestResult = SelfTestResult.Pass; return SelfTestResult.Pass; } } catch (Exception) { _selfTestResult = SelfTestResult.Fail; throw; } finally { if (_tcpStream != null) { _tcpStream.Close(); _tcpStream = null; } if (powerSupplySocketConn != null) powerSupplySocketConn.Close(); } } /// /// Read the overvoltage and overcurrent protection status. /// /// The name of the module. /// The binary sum of all bits (decimal value) set in the Questionable Status Enable register. public int ReadProtectionStatus(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::ReadProtectionStatus() - could not find supply: " + name.ToUpper() + " In System " + _name); } return _powerModuleMap[name.ToUpper()].ReadProtectionStatus(); } } /// /// reads power data /// /// /// A Power Data Object public PowerData ReadPowerData(string name) { lock (_syncObj) { // voltage, voltage setpoint, current, output status double voltage = MeasureVoltage(name); double voltageSetpoint = GetVoltageSetting(name); double current = MeasureCurrent(name); bool isOutputOn = IsOutputOn(name); int faultStatus = ReadProtectionStatus(name); double overVoltageProtection = GetOverVoltageSetting(name); double overCurrentProtection = GetOverCurrentSetting(name); return new PowerData(voltage, voltageSetpoint, overVoltageProtection, current, overCurrentProtection, isOutputOn, faultStatus); } } /// /// reads power data /// /// /// /// /// /// /// public void ReadPowerData(string moduleName, out double voltage, out double voltageSetpoint, out double current, out bool isOutputOn, out int faultStatus) { lock (_syncObj) { // voltage, voltage setpoint, current, output status voltage = MeasureVoltage(moduleName); voltageSetpoint = GetVoltageSetting(moduleName); current = MeasureCurrent(moduleName); isOutputOn = IsOutputOn(moduleName); faultStatus = ReadProtectionStatus(moduleName); } } /// /// Resets the instrument /// public void Reset() { lock (_syncObj) { // send the command string command = _scpiCommands._RESET_CMD + "\n"; IOWrite(command); } } /// /// /// public SelfTestResult SelfTestResult { get { return _selfTestResult; } } /// /// Changes the setpoint voltage back to the value that was passed into the constructor /// /// The name of the power module public void SetInitialVoltage(string name) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::SetInitialVoltage() - could not find supply: " + name.ToUpper() + " In System " + _name); } double initializeVoltage = _powerModuleInitialVoltageSetpoint[name.ToUpper()]; SetVoltageSetpoint(name.ToUpper(), initializeVoltage); } } /// /// Set the slew rate /// /// slew in volts per second public void SetSlewRate(string name, double commandedSlew) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::SetSlewRate() - could not find supply: " + name.ToUpper() + " In System " + _name); } throw new NotImplementedException(); //_powerModuleMap[name.ToUpper()].SetSlewRate(commandedSlew); } } /// /// Set the OCP value /// /// The name of the power module /// The value in amps to set as the OCP public void SetOverCurrentProtection(string moduleName, double ocpValue) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(moduleName.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::SetOverCurrentrotection() - could not find supply: " + moduleName.ToUpper() + " In System " + _name); } _powerModuleMap[moduleName.ToUpper()].CurrentLimit = Current.FromAmps(ocpValue); } } /// /// /// /// The name of the module /// The value in volts to set as the OVP public void SetOverVoltageProtection(string moduleName, double ovpValue) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(moduleName.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::SetOverVoltageProtection() - could not find supply: " + moduleName.ToUpper() + " In System " + _name); } _powerModuleMap[moduleName.ToUpper()].OverVoltageProtection = Voltage.FromVolts(ovpValue); } } /// /// Set the voltage setpoint. /// /// The name of the module. /// The desired voltage (in volts). public void SetVoltageSetpoint(string name, double volts) { lock (_syncObj) { if (_powerModuleMap.ContainsKey(name.ToUpper()) == false) { throw new Exception("PowerSupplySystemKeysight::SetVoltageSetpoint() - could not find supply: " + name.ToUpper() + " In System " + _name); } _powerModuleMap[name.ToUpper()].OutputVoltage = Voltage.FromVolts(volts); } } /// /// Turns off each supply, resets the system and disposes the socket /// public void Shutdown() { lock (_syncObj) { string errorMsg = ""; if (_state == State.Ready) { try { foreach (KeyValuePair entry in _powerModuleMap) { entry.Value.Shutdown(); } } catch (Exception ex) { _logger.Error(ex, ex.Message); } try { //Reset System Reset(); } catch (Exception ex) { _logger.Error(ex, ex.Message); } _state = State.Uninitialized; } // the stream was created in the constructor, dispose of it here try { if (_tcpStream != null) { _tcpStream.Dispose(); _tcpStream = null; } } catch (Exception ex) { _logger.Error(ex, ex.Message); } if (errorMsg != "") { throw new Exception("PowerSupplySystemKeysight::ShutdDown() - System " + _name + " Had an error: " + errorMsg); } } } /// /// /// public State Status { get { return _state; } } /// /// Turn off the watchdog capability. /// public void WatchdogDisable() { lock (_syncObj) { // send the command string command = _scpiCommands._SET_WATCHDOGOFF_CMD + "\n"; IOWrite(command); } } /// /// Turn on the watchdog capability. /// /// The watchdog time in seconds. public void WatchdogEnable(uint time) { lock (_syncObj) { string timeCommand = _scpiCommands._SET_WATCHDOGDELAY_CMD + " " + time.ToString() + "\n"; IOWrite(timeCommand); // send the command string onCommand = _scpiCommands._SET_WATCHDOGON_CMD + "\n"; IOWrite(onCommand); } } /// /// gets system name /// /// public string GetSystemName() { return _name; } #endregion #region PrivateFuctions /// /// The Finalizer. /// ~PowerSupplySystemKeysight() { Dispose(false); } /// /// Read data from the comm interface /// private string GetResponse() { string response = String.Empty; int bytesRead = _tcpStream.Read(_readBuffer, 0, _readBuffer.Length); if (bytesRead > 0) { response = Encoding.ASCII.GetString(_readBuffer, 0, bytesRead); } return response; } /// /// Set the comm interface timeout /// /// private void CommSetReadTimeout(int readTimeout) { _tcpStream.ReadTimeout = readTimeout; } /// /// Write data to the comm interface /// private void CommInterfaceWrite(byte[] dataToWrite) { _tcpStream.Write(dataToWrite, 0, dataToWrite.Length); } /// /// Dispose of this object. /// /// True = currently disposing, False = not disposing. protected virtual void Dispose(bool disposing) { lock (_syncObj) { if (disposing) { if (_state == State.Ready) { try { foreach (KeyValuePair entry in _powerModuleMap) { entry.Value.Shutdown(); } } catch (Exception ex) { _logger.Error(ex, ex.Message); } try { //Reset System Reset(); } catch (Exception ex) { _logger.Error(ex, ex.Message); } _state = State.Uninitialized; } // the stream was created in the constructor, dispose of it here if it is not null (Could be null if Shutdown() was called) try { if (_tcpStream != null) { _tcpStream.Dispose(); _tcpStream = null; } } catch (Exception ex) { _logger.Error(ex, ex.Message); } } } } /// /// Turns on the output protection coupling /// private void EnableOutputProtectionCoupling() { string command = _scpiCommands._SET_COUPLE_OUTPUT_PROTECT_ON_CMD + "\n"; IOWrite(command); } /// /// Group Modules Together /// /// private void GroupModules(List moduleNameList, out bool systemRebooted) { // 1. Group the channels string groupListToDefine = "(@"; string groupListToQuery = ""; string moduleNumber = ""; systemRebooted = false; for (int i = 0; i < moduleNameList.Count; i++) { moduleNumber = _powerSupplySystemConfig.ReadValue(moduleNameList[i], PowerSupply.ConfigIni.INDEX.ToString()); groupListToDefine += moduleNumber; groupListToQuery += moduleNumber; // add a ',' if this is not the final element in the list if (i < moduleNameList.Count() - 1) { groupListToDefine += ","; groupListToQuery += ","; } else { groupListToDefine += ")"; } } groupListToQuery = "\"" + groupListToQuery + "\"\n"; // see if channels are grouped string queryGroupCommand = _scpiCommands._QUERY_COUPLE_CHANNELS_CMD + "\n"; for (int i = 1; i <= 2; i++) { string respStr = IOQuery(queryGroupCommand); // if modules are not grouped if (respStr != groupListToQuery) { groupListToDefine += "\n"; string groupCommand = _scpiCommands._SET_GROUP_DEFINE_CMD + " " + groupListToDefine; IOWrite(groupCommand); } else if (i == 1) { break; } else { string command = _scpiCommands._REBOOT_CMD + "\n"; // after grouping the modules, need to reboot system for it to take effect IOWrite(command); // wait 20 seconds for reboot Thread.Sleep(20000); systemRebooted = true; } } } /// /// Couple modules together (output synchronization) /// /// private void CoupleModules(List moduleNameList) { string coupleListToDefine = ""; string moduleNumber = ""; for (int i = 0; i < moduleNameList.Count(); i++) { moduleNumber = _powerSupplySystemConfig.ReadValue($"{Name}.{moduleNameList[i]}", PowerSupply.ConfigIni.INDEX.ToString()); coupleListToDefine += moduleNumber; // add a ',' if this is not the final element in the list if (i < moduleNameList.Count() - 1) { coupleListToDefine += ","; } } coupleListToDefine += "\n"; // see if channels are coupled string queryCoupleChannelCommand = _scpiCommands._QUERY_COUPLE_CHANNELS_CMD + "\n"; for (int i = 1; i <= 2; i++) { string respStr = IOQuery(queryCoupleChannelCommand); string queryCoupleStateCommand = _scpiCommands._QUERY_COUPLE_STATE_CMD + "\n"; string respStr2 = IOQuery(queryCoupleStateCommand); if (coupleListToDefine != respStr || respStr2 == "0\n") { // send command to couple modules string command = _scpiCommands._SET_COUPLE_CHANNELS_CMD + " " + coupleListToDefine; IOWrite(command); // turn coupling on command = _scpiCommands._SET_COUPLE_ON_CMD + "\n"; IOWrite(command); // output protection on command = _scpiCommands._SET_COUPLE_OUTPUT_PROTECT_ON_CMD + "\n"; IOWrite(command); } else if (i == 1) break; } } #endregion } }