Files
GenericTeProgramLibrary/Source/TSRealLib/MAL/Managers/PowerSupplyMeasurementManger/PowerSupplyMeasurementManager.cs
2025-03-13 12:04:22 -07:00

781 lines
26 KiB
C#

// 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: Selftest ovp ocp
using NLog;
using Raytheon.Instruments;
using Raytheon.Instruments.PowerSupply;
using Raytheon.Common;
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace MeasurementManagerLib
{
/// <summary>
/// The entry point for the library that controls power supplies.
/// This class parses out the definition of all power supplies in a system and provides control to the host.
/// In simple cases, the host only needs to fill in the ini file and use the OutputDisable() and OutputEnable() functions.
/// A variety of other capability is exposed for more complex applications.
/// </summary>
public class PowerSupplyMeasurementManager : IDisposable
{
#region PublicClassMembers
/// <summary>
/// A callback definition for the power monitor.
/// The host may pass in this delegate to PowerLogStart() to receive callbacks from the monitor thread.
/// </summary>
/// <param name="retData">The callback returns a comma delimited string of the format: "System, Module, voltage, voltage setpoint, current, output status, fault status";</param>
/// <param name="errorCode">If an exception is thrown in the monitor thread, this value will be set to -1, else it will be 0;</param>
public delegate void PowerMonitorDelegate(List<PowerMonitorCallbackData> retData, int errorCode);
#endregion
#region PrivateClassMembers
// power system name to power system object
private SortedDictionary<string, IPowerSupplySystem> _powerSystemNameToObjectMap;
// power module name to power system object
private SortedDictionary<string, IPowerSupplySystem> _powerModuleNameToObjectMap;
private PowerSupplyDataLogWorker _dataLogWorker;
private Thread _dataLogThread;
// these are used to remember the logging thread params if the host is loading new power def files
string _prevPowerLogFileName;
int _prevPowerLogRestTime;
PowerMonitorDelegate _prevPowerLogCallback;
private static NLog.ILogger _logger;
private IInstrumentManager _instrumentManager;
private string _powerSystemWithFailedSelfTest = String.Empty;
#endregion
#region PublicFuctions
/// <summary>
/// will create an array of power systems with power supplies
/// </summary>
/// <param name="instrumentManager"></param>
/// <param name="powerSupplySystems"></param>
public PowerSupplyMeasurementManager(IInstrumentManager instrumentManager)
{
_logger = LogManager.GetCurrentClassLogger();
_instrumentManager = instrumentManager;
_powerSystemNameToObjectMap = new SortedDictionary<string, IPowerSupplySystem>();
// create some maps to support the functions the MAL input
_powerSystemNameToObjectMap = new SortedDictionary<string, IPowerSupplySystem>(StringComparer.InvariantCultureIgnoreCase);
_powerModuleNameToObjectMap = new SortedDictionary<string, IPowerSupplySystem>(StringComparer.InvariantCultureIgnoreCase);
ICollection<object> powerSystemList = _instrumentManager.GetInstruments(typeof(IPowerSupplySystem));
// populate the maps
foreach (IPowerSupplySystem powerSystem in powerSystemList)
{
powerSystem.Initialize();
_powerSystemNameToObjectMap[powerSystem.Name.ToUpper()] = powerSystem;
List<string> moduleNames = powerSystem.GetModuleNames();
foreach (string moduleName in moduleNames)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()))
{
throw new Exception("There is more than 1 power system that have the same module name: " + moduleName);
}
_powerModuleNameToObjectMap[moduleName.ToUpper()] = powerSystem;
}
}
PerformPowerSupplySelfTests();
if (_powerSystemWithFailedSelfTest != String.Empty)
{
throw new Exception($"{_powerSystemWithFailedSelfTest}'s self-test failed.");
}
}
/// <summary>
/// Perform self test on power supply system
/// Self test for each power system takes a while, so we don't want to run self test every time we initialize the power system
/// So we only want to run self test under 2 conditions:
/// 1. Certain time has elapsed since last power off
/// 2. Certain time has elapsed since last self test run ( in the absence of power off time)
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private void PerformPowerSupplySelfTests()
{
_logger.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
string errorMsg = String.Empty;
ICollection<object> powerSystemList = _instrumentManager.GetInstruments(typeof(IPowerSupplySystem));
Task[] taskArray = new Task[powerSystemList.Count];
int index = 0;
foreach (IPowerSupplySystem powerSystem in powerSystemList)
{
// perform self test on power system
Task task = Task.Factory.StartNew(() => PerformPowerSupplySelfTestTask(powerSystem));
taskArray.SetValue(task,index++);
}
Task.WaitAll(taskArray);
}
/// <summary>
/// Perform self test on power supply system
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private void PerformPowerSupplySelfTestTask(IPowerSupplySystem powerSystem)
{
SelfTestResult result = SelfTestResult.Pass;
_logger?.Debug($"{this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() for {powerSystem.Name} is running...");
try
{
result = powerSystem.PerformSelfTest();
if (result == SelfTestResult.Fail && String.IsNullOrEmpty(_powerSystemWithFailedSelfTest))
{
_powerSystemWithFailedSelfTest = powerSystem.Name;
}
}
catch (Exception ex)
{
_logger?.Error(ex.Message + "\n" + ex.StackTrace);
}
_logger?.Debug($"{this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() for {powerSystem.Name} is exiting...");
}
/// <summary>
/// Disable the power supply display interface.
/// </summary>
/// <param name="powerSystem">The name of the system to disable, as defined in the config file</param>
public void DisplayDisable(string powerSystem)
{
if (_powerSystemNameToObjectMap.ContainsKey(powerSystem.ToUpper()) == false)
{
throw new Exception("Could not find power system: " + powerSystem);
}
_powerSystemNameToObjectMap[powerSystem.ToUpper()].DisplayEnabled = false;
}
/// <summary>
/// Enable the power supply display interface.
/// </summary>
/// <param name="powerSystem">The name of the system to disable, as defined in the config file</param>
public void DisplayEnable(string powerSystem)
{
if (_powerSystemNameToObjectMap.ContainsKey(powerSystem.ToUpper()) == false)
{
throw new Exception("Could not find power system: " + powerSystem);
}
_powerSystemNameToObjectMap[powerSystem.ToUpper()].DisplayEnabled = true;
}
/// <summary>
/// Dispose of this object.
/// </summary>
public void Dispose()
{
try
{
Dispose(true);
GC.SuppressFinalize(this);
}
catch (Exception err)
{
try
{
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
}
catch (Exception)
{
//Do not rethrow. Exception from error logger that has already been garbage collected
}
}
}
/// <summary>
/// Get all of the power module names
/// </summary>
/// <returns>Array of the system/module names.</returns>
public List<string> GetPowerModuleList()
{
List<string> powerModules = new List<string>();
foreach (KeyValuePair<string, IPowerSupplySystem> item in _powerModuleNameToObjectMap)
{
powerModules.Add(item.Key);
}
return powerModules;
}
/// <summary>
/// Get the power module names for a given system
/// </summary>
/// <returns>Array of the system/module names.</returns>
public List<string> GetPowerSupplyList(string powerSystem)
{
if (_powerSystemNameToObjectMap.ContainsKey(powerSystem.ToUpper()) == false)
{
throw new Exception("Unknown power system: " + powerSystem);
}
return _powerSystemNameToObjectMap[powerSystem.ToUpper()].GetModuleNames();
}//GetPowerSupplyModuleInfoDict
/// <summary>
/// Get the dictionary that contains configuration information for each module
/// </summary>
/// <returns></returns>
public Dictionary<string, PowerSupplyModuleInfo> GetPowerSupplyModuleInfoDict(string powerSystem)
{
if (_powerSystemNameToObjectMap.ContainsKey(powerSystem.ToUpper()) == false)
{
throw new Exception("Unknown power system: " + powerSystem);
}
return _powerSystemNameToObjectMap[powerSystem.ToUpper()].GetPowerSupplyModuleInfoDict(powerSystem);
}
/// <summary>
/// Gets the Power System names.
/// </summary>
/// <returns>Array of power system names, as defined in the config file</returns>
public List<string> GetPowerSupplySystemList()
{
List<string> powerSystems = new List<string>();
foreach (KeyValuePair<string, IPowerSupplySystem> item in _powerSystemNameToObjectMap)
{
powerSystems.Add(item.Key);
}
return powerSystems;
}
/// <summary>
/// Query the supply and returns the programed OCP. Should match what was in the definition file.
/// </summary>
/// <param name="moduleName">The name of the power supply.</param>
/// <returns>The programmed overcurrent protection value</returns>
public double GetOverCurrentProtection(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
return _powerModuleNameToObjectMap[moduleName.ToUpper()].GetOverCurrentSetting(moduleName);
}
/// <summary>
/// Query the supply and returns the programed OVP. Should match what was in the definition file.
/// </summary>
/// <param name="moduleName">The name of the power supply.</param>
/// <returns>The programmed overvoltage protection value.</returns>
public double GetOverVoltageProtection(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
return _powerModuleNameToObjectMap[moduleName.ToUpper()].GetOverVoltageSetting(moduleName);
}
/// <summary>
/// Query the supply and returns the programed slew rate
/// </summary>
/// <param name="moduleName"></param>
/// <returns>The programmed slew rate</returns>
public double GetSlewRate(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
return _powerModuleNameToObjectMap[moduleName.ToUpper()].GetSlewRate(moduleName);
}
/// <summary>
/// Query the system that contains the passed in module and returns the system error code.
/// </summary>
/// <param name="moduleName">The module to query.</param>
/// <param name="errorCode">The error code.</param>
/// <returns>The string form of the error code. Will be empty string if there is no error.</returns>
public string GetSystemErrorCode(string moduleName, out int errorCode)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
return _powerModuleNameToObjectMap[moduleName.ToUpper()].GetErrorCode(out errorCode);
}
/// <summary>
/// Query the supply and returns the programmed voltage setpoint.
/// After construction, this should match what was in the definition file.
/// The host may override the value by calling SetVoltageSetpoint().
/// </summary>
/// <param name="moduleName">The name of the power supply.</param>
/// <returns>The programmed voltage setpoint.</returns>
public double GetVoltageSetpoint(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
return _powerModuleNameToObjectMap[moduleName.ToUpper()].GetVoltageSetting(moduleName);
}
/// <summary>
/// Query the supply and returns true if output is enabled.
/// </summary>
/// <param name="moduleName">The name of the power supply.</param>
/// <returns>True if output is enabled, false if it is not enabled.</returns>
public bool IsPowerSupplyOn(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
return _powerModuleNameToObjectMap[moduleName.ToUpper()].IsOutputOn(moduleName);
}
/// <summary>
/// Sends a SCPI command to the power system and reads the response
/// </summary>
/// <param name="powerSystem">The name of the power system.</param>
/// <param name="command">The SCPI command to send</param>
/// <returns></returns>
public string IOQuery(string powerSystem, string command)
{
if (_powerSystemNameToObjectMap.ContainsKey(powerSystem.ToUpper()) == false)
{
throw new Exception("Could not find power system: " + powerSystem);
}
return _powerSystemNameToObjectMap[powerSystem.ToUpper()].IOQuery(command);
}
/// <summary>
/// Sends a SCPI command to the power system
/// </summary>
/// <param name="powerSystem">The name of the power system.</param>
/// <param name="command">The SCPI command to send</param>
public void IOWrite(string powerSystem, string command)
{
if (_powerSystemNameToObjectMap.ContainsKey(powerSystem.ToUpper()) == false)
{
throw new Exception("Could not find power system: " + powerSystem);
}
_powerSystemNameToObjectMap[powerSystem.ToUpper()].IOWrite(command);
}
/// <summary>
/// Read the current of a module.
/// </summary>
/// <param name="moduleName">The module to read.</param>
/// <returns>The current (Amps).</returns>
public double MeasureCurrent(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
return _powerModuleNameToObjectMap[moduleName.ToUpper()].MeasureCurrent(moduleName);
}
/// <summary>
/// Query the supply for its voltage.
/// </summary>
/// <param name="moduleName">The module to read.</param>
/// <returns>The voltage (Volts).</returns>
public double MeasureVoltage(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
return _powerModuleNameToObjectMap[moduleName.ToUpper()].MeasureVoltage(moduleName);
}
/// <summary>
/// Disable the output of the power supply.
/// </summary>
/// <param name="moduleName">The name of the power supply module.</param>
public void OutputDisable(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
_powerModuleNameToObjectMap[moduleName.ToUpper()].Off(moduleName);
}
/// <summary>
/// Enable the output of the power supply.
/// </summary>
/// <param name="moduleName">The name of the module to enable.</param>
public void OutputEnable(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
_powerModuleNameToObjectMap[moduleName.ToUpper()].On(moduleName);
}
/// <summary>
/// start logging of power supply data.
/// Queries the list of all power modules.
/// Logs data to the define path.
/// Returns data to defined callback function.
/// </summary>
/// <param name="fileName">Path to create the log file.</param>
/// <param name="threadRestTimeMs">The time to wait between queries.</param>
/// <param name="callback">Function to call. Null can be passed in in which case no hot callback will be issued</param>
public void PowerLogStart(string fileName, int threadRestTimeMs, PowerMonitorDelegate callback)
{
// if we have been running before, stop just in case the host did not
if (_dataLogWorker != null)
{
PowerLogStop();
_dataLogWorker.Dispose();
}
_dataLogWorker = new PowerSupplyDataLogWorker(this, fileName, threadRestTimeMs, callback);
_dataLogThread = new Thread(_dataLogWorker.DoWork);
// start the thread back up
_dataLogThread.Start();
_prevPowerLogFileName = fileName;
_prevPowerLogRestTime = threadRestTimeMs;
_prevPowerLogCallback = callback;
}
/// <summary>
/// stops logging data and closes the file.
/// </summary>
public void PowerLogStop()
{
// Wait up to 5 seconds for the thread to quit
const int THREAD_QUIT_TIMEOUT_MS = 5000;
string functionName = $"{this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}()";
if (_dataLogWorker != null)
{
_dataLogWorker.QuitWork();
if ((_dataLogThread != null) && _dataLogThread.IsAlive)
{
bool didThreadQuit = _dataLogThread.Join(THREAD_QUIT_TIMEOUT_MS);
if (didThreadQuit == false)
{
_logger.Error($"{functionName} - Logging Thread did not quit as expected, aborting it");
_dataLogThread.Abort();
}
else
{
_logger.Debug("{functionName} - Logging Thread quit successfully after join");
}
}
else
{
_logger.Debug("{functionName} - Logging Thread quit successfully");
}
}
_prevPowerLogFileName = null;
_prevPowerLogRestTime = 0;
_prevPowerLogCallback = null;
}
/// <summary>
/// Control the power supply internal mechanical relay state
/// </summary>
/// <param name="shallWeConnect">True to connect, false to disconnect</param>
public void MechanicalRelayOutputControl(string moduleName, bool shallWeConnect)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
_powerModuleNameToObjectMap[moduleName.ToUpper()].MechanicalRelayOutputControl(moduleName, shallWeConnect);
}
/// <summary>
/// Query all power supply data in a single call.
/// </summary>
/// <param name="moduleName">The name of the module to query.</param>
/// <param name="voltage">The voltage that was read.</param>
/// <param name="voltageSetpoint">The voltage setpoint that was read.</param>
/// <param name="current">The current that was read.</param>
/// <param name="outputStatus">The output status. True if output is enabled, false if output is disabled.</param>
/// <param name="faultStatus">The value of the fault status register. See power supply docs for meaning (0 means no fault).</param>
/*public void ReadPowerData(string moduleName, out double voltage, out double voltageSetpoint, out double current, out bool outputStatus, out int faultStatus)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("PowerSupplyManager::ReadPowerData() - could not find module: " + moduleName);
}
_powerModuleNameToObjectMap[moduleName.ToUpper()].ReadPowerData(moduleName, out voltage, out voltageSetpoint, out current, out outputStatus, out faultStatus);
}*/
/// <summary>
/// Query all power supply data in a single call.
/// </summary>
/// <param name="moduleName">The name of the module to query.</param>
public PowerData ReadPowerData(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
return _powerModuleNameToObjectMap[moduleName.ToUpper()].ReadPowerData(moduleName);
}
/// <summary>
///
/// </summary>
/// <param name="moduleName"></param>
/// <returns></returns>
public int ReadProtectionStatus(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
return _powerModuleNameToObjectMap[moduleName.ToUpper()].ReadProtectionStatus(moduleName);
}
/// <summary>
/// Resets the setpoint voltage to the value contained in the ini file
/// </summary>
/// <param name="moduleName">The module to reset</param>
public void SetInitialVoltage(string moduleName)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
_powerModuleNameToObjectMap[moduleName.ToUpper()].SetInitialVoltage(moduleName);
}
/// <summary>
/// Every power supply gets its voltage set to what was in the ini file
/// </summary>
public void SetInitialVoltageAll()
{
List<string> powerModules = GetPowerModuleList();
foreach (string powerModule in powerModules)
{
SetInitialVoltage(powerModule);
}
}
/// <summary>
/// Sets the slew rate in volts per second
/// </summary>
/// <param name="moduleName">The name of the power module</param>
/// <param name="slewRate">slew in volts per second</param>
/*public void SetSlewRate(string moduleName, double slewRate)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("PowerSupplyManager::SetSlewRate() - could not find module: " + moduleName);
}
_powerModuleNameToObjectMap[moduleName.ToUpper()].SetSlewRate(moduleName, slewRate);
}*/
/// <summary>
///
/// </summary>
/// <param name="moduleName"></param>
/// <param name="ocpValue"></param>
public void SetOverCurrentProtection(string moduleName, double ocpValue)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
_powerModuleNameToObjectMap[moduleName.ToUpper()].SetOverCurrentProtection(moduleName, ocpValue);
}
/// <summary>
///
/// </summary>
/// <param name="moduleName"></param>
/// <param name="ovpValue"></param>
public void SetOverVoltageProtection(string moduleName, double ovpValue)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
_powerModuleNameToObjectMap[moduleName.ToUpper()].SetOverVoltageProtection(moduleName, ovpValue);
}
/// <summary>
/// Set the setpoint voltage of a module.
/// </summary>
/// <param name="moduleName">The module to set.</param>
/// <param name="setpointVoltage">The setpoint voltage.</param>
public void SetVoltageSetpoint(string moduleName, double setpointVoltage)
{
if (_powerModuleNameToObjectMap.ContainsKey(moduleName.ToUpper()) == false)
{
throw new Exception("Could not find module: " + moduleName);
}
_powerModuleNameToObjectMap[moduleName.ToUpper()].SetVoltageSetpoint(moduleName, setpointVoltage);
}
/// <summary>
/// Disable the power system watchdog.
/// </summary>
/// <param name="powerSystem">The power system to act on.</param>
public void WatchdogDisable(string powerSystem)
{
if (_powerSystemNameToObjectMap.ContainsKey(powerSystem.ToUpper()) == false)
{
throw new Exception("Could not find power system: " + powerSystem);
}
_powerSystemNameToObjectMap[powerSystem.ToUpper()].WatchdogDisable();
}
/// <summary>
/// Enable the power system watchdog.
/// </summary>
/// <param name="powerSystem">The system to act on.</param>
/// <param name="timeInSeconds">The number of seconds for the watchdog.</param>
public void WatchdogEnable(string powerSystem, uint timeInSeconds)
{
if (_powerSystemNameToObjectMap.ContainsKey(powerSystem.ToUpper()) == false)
{
throw new Exception("Could not find power system: " + powerSystem);
}
_powerSystemNameToObjectMap[powerSystem.ToUpper()].WatchdogEnable(timeInSeconds);
}
#endregion
#region PrivateClassFunctions
/// <summary>
/// The Finalizer
/// </summary>
~PowerSupplyMeasurementManager()
{
Dispose(false);
}
/// <summary>
/// Dispose of this object.
/// </summary>
/// <param name="disposing">True = currently disposing, False = not disposing.</param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_logger.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");
// stop the logging if it is still running
try
{
PowerLogStop();
}
catch (Exception ex)
{
_logger.Error(ex.Message + "\r\n" + ex.StackTrace);
}
// dispose the thread
try
{
if (_dataLogWorker != null)
{
_dataLogWorker.Dispose();
}
}
catch (Exception ex)
{
_logger.Error(ex.Message + "\r\n" + ex.StackTrace);
}
// dispose of the other resources
foreach (KeyValuePair<string, IPowerSupplySystem> entry in _powerSystemNameToObjectMap)
{
try
{
entry.Value.Shutdown();
}
catch (Exception ex)
{
_logger.Error(ex.Message + "\r\n" + ex.StackTrace);
}
}
}
}
#endregion
}
}