This is Unofficial EPICS BASE Doxygen Site
scalarAlarmSupport.cpp
Go to the documentation of this file.
1 /* scalarAlarmSupport.cpp */
11 #include <pv/pvTimeStamp.h>
12 #include <pv/rpcService.h>
13 #include <pv/convert.h>
14 #include <pv/standardField.h>
15 #include <pv/alarm.h>
16 #include <pv/pvAlarm.h>
17 
18 #define epicsExportSharedSymbols
19 #include "pv/pvStructureCopy.h"
20 #include "pv/pvSupport.h"
21 #include "pv/pvDatabase.h"
22 #include "pv/scalarAlarmSupport.h"
23 
25 using namespace epics::pvData;
26 using namespace epics::pvAccess;
27 using namespace std;
28 
29 namespace epics { namespace pvDatabase {
30 
31 ScalarAlarmSupport::~ScalarAlarmSupport()
32 {
33 //cout << "ScalarAlarmSupport::~ScalarAlarmSupport()\n";
34 }
35 
36 
37 epics::pvData::StructureConstPtr ScalarAlarmSupport::scalarAlarmField()
38 {
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)
46  ->createStructure();
47 }
48 
49 ScalarAlarmSupportPtr ScalarAlarmSupport::create(PVRecordPtr const & pvRecord)
50 {
51  ScalarAlarmSupportPtr support(new ScalarAlarmSupport(pvRecord));
52  return support;
53 }
54 
55 ScalarAlarmSupport::ScalarAlarmSupport(PVRecordPtr const & pvRecord)
56  : pvRecord(pvRecord),
57  prevAlarmRange(range_Undefined)
58 {}
59 
60 
61 bool ScalarAlarmSupport::init(
62  PVFieldPtr const & pvval,
63  PVStructurePtr const & pvalarm,
64  PVFieldPtr const & pvsup)
65 {
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);
70  }
71  }
72  if(!pvValue) {
73  cout << "ScalarAlarmSupport for record " << pvRecord->getRecordName()
74  << " failed because not numeric scalar\n";
75  return false;
76  }
77  pvScalarAlarm = static_pointer_cast<PVStructure>(pvsup);
78  if(pvScalarAlarm) {
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");
84  }
85  if(!pvScalarAlarm
86  || !pvLowAlarmLimit || !pvLowWarningLimit
87  || !pvLowWarningLimit || !pvHighAlarmLimit
88  || !pvHysteresis)
89  {
90  cout << "ScalarAlarmSupport for record " << pvRecord->getRecordName()
91  << " failed because pvSupport not a valid scalarAlarm structure\n";
92  return false;
93  }
94  pvAlarm = pvalarm;
95  ConvertPtr convert = getConvert();
96  requestedValue = convert->toDouble(pvValue);
97  currentValue = requestedValue;
98  isHystersis = false;
99  setAlarm(pvAlarm,range_Undefined);
100  return true;
101 }
102 
103 bool ScalarAlarmSupport::process()
104 {
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;
120  }
121  }
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;
129  }
130  }
131  bool retValue = false;
132  if(alarmRange!=prevAlarmRange) {
133  setAlarm(pvAlarm,alarmRange);
134  retValue = true;
135  }
136  prevAlarmRange = alarmRange;
137  currentValue = value;
138  return retValue;
139 }
140 
141 void ScalarAlarmSupport::reset()
142 {
143  isHystersis = false;
144 }
145 
146 void ScalarAlarmSupport::setAlarm(
148  int alarmRange)
149 {
150  Alarm alarm;
151  PVAlarm pvAlarm;
152  if(!pvAlarm.attach(pva)) throw std::logic_error("bad alarm field");
155  string message;
156  switch (alarmRange) {
157  case range_Lolo :
158  {
159  severity = epics::pvData::majorAlarm;
161  message = "major low alarm";
162  break;
163  }
164  case range_Low :
165  {
166  severity = epics::pvData::minorAlarm;
168  message = "minor low alarm";
169  break;
170  }
171  case range_Normal :
172  {
173  break;
174  }
175  case range_High :
176  {
177  severity = epics::pvData::minorAlarm;
179  message = "minor high alarm";
180  break;
181  }
182  case range_Hihi :
183  {
184  severity = epics::pvData::majorAlarm;
186  message = "major high alarm";
187  break;
188  }
189  case range_Invalid :
190  {
191  severity = epics::pvData::invalidAlarm;
193  message = "invalid alarm";
194  break;
195  }
196  case range_Undefined :
197  {
200  message = "undefined alarm";
201  break;
202  }
203  default:
204  {
207  message = "bad alarm definition";
208  break;
209  }
210  }
211  alarm.setStatus(status);
212  alarm.setSeverity(severity);
213  alarm.setMessage(message);
214  pvAlarm.set(alarm);
215 }
216 
217 
218 }}
FORCE_INLINE std::tr1::shared_ptr< PVField > getSubField(A a)
Definition: pvData.h:744
This class implements introspection object for Scalar.
Definition: pvIntrospect.h:397
Definition: link.h:174
AlarmSeverity
enum definition of AlarmSeverity
Definition: alarm.h:30
PVScalar is the base class for each scalar field.
Definition: pvData.h:272
Methods for manipulating alarm.
Definition: alarm.h:105
pvd::Status status
void setMessage(std::string const &value)
Definition: alarm.h:121
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:788
bool attach(PVFieldPtr const &pvField)
Definition: pvAlarm.cpp:26
Definition: memory.hpp:41
bool set(Alarm const &alarm)
Definition: pvAlarm.cpp:69
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
std::tr1::shared_ptr< const Scalar > ScalarConstPtr
Definition: pvIntrospect.h:150
Holds all PVA related.
Definition: pvif.h:34
pvData
Definition: monitor.h:428
void setSeverity(AlarmSeverity value)
Definition: alarm.h:132
bool isNumeric(ScalarType type)
Definition: TypeFunc.cpp:53
Methods for accessing an alarm structure.
Definition: pvAlarm.h:37
Data interface for a structure,.
Definition: pvData.h:712
std::tr1::shared_ptr< PVRecord > PVRecordPtr
Definition: pvDatabase.h:21
std::tr1::shared_ptr< PVStructure > PVStructurePtr
Definition: pvData.h:87
std::tr1::shared_ptr< ScalarAlarmSupport > ScalarAlarmSupportPtr
void setStatus(AlarmStatus value)
Definition: alarm.h:143
AlarmStatus
enum definition of AlarmStatus
Definition: alarm.h:45
Class that holds the data for each possible scalar type.
Definition: pvData.h:54
std::tr1::shared_ptr< PVField > PVFieldPtr
Definition: pvData.h:66
std::tr1::shared_ptr< Convert > ConvertPtr
Definition: convert.h:23
Base interface for a ScalarAlarmSupport.
static FieldBuilderPtr begin()