add scalarAlarmSupport

This commit is contained in:
mrkraimer
2019-06-04 14:21:38 -04:00
parent b052e28788
commit 6c91249340
9 changed files with 371 additions and 30 deletions
+1
View File
@@ -3,3 +3,4 @@
SRC_DIRS += $(PVDATABASE_SRC)/support
LIBSRCS += controlSupport.cpp
LIBSRCS += scalarAlarmSupport.cpp
+12 -12
View File
@@ -39,10 +39,8 @@ ControlSupport::ControlSupport(PVRecordPtr const & pvRecord)
: pvRecord(pvRecord)
{}
bool ControlSupport::init()
bool ControlSupport::init(PVFieldPtr const & pv,PVFieldPtr const & pvsup)
{
PVStructurePtr pvStructure = pvRecord->getPVStructure();
PVFieldPtr pv(pvStructure->getSubField("value"));
if(pv) {
if(pv->getField()->getType()==epics::pvData::scalar) {
ScalarConstPtr s = static_pointer_cast<const Scalar>(pv->getField());
@@ -56,14 +54,21 @@ bool ControlSupport::init()
<< " failed because not numeric scalar\n";
return false;
}
pvControl = static_pointer_cast<PVStructure>(pvsup);
if(pvControl) {
pvLimitLow = pvControl->getSubField<PVDouble>("limitLow");
pvLimitHigh = pvControl->getSubField<PVDouble>("limitHigh");
pvMinStep = pvControl->getSubField<PVDouble>("minStep");
}
if(!pvControl || !pvLimitLow || !pvLimitHigh || !pvMinStep) {
cout << "ControlSupport for record " << pvRecord->getRecordName()
<< " failed because pvSupport not a valid control structure\n";
return false;
}
ConvertPtr convert = getConvert();
requestedValue = convert->toDouble(pvValue);
currentValue = requestedValue;
isMinStep = false;
pvControl = pvStructure->getSubField<PVStructure>("control");
pvLimitLow = pvControl->getSubField<PVDouble>("limitLow");
pvLimitHigh = pvControl->getSubField<PVDouble>("limitHigh");
pvMinStep = pvControl->getSubField<PVDouble>("minStep");
return true;
}
@@ -71,11 +76,6 @@ void ControlSupport::process()
{
ConvertPtr convert = getConvert();
double value = convert->toDouble(pvValue);
cout << "value " << value
<< " requestedValue " << requestedValue
<< " currentValue " << currentValue
<< " isMinStep " << (isMinStep ? "true" : "false")
<< "\n";
if(value==requestedValue&&value==currentValue) return;
if(!isMinStep) requestedValue = value;
double limitLow = pvLimitLow->get();
+215
View File
@@ -0,0 +1,215 @@
/* scalarAlarmSupport.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2019.06.01
*/
#include <pv/pvDatabase.h>
#include <pv/pvSupport.h>
#include <pv/convert.h>
#include <pv/standardField.h>
#include <pv/alarm.h>
#include <pv/pvAlarm.h>
#define epicsExportSharedSymbols
#include <pv/scalarAlarmSupport.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pvDatabase {
ScalarAlarmSupport::~ScalarAlarmSupport()
{
cout << "ScalarAlarmSupport::~ScalarAlarmSupport()\n";
}
epics::pvData::StructureConstPtr ScalarAlarmSupport::scalarAlarmField =
FieldBuilder::begin()
->setId("scalarAlarm_t")
->add("active", pvBoolean)
->add("lowAlarmLimit", pvDouble)
->add("lowWarningLimit", pvDouble)
->add("highWarningLimit", pvDouble)
->add("highAlarmLimit", pvDouble)
->add("hysteresis", pvDouble)
->createStructure();
epics::pvData::StructureConstPtr ScalarAlarmSupport::scalarAlarm()
{
return scalarAlarmField;
}
ScalarAlarmSupportPtr ScalarAlarmSupport::create(PVRecordPtr const & pvRecord)
{
ScalarAlarmSupportPtr support(new ScalarAlarmSupport(pvRecord));
return support;
}
ScalarAlarmSupport::ScalarAlarmSupport(PVRecordPtr const & pvRecord)
: pvRecord(pvRecord),
prevAlarmRange(range_Undefined)
{}
bool ScalarAlarmSupport::init(
PVFieldPtr const & pvval,
PVStructurePtr const & pvalarm,
PVFieldPtr const & pvsup)
{
if(pvval->getField()->getType()==epics::pvData::scalar) {
ScalarConstPtr s = static_pointer_cast<const Scalar>(pvval->getField());
if(ScalarTypeFunc::isNumeric(s->getScalarType())) {
pvValue = static_pointer_cast<PVScalar>(pvval);
}
}
if(!pvValue) {
cout << "ScalarAlarmSupport for record " << pvRecord->getRecordName()
<< " failed because not numeric scalar\n";
return false;
}
pvScalarAlarm = static_pointer_cast<PVStructure>(pvsup);
if(pvScalarAlarm) {
pvActive = pvScalarAlarm->getSubField<PVBoolean>("active");
pvLowAlarmLimit = pvScalarAlarm->getSubField<PVDouble>("lowAlarmLimit");
pvLowWarningLimit = pvScalarAlarm->getSubField<PVDouble>("lowWarningLimit");
pvHighWarningLimit = pvScalarAlarm->getSubField<PVDouble>("highWarningLimit");
pvHighAlarmLimit = pvScalarAlarm->getSubField<PVDouble>("highAlarmLimit");
pvHysteresis = pvScalarAlarm->getSubField<PVDouble>("hysteresis");
}
if(!pvScalarAlarm
|| !pvActive
|| !pvLowAlarmLimit || !pvLowWarningLimit
|| !pvLowWarningLimit || !pvHighAlarmLimit
|| !pvHysteresis)
{
cout << "ScalarAlarmSupport for record " << pvRecord->getRecordName()
<< " failed because pvSupport not a valid scalarAlarm structure\n";
return false;
}
pvAlarm = pvalarm;
ConvertPtr convert = getConvert();
requestedValue = convert->toDouble(pvValue);
currentValue = requestedValue;
isHystersis = false;
setAlarm(pvAlarm,range_Undefined);
return true;
}
void ScalarAlarmSupport::process()
{
ConvertPtr convert = getConvert();
double value = convert->toDouble(pvValue);
double lowAlarmLimit = pvLowAlarmLimit->get();
double lowWarningLimit = pvLowWarningLimit->get();
double highWarningLimit = pvHighWarningLimit->get();
double highAlarmLimit = pvHighAlarmLimit->get();
double hysteresis = pvHysteresis->get();
int alarmRange = range_Normal;
if(highAlarmLimit>lowAlarmLimit) {
if(value>=highAlarmLimit) {
alarmRange = range_Hihi;
} else if(value<=lowAlarmLimit) {
alarmRange = range_Lolo;
}
}
if(alarmRange==range_Normal && (pvHighWarningLimit>pvLowWarningLimit)) {
if(value>=highWarningLimit) {
alarmRange = range_High;
} else if(value<=lowWarningLimit) {
alarmRange = range_Low;
}
}
cout << "ScalarAlarmSupport::process() alarmRange " << alarmRange
<< " prevAlarmRange " << prevAlarmRange << "\n";
if(alarmRange!=prevAlarmRange) setAlarm(pvAlarm,alarmRange);
prevAlarmRange = alarmRange;
}
void ScalarAlarmSupport::reset()
{
isHystersis = false;
}
void ScalarAlarmSupport::setAlarm(
epics::pvData::PVStructurePtr const & pva,
int alarmRange)
{
Alarm alarm;
PVAlarm pvAlarm;
if(!pvAlarm.attach(pva)) throw std::logic_error("bad alarm field");
epics::pvData::AlarmStatus status(epics::pvData::noStatus);
epics::pvData::AlarmSeverity severity(epics::pvData::noAlarm);
string message;
switch (alarmRange) {
case range_Lolo :
{
severity = epics::pvData::majorAlarm;
status = epics::pvData::recordStatus;
message = "major low alarm";
break;
}
case range_Low :
{
severity = epics::pvData::minorAlarm;
status = epics::pvData::recordStatus;
message = "minor low alarm";
break;
}
case range_Normal :
{
break;
}
case range_High :
{
severity = epics::pvData::minorAlarm;
status = epics::pvData::recordStatus;
message = "minor high alarm";
break;
}
case range_Hihi :
{
severity = epics::pvData::majorAlarm;
status = epics::pvData::recordStatus;
message = "major high alarm";
break;
}
case range_Invalid :
{
severity = epics::pvData::invalidAlarm;
status = epics::pvData::recordStatus;
message = "invalid alarm";
break;
}
case range_Undefined :
{
severity = epics::pvData::undefinedAlarm;
status = epics::pvData::recordStatus;
message = "undefined alarm";
break;
}
default:
{
severity = epics::pvData::undefinedAlarm;
status = epics::pvData::recordStatus;
message = "bad alarm definition";
break;
}
}
alarm.setStatus(status);
alarm.setSeverity(severity);
alarm.setMessage(message);
pvAlarm.set(alarm);
}
}}