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)
51 cerr <<
"ScalarAlarmSupport IS DEPRECATED\n";
56 ScalarAlarmSupport::ScalarAlarmSupport(
PVRecordPtr const & pvRecord)
58 prevAlarmRange(range_Undefined)
62 bool ScalarAlarmSupport::init(
63 PVFieldPtr
const & pvval,
64 PVStructurePtr
const & pvalarm,
65 PVFieldPtr
const & pvsup)
67 if(pvval->getField()->getType()==epics::pvData::scalar) {
68 ScalarConstPtr s = static_pointer_cast<
const Scalar>(pvval->getField());
69 if(ScalarTypeFunc::isNumeric(s->getScalarType())) {
70 pvValue = static_pointer_cast<PVScalar>(pvval);
74 cout <<
"ScalarAlarmSupport for record " << pvRecord->getRecordName()
75 <<
" failed because not numeric scalar\n";
78 pvScalarAlarm = static_pointer_cast<PVStructure>(pvsup);
80 pvLowAlarmLimit = pvScalarAlarm->getSubField<PVDouble>(
"lowAlarmLimit");
81 pvLowWarningLimit = pvScalarAlarm->getSubField<PVDouble>(
"lowWarningLimit");
82 pvHighWarningLimit = pvScalarAlarm->getSubField<PVDouble>(
"highWarningLimit");
83 pvHighAlarmLimit = pvScalarAlarm->getSubField<PVDouble>(
"highAlarmLimit");
84 pvHysteresis = pvScalarAlarm->getSubField<PVDouble>(
"hysteresis");
87 || !pvLowAlarmLimit || !pvLowWarningLimit
88 || !pvLowWarningLimit || !pvHighAlarmLimit
91 cout <<
"ScalarAlarmSupport for record " << pvRecord->getRecordName()
92 <<
" failed because pvSupport not a valid scalarAlarm structure\n";
96 ConvertPtr convert = getConvert();
97 requestedValue = convert->toDouble(pvValue);
98 currentValue = requestedValue;
100 setAlarm(pvAlarm,range_Undefined);
104 bool ScalarAlarmSupport::process()
106 ConvertPtr convert = getConvert();
107 double value = convert->toDouble(pvValue);
108 double lowAlarmLimit = pvLowAlarmLimit->get();
109 double lowWarningLimit = pvLowWarningLimit->get();
110 double highWarningLimit = pvHighWarningLimit->get();
111 double highAlarmLimit = pvHighAlarmLimit->get();
112 double hysteresis = pvHysteresis->get();
113 int alarmRange = range_Normal;
114 if(highAlarmLimit>lowAlarmLimit) {
115 if(value>=highAlarmLimit
116 ||(prevAlarmRange==range_Hihi && value>=highAlarmLimit-hysteresis)) {
117 alarmRange = range_Hihi;
118 }
else if(value<=lowAlarmLimit
119 ||(prevAlarmRange==range_Lolo && value<=lowAlarmLimit+hysteresis)) {
120 alarmRange = range_Lolo;
123 if(alarmRange==range_Normal && (highWarningLimit>lowWarningLimit)) {
124 if(value>=highWarningLimit
125 ||(prevAlarmRange==range_High && value>=highWarningLimit-hysteresis)) {
126 alarmRange = range_High;
127 }
else if(value<=lowWarningLimit
128 ||(prevAlarmRange==range_Low && value<=lowWarningLimit+hysteresis)) {
129 alarmRange = range_Low;
132 bool retValue =
false;
133 if(alarmRange!=prevAlarmRange) {
134 setAlarm(pvAlarm,alarmRange);
137 prevAlarmRange = alarmRange;
138 currentValue = value;
142 void ScalarAlarmSupport::reset()
147 void ScalarAlarmSupport::setAlarm(
148 epics::pvData::PVStructurePtr
const & pva,
153 if(!pvAlarm.attach(pva))
throw std::logic_error(
"bad alarm field");
154 epics::pvData::AlarmStatus status(epics::pvData::noStatus);
155 epics::pvData::AlarmSeverity severity(epics::pvData::noAlarm);
157 switch (alarmRange) {
160 severity = epics::pvData::majorAlarm;
161 status = epics::pvData::recordStatus;
162 message =
"major low alarm";
167 severity = epics::pvData::minorAlarm;
168 status = epics::pvData::recordStatus;
169 message =
"minor low alarm";
178 severity = epics::pvData::minorAlarm;
179 status = epics::pvData::recordStatus;
180 message =
"minor high alarm";
185 severity = epics::pvData::majorAlarm;
186 status = epics::pvData::recordStatus;
187 message =
"major high alarm";
192 severity = epics::pvData::invalidAlarm;
193 status = epics::pvData::recordStatus;
194 message =
"invalid alarm";
197 case range_Undefined :
199 severity = epics::pvData::undefinedAlarm;
200 status = epics::pvData::recordStatus;
201 message =
"undefined alarm";
206 severity = epics::pvData::undefinedAlarm;
207 status = epics::pvData::recordStatus;
208 message =
"bad alarm definition";
212 alarm.setStatus(status);
213 alarm.setSeverity(severity);
214 alarm.setMessage(message);
std::tr1::shared_ptr< PVRecord > PVRecordPtr
std::tr1::shared_ptr< ScalarAlarmSupport > ScalarAlarmSupportPtr
Base interface for a ScalarAlarmSupport.