action
container
contrib
controller
coordinates
datalinklayer
datapool
datapoolglob
datapoollocal
devicehandlers
events
fdir
globalfunctions
health
housekeeping
internalError
ipc
memory
modes
monitoring
AbsLimitMonitor.h
HasMonitorsIF.h
LimitMonitor.h
LimitViolationReporter.cpp
LimitViolationReporter.h
MonitorBase.h
MonitorReporter.h
MonitoringIF.h
MonitoringMessage.cpp
MonitoringMessage.h
MonitoringMessageContent.h
ReceivesMonitoringReportsIF.h
TriplexMonitor.h
TwoValueLimitMonitor.h
objectmanager
osal
parameters
power
returnvalues
rmap
serialize
serviceinterface
storagemanager
subsystem
tasks
tcdistribution
thermal
timemanager
tmstorage
tmtcpacket
tmtcservices
.gitignore
LICENSE
NOTICE
framework.mk
156 lines
4.8 KiB
C++
156 lines
4.8 KiB
C++
#ifndef FRAMEWORK_MONITORING_TRIPLEXMONITOR_H_
|
|
#define FRAMEWORK_MONITORING_TRIPLEXMONITOR_H_
|
|
|
|
#include <framework/datapool/DataSet.h>
|
|
#include <framework/datapool/PIDReaderList.h>
|
|
#include <framework/health/HealthTableIF.h>
|
|
#include <framework/parameters/HasParametersIF.h>
|
|
#include <framework/objectmanager/ObjectManagerIF.h>
|
|
|
|
|
|
//SHOULDDO: This is by far not perfect. Could be merged with new Monitor classes. But still, it's over-engineering.
|
|
template<typename T>
|
|
class TriplexMonitor : public HasParametersIF {
|
|
public:
|
|
static const uint8_t INTERFACE_ID = CLASS_ID::TRIPLE_REDUNDACY_CHECK;
|
|
static const ReturnValue_t NOT_ENOUGH_SENSORS = MAKE_RETURN_CODE(1);
|
|
static const ReturnValue_t LOWEST_VALUE_OOL = MAKE_RETURN_CODE(2);
|
|
static const ReturnValue_t HIGHEST_VALUE_OOL = MAKE_RETURN_CODE(3);
|
|
static const ReturnValue_t BOTH_VALUES_OOL = MAKE_RETURN_CODE(4);
|
|
static const ReturnValue_t DUPLEX_OOL = MAKE_RETURN_CODE(5);
|
|
|
|
static const uint8_t THREE = 3;
|
|
|
|
TriplexMonitor(const uint32_t parameterIds[3], uint8_t domainId, const T initialLimit,
|
|
Event eventTripleCheck, Event eventDualCheck) :
|
|
values(parameterIds, &dataSet), limit(initialLimit), eventTripleCheck(
|
|
eventTripleCheck), eventDualCheck(eventDualCheck), healthTable(
|
|
NULL), domainId(domainId) {
|
|
|
|
}
|
|
virtual ~TriplexMonitor() {
|
|
}
|
|
ReturnValue_t check() {
|
|
dataSet.read();
|
|
//check health and validity
|
|
uint8_t availableIndex[2] = { 0, 0 };
|
|
bool first = true;
|
|
uint8_t nAvailable = 0;
|
|
for (uint8_t count = 0; count < THREE; count++) {
|
|
if (values[count].isValid() && checkObjectHealthState(count)) {
|
|
if (first) {
|
|
availableIndex[0] = count;
|
|
first = false;
|
|
} else {
|
|
//Might be filled twice, but then it's not needed anyway.
|
|
availableIndex[1] = count;
|
|
}
|
|
nAvailable++;
|
|
}
|
|
}
|
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
|
switch (nAvailable) {
|
|
case 3:
|
|
result = doTriplexMonitoring();
|
|
break;
|
|
case 2:
|
|
result = doDuplexMonitoring(availableIndex);
|
|
break;
|
|
default:
|
|
result = NOT_ENOUGH_SENSORS;
|
|
break;
|
|
}
|
|
dataSet.commit();
|
|
return result;
|
|
}
|
|
ReturnValue_t initialize() {
|
|
healthTable = objectManager->get<HealthTableIF>(objects::HEALTH_TABLE);
|
|
if (healthTable == NULL) {
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
|
}
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
|
ParameterWrapper *parameterWrapper,
|
|
const ParameterWrapper *newValues, uint16_t startAtIndex) {
|
|
if (domainId != this->domainId) {
|
|
return INVALID_DOMAIN_ID;
|
|
}
|
|
switch (parameterId) {
|
|
case 0:
|
|
parameterWrapper->set(limit);
|
|
break;
|
|
default:
|
|
return INVALID_MATRIX_ID;
|
|
}
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
protected:
|
|
DataSet dataSet;
|
|
PIDReaderList<T, THREE> values;
|
|
T limit;
|
|
Event eventTripleCheck;
|
|
Event eventDualCheck;
|
|
HealthTableIF* healthTable;
|
|
uint8_t domainId;
|
|
ReturnValue_t doTriplexMonitoring() {
|
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
|
//Find middle value, by ordering indices
|
|
uint8_t index[3] = { 0, 1, 2 };
|
|
if (values[index[0]].value > values[index[1]].value) {
|
|
std::swap(index[0], index[1]);
|
|
}
|
|
if (values[index[0]].value > values[index[2]].value) {
|
|
std::swap(index[0], index[2]);
|
|
}
|
|
if (values[index[1]].value > values[index[2]].value) {
|
|
std::swap(index[1], index[2]);
|
|
}
|
|
//Test if smallest value is out-of-limit.
|
|
if (values[index[0]] < (values[index[1]] - limit)) {
|
|
EventManagerIF::triggerEvent(getRefereneceObject(index[0]),
|
|
eventTripleCheck, LOWEST_VALUE_OOL, 0);
|
|
result = LOWEST_VALUE_OOL;
|
|
}
|
|
//Test if largest value is out-of-limit.
|
|
if (values[index[2]] > (values[index[1]] + limit)) {
|
|
EventManagerIF::triggerEvent(getRefereneceObject(index[2]),
|
|
eventTripleCheck, HIGHEST_VALUE_OOL, 0);
|
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
result = HIGHEST_VALUE_OOL;
|
|
} else {
|
|
result = BOTH_VALUES_OOL;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
ReturnValue_t doDuplexMonitoring(uint8_t index[2]) {
|
|
T mean = (values[index[0]] + values[index[1]]) / 2;
|
|
if (values[index[0]] > values[index[1]]) {
|
|
if (values[index[0]] > (mean + limit)) {
|
|
EventManagerIF::triggerEvent(getRefereneceObject(index[0]),
|
|
eventDualCheck, 0, 0);
|
|
EventManagerIF::triggerEvent(getRefereneceObject(index[1]),
|
|
eventDualCheck, 0, 0);
|
|
return DUPLEX_OOL;
|
|
}
|
|
} else {
|
|
if (values[index[1]] > (mean + limit)) {
|
|
EventManagerIF::triggerEvent(getRefereneceObject(index[0]),
|
|
eventDualCheck, 0, 0);
|
|
EventManagerIF::triggerEvent(getRefereneceObject(index[1]),
|
|
eventDualCheck, 0, 0);
|
|
return DUPLEX_OOL;
|
|
}
|
|
}
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
virtual bool checkObjectHealthState(uint8_t valueIndex) = 0;
|
|
virtual object_id_t getRefereneceObject(uint8_t valueIndex) = 0;
|
|
};
|
|
|
|
#endif /* FRAMEWORK_MONITORING_TRIPLEXMONITOR_H_ */
|