Monitor power supply data for fault conditions

This commit is contained in:
Duc
2025-01-04 18:41:54 -07:00
parent 7e2a821337
commit b38765789d
14 changed files with 242 additions and 70 deletions

View File

@@ -55,8 +55,8 @@ namespace ProgramLib
private ILogger _logger;
private object _fatalErrorMsgFromThreadSyncObj = new object();
private string _fatalErrorMsgFromThread;
private object _fatalErrorMsgFromSupportThreadSyncObj = new object();
private string _fatalErrorMsgFromSupportThread;
#endregion
@@ -249,7 +249,7 @@ namespace ProgramLib
if (!_terminateTestInitiated)
{
// tells teststand there's a exception occurred and give it the error message
_testStandSeqContext.SequenceErrorMessage = _fatalErrorMsgFromThread + " ";
_testStandSeqContext.SequenceErrorMessage = _fatalErrorMsgFromSupportThread + " ";
_testStandSeqContext.SequenceErrorOccurred = true;
// tells TestStand to go to clean up
@@ -267,13 +267,13 @@ namespace ProgramLib
/// </summary>
/// <param name=""></param>
/// <returns></returns>
internal void SetFatalErrorMsgFromThread(string errorMsg)
internal void SetFatalErrorMsgFromSupportThread(string errorMsg)
{
lock(_fatalErrorMsgFromThreadSyncObj)
lock(_fatalErrorMsgFromSupportThreadSyncObj)
{
if (String.IsNullOrEmpty(_fatalErrorMsgFromThread))
if (String.IsNullOrEmpty(_fatalErrorMsgFromSupportThread))
{
_fatalErrorMsgFromThread = errorMsg;
_fatalErrorMsgFromSupportThread = errorMsg;
}
}
}

View File

@@ -81,6 +81,8 @@ namespace ProgramLib
if (id == Events.FATAL_FAILURE)
{
Program.Instance()._eventManager[EventManager.Events.GLOBAL_QUIT].Set();
UutPowerAction uutPowerAction = new UutPowerAction();
uutPowerAction.UutPowerOff();

View File

@@ -29,6 +29,9 @@ using System.Threading.Tasks;
namespace ProgramLib
{
/// <summary>
/// Class to spawn thread to update passthrough data on GUI
/// </summary>
internal class PassthroughDataGuiUpdateThread : BasicThread
{
private enum Events
@@ -46,6 +49,9 @@ namespace ProgramLib
private MainWindow _mainWindow;
private PassthroughData _passthroughData = null;
/// <summary>
/// Constructor
/// </summary>
public PassthroughDataGuiUpdateThread()
{
_logger = LogManager.GetCurrentClassLogger();
@@ -65,6 +71,11 @@ namespace ProgramLib
_logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() ...");
}
/// <summary>
/// Method that executes on the thread.
/// </summary>
/// <param name=""></param>
/// <returns></returns>
protected override void DoWork()
{
_logger?.Debug($"{this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() is running...");
@@ -99,6 +110,11 @@ namespace ProgramLib
}
/// <summary>
/// Update GUI with data
/// </summary>
/// <param name=""></param>
/// <returns></returns>
private void UpdatePassthroughDataGui()
{
int pollRateMs = 1000;

View File

@@ -29,6 +29,9 @@ using System.Threading.Tasks;
namespace ProgramLib
{
/// <summary>
/// Class to spawn thread to update power supply data on GUI
/// </summary>
internal class PowerSupplyGuiUpdateThread : BasicThread
{
private enum Events
@@ -47,6 +50,9 @@ namespace ProgramLib
private Dictionary<string, PowerModuleDataModel> _powerModuleToPowerDataModelDict = new Dictionary<string, PowerModuleDataModel>();
/// <summary>
/// Constructor
/// </summary>
public PowerSupplyGuiUpdateThread()
{
_logger = LogManager.GetCurrentClassLogger();
@@ -67,6 +73,11 @@ namespace ProgramLib
_logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() ...");
}
/// <summary>
/// Method that executes on the thread.
/// </summary>
/// <param name=""></param>
/// <returns></returns>
protected override void DoWork()
{
_logger?.Debug($"{this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() is running...");
@@ -101,6 +112,11 @@ namespace ProgramLib
}
/// <summary>
/// Update GUI with data
/// </summary>
/// <param name=""></param>
/// <returns></returns>
private void UpdatePowerSupplyGui()
{
int pollRateMs = 1000;

View File

@@ -15,20 +15,17 @@ GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using NLog;
using ProgramGui;
using ProgramGui.Model;
using ProgramGui.ViewModel;
using ProgramLib;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using NLog;
namespace ProgramLib
{
/// <summary>
/// Class to spawn thread to read power supply data
/// </summary>
internal class PowerSupplyReadThread : BasicThread
{
private enum Events
@@ -46,7 +43,12 @@ namespace ProgramLib
private string _powerSupplySystemName;
private List<string> _powerModuleNameList;
Dictionary<string, Raytheon.Instruments.PowerSupplies.PowerSupplyModuleInfo> _powerSupplyModuleInfoDict;
/// <summary>
/// Constructor
/// </summary>
public PowerSupplyReadThread(string powerSupplySystemName)
{
_logger = LogManager.GetCurrentClassLogger();
@@ -60,6 +62,11 @@ namespace ProgramLib
_logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() ...");
}
/// <summary>
/// Method that executes on the thread.
/// </summary>
/// <param name=""></param>
/// <returns></returns>
protected override void DoWork()
{
_logger?.Debug($"{this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() for {_powerSupplySystemName} is running...");
@@ -73,6 +80,9 @@ namespace ProgramLib
EventGroup<Events, EventWaitHandle> eventGroup = new EventGroup<Events, EventWaitHandle>(eventDict);
_powerModuleNameList = Program.Instance().GetPowerSupplyMeasurementManager()[_powerSupplySystemName].GetModuleNames();
_powerSupplyModuleInfoDict = Program.Instance().GetPowerSupplyMeasurementManager()[_powerSupplySystemName].GetPowerSupplyModuleInfoDict();
while (true)
{
Events id = eventGroup.WaitAny();
@@ -94,6 +104,11 @@ namespace ProgramLib
}
/// <summary>
/// Read power supply data and check for faults
/// </summary>
/// <param name=""></param>
/// <returns></returns>
private void ReadPowerSupplyData()
{
int pollRateMs = 1000;
@@ -108,15 +123,53 @@ namespace ProgramLib
EventGroup<Events, EventWaitHandle> eventGroup = new EventGroup<Events, EventWaitHandle>(eventDict);
Random rnd = new Random();
double voltage;
double current;
double voltageSetPoint;
bool isOn;
int faultStatus;
while (true)
{
Events id = eventGroup.WaitAny(pollRateMs);
if (id == Events.EVENT_TIMED_OUT)
{
Thread.Sleep(100);
foreach (string moduleName in _powerModuleNameList)
{
Program.Instance().GetPowerSupplyMeasurementManager()[_powerSupplySystemName].ReadPowerSupplyData(moduleName, out voltage, out current, out voltageSetPoint, out isOn, out faultStatus);
BitArray statusReg = new BitArray(new int[] { faultStatus });
bool ovpTriggeredInPowerSupply = statusReg[0];
bool ocpTriggeredInPowerSupply = statusReg[1];
if (!ovpTriggeredInPowerSupply && !ocpTriggeredInPowerSupply)
{
if (IsCurrentWithinLimits(moduleName, current))
break;
if (IsVoltageWithinLimits(moduleName, voltage))
break;
}
else
{
string errorMsg = String.Empty;
if (ovpTriggeredInPowerSupply)
{
errorMsg = moduleName + "'s OVP circuitry has tripped";
}
else if (ocpTriggeredInPowerSupply)
{
errorMsg = moduleName + "'s OCP circuitry has tripped";
}
HandleOutOfToleranceCondition(errorMsg);
break;
}
}
}
else
break;
@@ -130,5 +183,59 @@ namespace ProgramLib
_logger?.Debug($"{this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() for {_powerSupplySystemName} is exiting...");
}
/// <summary>
/// Check for current's upper limit
/// </summary>
/// <param name=""></param>
/// <returns></returns>
private bool IsCurrentWithinLimits(string moduleName, double current)
{
bool outOfLimits = false;
Raytheon.Instruments.PowerSupplies.PowerSupplyModuleInfo powerSupplyModuleInfo = _powerSupplyModuleInfoDict[moduleName];
if ((current < powerSupplyModuleInfo.currentLowerLimit_ || current > powerSupplyModuleInfo.currentUpperLimit_) && powerSupplyModuleInfo.isOn_)
{
outOfLimits = true;
string errorMsg = moduleName + "'s current is out of limits (" + powerSupplyModuleInfo.currentLowerLimit_.ToString("0.00") + "," + powerSupplyModuleInfo.currentUpperLimit_.ToString("0.00") + "). Current reading: " + current.ToString("0.00");
HandleOutOfToleranceCondition(errorMsg);
}
return outOfLimits;
}
/// <summary>
/// Check for voltage's limit exceedence
/// </summary>
/// <param name=""></param>
/// <returns></returns>
private bool IsVoltageWithinLimits(string moduleName, double voltage)
{
bool outOfLimits = false;
Raytheon.Instruments.PowerSupplies.PowerSupplyModuleInfo powerSupplyModuleInfo = _powerSupplyModuleInfoDict[moduleName];
if ((voltage < powerSupplyModuleInfo.voltageLowerLimit_ || voltage > powerSupplyModuleInfo.voltageUpperLimit_) && powerSupplyModuleInfo.isOn_)
{
outOfLimits = true;
string errorMsg = moduleName + "'s voltage is out of limits (" + powerSupplyModuleInfo.voltageLowerLimit_.ToString("0.00") + "," + powerSupplyModuleInfo.voltageUpperLimit_.ToString("0.00") + "). Voltage reading: " + voltage.ToString("0.00");
HandleOutOfToleranceCondition(errorMsg);
}
return outOfLimits;
}
/// <summary>
/// Handle power fault conditions
/// </summary>
/// <param name=""></param>
/// <returns></returns>
private void HandleOutOfToleranceCondition(string errorMsg)
{
if (!Program.Instance()._eventManager[EventManager.Events.FATAL_FAILURE].WaitOne(0))
{
Program.Instance().SetFatalErrorMsgFromSupportThread(errorMsg);
Program.Instance()._eventManager[EventManager.Events.FATAL_FAILURE].Set();
}
}
}
}