pvDatabaseCPP  4.7.0
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 
24 using std::tr1::static_pointer_cast;
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  cerr << "ScalarAlarmSupport IS DEPRECATED\n";
52  ScalarAlarmSupportPtr support(new ScalarAlarmSupport(pvRecord));
53  return support;
54 }
55 
56 ScalarAlarmSupport::ScalarAlarmSupport(PVRecordPtr const & pvRecord)
57  : pvRecord(pvRecord),
58  prevAlarmRange(range_Undefined)
59 {}
60 
61 
62 bool ScalarAlarmSupport::init(
63  PVFieldPtr const & pvval,
64  PVStructurePtr const & pvalarm,
65  PVFieldPtr const & pvsup)
66 {
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);
71  }
72  }
73  if(!pvValue) {
74  cout << "ScalarAlarmSupport for record " << pvRecord->getRecordName()
75  << " failed because not numeric scalar\n";
76  return false;
77  }
78  pvScalarAlarm = static_pointer_cast<PVStructure>(pvsup);
79  if(pvScalarAlarm) {
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");
85  }
86  if(!pvScalarAlarm
87  || !pvLowAlarmLimit || !pvLowWarningLimit
88  || !pvLowWarningLimit || !pvHighAlarmLimit
89  || !pvHysteresis)
90  {
91  cout << "ScalarAlarmSupport for record " << pvRecord->getRecordName()
92  << " failed because pvSupport not a valid scalarAlarm structure\n";
93  return false;
94  }
95  pvAlarm = pvalarm;
96  ConvertPtr convert = getConvert();
97  requestedValue = convert->toDouble(pvValue);
98  currentValue = requestedValue;
99  isHystersis = false;
100  setAlarm(pvAlarm,range_Undefined);
101  return true;
102 }
103 
104 bool ScalarAlarmSupport::process()
105 {
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;
121  }
122  }
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;
130  }
131  }
132  bool retValue = false;
133  if(alarmRange!=prevAlarmRange) {
134  setAlarm(pvAlarm,alarmRange);
135  retValue = true;
136  }
137  prevAlarmRange = alarmRange;
138  currentValue = value;
139  return retValue;
140 }
141 
142 void ScalarAlarmSupport::reset()
143 {
144  isHystersis = false;
145 }
146 
147 void ScalarAlarmSupport::setAlarm(
148  epics::pvData::PVStructurePtr const & pva,
149  int alarmRange)
150 {
151  Alarm alarm;
152  PVAlarm pvAlarm;
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);
156  string message;
157  switch (alarmRange) {
158  case range_Lolo :
159  {
160  severity = epics::pvData::majorAlarm;
161  status = epics::pvData::recordStatus;
162  message = "major low alarm";
163  break;
164  }
165  case range_Low :
166  {
167  severity = epics::pvData::minorAlarm;
168  status = epics::pvData::recordStatus;
169  message = "minor low alarm";
170  break;
171  }
172  case range_Normal :
173  {
174  break;
175  }
176  case range_High :
177  {
178  severity = epics::pvData::minorAlarm;
179  status = epics::pvData::recordStatus;
180  message = "minor high alarm";
181  break;
182  }
183  case range_Hihi :
184  {
185  severity = epics::pvData::majorAlarm;
186  status = epics::pvData::recordStatus;
187  message = "major high alarm";
188  break;
189  }
190  case range_Invalid :
191  {
192  severity = epics::pvData::invalidAlarm;
193  status = epics::pvData::recordStatus;
194  message = "invalid alarm";
195  break;
196  }
197  case range_Undefined :
198  {
199  severity = epics::pvData::undefinedAlarm;
200  status = epics::pvData::recordStatus;
201  message = "undefined alarm";
202  break;
203  }
204  default:
205  {
206  severity = epics::pvData::undefinedAlarm;
207  status = epics::pvData::recordStatus;
208  message = "bad alarm definition";
209  break;
210  }
211  }
212  alarm.setStatus(status);
213  alarm.setSeverity(severity);
214  alarm.setMessage(message);
215  pvAlarm.set(alarm);
216 }
217 
218 
219 }}
STL namespace.
std::tr1::shared_ptr< PVRecord > PVRecordPtr
Definition: pvDatabase.h:21
std::tr1::shared_ptr< ScalarAlarmSupport > ScalarAlarmSupportPtr
Base interface for a ScalarAlarmSupport.