11 #include <pv/pvTimeStamp.h> 12 #include <pv/rpcService.h> 13 #include <pv/convert.h> 14 #include <pv/standardField.h> 16 #include <pv/pvAlarm.h> 18 #define epicsExportSharedSymbols 24 using std::tr1::static_pointer_cast;
29 namespace epics {
namespace pvDatabase {
31 ScalarAlarmSupport::~ScalarAlarmSupport()
37 epics::pvData::StructureConstPtr ScalarAlarmSupport::scalarAlarmField()
39 return FieldBuilder::begin()
40 ->setId(
"scalarAlarm_t")
41 ->add(
"lowAlarmLimit", pvDouble)
42 ->add(
"lowWarningLimit", pvDouble)
43 ->add(
"highWarningLimit", pvDouble)
44 ->add(
"highAlarmLimit", pvDouble)
45 ->add(
"hysteresis", pvDouble)
55 ScalarAlarmSupport::ScalarAlarmSupport(
PVRecordPtr const & pvRecord)
57 prevAlarmRange(range_Undefined)
61 bool ScalarAlarmSupport::init(
62 PVFieldPtr
const & pvval,
63 PVStructurePtr
const & pvalarm,
64 PVFieldPtr
const & pvsup)
66 if(pvval->getField()->getType()==epics::pvData::scalar) {
67 ScalarConstPtr s = static_pointer_cast<
const Scalar>(pvval->getField());
68 if(ScalarTypeFunc::isNumeric(s->getScalarType())) {
69 pvValue = static_pointer_cast<PVScalar>(pvval);
73 cout <<
"ScalarAlarmSupport for record " << pvRecord->getRecordName()
74 <<
" failed because not numeric scalar\n";
77 pvScalarAlarm = static_pointer_cast<PVStructure>(pvsup);
79 pvLowAlarmLimit = pvScalarAlarm->getSubField<PVDouble>(
"lowAlarmLimit");
80 pvLowWarningLimit = pvScalarAlarm->getSubField<PVDouble>(
"lowWarningLimit");
81 pvHighWarningLimit = pvScalarAlarm->getSubField<PVDouble>(
"highWarningLimit");
82 pvHighAlarmLimit = pvScalarAlarm->getSubField<PVDouble>(
"highAlarmLimit");
83 pvHysteresis = pvScalarAlarm->getSubField<PVDouble>(
"hysteresis");
86 || !pvLowAlarmLimit || !pvLowWarningLimit
87 || !pvLowWarningLimit || !pvHighAlarmLimit
90 cout <<
"ScalarAlarmSupport for record " << pvRecord->getRecordName()
91 <<
" failed because pvSupport not a valid scalarAlarm structure\n";
95 ConvertPtr convert = getConvert();
96 requestedValue = convert->toDouble(pvValue);
97 currentValue = requestedValue;
99 setAlarm(pvAlarm,range_Undefined);
103 bool ScalarAlarmSupport::process()
105 ConvertPtr convert = getConvert();
106 double value = convert->toDouble(pvValue);
107 double lowAlarmLimit = pvLowAlarmLimit->get();
108 double lowWarningLimit = pvLowWarningLimit->get();
109 double highWarningLimit = pvHighWarningLimit->get();
110 double highAlarmLimit = pvHighAlarmLimit->get();
111 double hysteresis = pvHysteresis->get();
112 int alarmRange = range_Normal;
113 if(highAlarmLimit>lowAlarmLimit) {
114 if(value>=highAlarmLimit
115 ||(prevAlarmRange==range_Hihi && value>=highAlarmLimit-hysteresis)) {
116 alarmRange = range_Hihi;
117 }
else if(value<=lowAlarmLimit
118 ||(prevAlarmRange==range_Lolo && value<=lowAlarmLimit+hysteresis)) {
119 alarmRange = range_Lolo;
122 if(alarmRange==range_Normal && (highWarningLimit>lowWarningLimit)) {
123 if(value>=highWarningLimit
124 ||(prevAlarmRange==range_High && value>=highWarningLimit-hysteresis)) {
125 alarmRange = range_High;
126 }
else if(value<=lowWarningLimit
127 ||(prevAlarmRange==range_Low && value<=lowWarningLimit+hysteresis)) {
128 alarmRange = range_Low;
131 bool retValue =
false;
132 if(alarmRange!=prevAlarmRange) {
133 setAlarm(pvAlarm,alarmRange);
136 prevAlarmRange = alarmRange;
137 currentValue = value;
141 void ScalarAlarmSupport::reset()
146 void ScalarAlarmSupport::setAlarm(
147 epics::pvData::PVStructurePtr
const & pva,
152 if(!pvAlarm.attach(pva))
throw std::logic_error(
"bad alarm field");
153 epics::pvData::AlarmStatus status(epics::pvData::noStatus);
154 epics::pvData::AlarmSeverity severity(epics::pvData::noAlarm);
156 switch (alarmRange) {
159 severity = epics::pvData::majorAlarm;
160 status = epics::pvData::recordStatus;
161 message =
"major low alarm";
166 severity = epics::pvData::minorAlarm;
167 status = epics::pvData::recordStatus;
168 message =
"minor low alarm";
177 severity = epics::pvData::minorAlarm;
178 status = epics::pvData::recordStatus;
179 message =
"minor high alarm";
184 severity = epics::pvData::majorAlarm;
185 status = epics::pvData::recordStatus;
186 message =
"major high alarm";
191 severity = epics::pvData::invalidAlarm;
192 status = epics::pvData::recordStatus;
193 message =
"invalid alarm";
196 case range_Undefined :
198 severity = epics::pvData::undefinedAlarm;
199 status = epics::pvData::recordStatus;
200 message =
"undefined alarm";
205 severity = epics::pvData::undefinedAlarm;
206 status = epics::pvData::recordStatus;
207 message =
"bad alarm definition";
211 alarm.setStatus(status);
212 alarm.setSeverity(severity);
213 alarm.setMessage(message);
std::tr1::shared_ptr< PVRecord > PVRecordPtr
std::tr1::shared_ptr< ScalarAlarmSupport > ScalarAlarmSupportPtr
Base interface for a ScalarAlarmSupport.