DABC (Data Acquisition Backbone Core)  2.9.9
Monitor.cxx
Go to the documentation of this file.
1 // $Id: Monitor.cxx 4473 2020-04-15 13:35:08Z linev $
2 
3 /************************************************************
4  * The Data Acquisition Backbone Core (DABC) *
5  ************************************************************
6  * Copyright (C) 2009 - *
7  * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
8  * Planckstr. 1, 64291 Darmstadt, Germany *
9  * Contact: http://dabc.gsi.de *
10  ************************************************************
11  * This software can be used under the GPL license *
12  * agreements as stated in LICENSE.txt file *
13  * which is part of the distribution. *
14  ************************************************************/
15 
16 #include "ezca/Monitor.h"
17 
18 #include <ctime>
19 
20 #include "tsDefs.h"
21 #include "cadef.h"
22 #include "ezca.h"
23 
24 #include "ezca/Definitions.h"
25 
26 #include "dabc/Publisher.h"
27 #include "mbs/MbsTypeDefs.h"
28 #include "mbs/Iterator.h"
29 #include "mbs/SlowControlData.h"
30 
31 ezca::Monitor::Monitor(const std::string &name, dabc::Command cmd) :
32  mbs::MonitorSlowControl(name, "Epics", cmd),
33  fEzcaTimeout(-1.),
34  fEzcaRetryCnt(-1),
35  fEzcaDebug(false),
36  fEzcaAutoError(false),
37  fTimeout(1),
38  fNameSepar(":"),
39  fTopFolder(),
40  fLongRecords(),
41  fLongValues(),
42  fLongRes(),
43  fDoubleRecords(),
44  fDoubleValues(),
45  fDoubleRes()
46 {
47  fEzcaTimeout = Cfg(ezca::xmlEzcaTimeout, cmd).AsDouble(fEzcaTimeout);
48  fEzcaRetryCnt = Cfg(ezca::xmlEzcaRetryCount, cmd).AsInt(fEzcaRetryCnt);
49  fEzcaDebug = Cfg(ezca::xmlEzcaDebug, cmd).AsBool(fEzcaDebug);
50  fEzcaAutoError = Cfg(ezca::xmlEzcaAutoError, cmd).AsBool(fEzcaAutoError);
51 
52  fTimeout = Cfg(ezca::xmlTimeout, cmd).AsDouble(fTimeout);
53  fNameSepar = Cfg("NamesSepar", cmd).AsStr(fNameSepar);
54  fTopFolder = Cfg("TopFolder", cmd).AsStr(fTopFolder);
55 
56  fLongRecords = Cfg(ezca::xmlNameLongRecords, cmd).AsStrVect();
57  fLongValues.resize(fLongRecords.size(), 0);
58  fLongRes.resize(fLongRecords.size(), false);
59 
60  fDoubleRecords = Cfg(ezca::xmlNameDoubleRecords, cmd).AsStrVect();
61  fDoubleValues.resize(fDoubleRecords.size());
62  fDoubleRes.resize(fDoubleRecords.size(), false);
63 
64  fWorkerHierarchy.Create("EZCA");
65 
66  // fTopFolder = "HAD";
67 
68  for (unsigned ix = 0; ix < fLongRecords.size(); ++ix) {
69  dabc::Hierarchy item = fWorkerHierarchy.CreateHChild(GetItemName(fLongRecords[ix]));
70  DOUT0("Name = %s item %p", GetItemName(fLongRecords[ix]).c_str(), item());
71  item.SetField(dabc::prop_kind, "rate");
72  item.EnableHistory(100);
73  }
74 
75  for (unsigned ix = 0; ix < fDoubleRecords.size(); ++ix) {
76  dabc::Hierarchy item = fWorkerHierarchy.CreateHChild(GetItemName(fDoubleRecords[ix]));
77  item.SetField(dabc::prop_kind, "rate");
78  item.EnableHistory(100);
79  }
80 
81  if (fTimeout<=0.001) fTimeout = 0.001;
82 
83  CreateTimer("EpicsRead", fTimeout);
84 
85  if (fTopFolder.empty())
86  Publish(fWorkerHierarchy, "EZCA");
87  else
88  Publish(fWorkerHierarchy, std::string("EZCA/") + fTopFolder);
89 }
90 
91 std::string ezca::Monitor::GetItemName(const std::string &ezcaname)
92 {
93  std::string res = ezcaname;
94 
95  if (!fNameSepar.empty()) {
96  size_t pos = 0;
97 
98  while ((pos = res.find_first_of(fNameSepar, pos)) != std::string::npos)
99  res[pos++] = '/';
100  }
101 
102  if (!fTopFolder.empty()) {
103  // any variable should have top folder name in front
104  if (res.find(fTopFolder)!=0) return std::string();
105  res.erase(0, fTopFolder.length()+1); // delete top folder and slash
106  }
107 
108  return res;
109 }
110 
111 
113 {
115 
116  if (fEzcaTimeout>0) ezcaSetTimeout(fEzcaTimeout);
117 
118  if (fEzcaRetryCnt>0) ezcaSetRetryCount(fEzcaRetryCnt);
119 
120  if (fEzcaDebug) ezcaDebugOn();
121  else ezcaDebugOff();
122 
123  if (fEzcaAutoError) ezcaAutoErrorMessageOn();
124  else ezcaAutoErrorMessageOff();
125 
126  fLastSendTime.GetNow();
127 }
128 
129 void ezca::Monitor::ProcessTimerEvent(unsigned timer)
130 {
131  if (TimerName(timer) == "EpicsRead") {
132  if (!DoEpicsReadout()) return;
133 
134  for (unsigned ix = 0; ix < fLongRecords.size(); ++ix)
135  if (fLongRes[ix])
136  fWorkerHierarchy.GetHChild(GetItemName(fLongRecords[ix])).SetField("value", fLongValues[ix]);
137 
138  for (unsigned ix = 0; ix < fDoubleRecords.size(); ++ix)
139  if (fDoubleRes[ix])
140  fWorkerHierarchy.GetHChild(GetItemName(fDoubleRecords[ix])).SetField("value", fDoubleValues[ix]);
141 
142  fWorkerHierarchy.MarkChangedItems();
143  }
144 
145 
147 }
148 
150 {
151  fRec.Clear();
152 
153  for (unsigned ix = 0; ix < fLongRecords.size(); ++ix)
154  if (fLongRes[ix]) fRec.AddLong(fLongRecords[ix], fLongValues[ix]);
155 
156  for (unsigned ix = 0; ix < fDoubleRecords.size(); ++ix)
157  if (fDoubleRes[ix]) fRec.AddDouble(fDoubleRecords[ix], fDoubleValues[ix]);
158 
159  return fRec.GetRawSize();
160 }
161 
163 {
164  if ((fLongRecords.size()==0) && (fDoubleRecords.size()==0)) return false;
165 
166  dabc::TimeStamp tm = dabc::Now();
167 
168  bool res = true;
169 
170  ezcaStartGroup();
171 
172  // now the data values for each record in order:
173  for (unsigned ix = 0; ix < fLongRecords.size(); ix++) {
174  fLongValues[ix] = 0;
175  fLongRes[ix] = true;
176  int ret = CA_GetLong(fLongRecords[ix], fLongValues[ix]);
177  if (ret==EZCA_OK) continue;
178  EOUT("Request long %s Ret = %s", fLongRecords[ix].c_str(), CA_RetCode(ret));
179  res = false;
180  }
181 
182  for (unsigned ix = 0; ix < fDoubleRecords.size(); ix++) {
183  fDoubleValues[ix] = 0;
184  fDoubleRes[ix] = true;
185  int ret = CA_GetDouble(fDoubleRecords[ix], fDoubleValues[ix]);
186  if (ret==EZCA_OK) continue;
187  EOUT("Request double %s Ret = %s", fDoubleRecords[ix].c_str(), CA_RetCode(ret));
188  res = false;
189  }
190 
191 
192  int *rcs(0), nrcs(0);
193 
194  if (ezcaEndGroupWithReport(&rcs, &nrcs) != EZCA_OK) {
195  res = false;
196  EOUT("EZCA error %s", CA_ErrorString().c_str());
197  for (unsigned i=0; i< (unsigned) nrcs; i++)
198  if (i<fLongRecords.size()) {
199  unsigned ix = i;
200  fLongRes[ix] = (rcs[i]==EZCA_OK);
201  if (!fLongRes[ix])
202  EOUT("Problem getting long %s ret %s", fLongRecords[ix].c_str(), CA_RetCode(rcs[i]));
203  } else {
204  unsigned ix = i - fLongRecords.size();
205  fDoubleRes[ix] = (rcs[i]==EZCA_OK);
206  if (!fDoubleRes[ix])
207  EOUT("Problem getting double %s ret %s", fDoubleRecords[ix].c_str(), CA_RetCode(rcs[i]));
208  }
209  }
210 
211  ezcaFree(rcs);
212 
213  DOUT0("Epics readout time is = %7.5f s res = %s", tm.SpentTillNow(), DBOOL(res));
214 
215  return res;
216 }
217 
218 
219 int ezca::Monitor::CA_GetLong(const std::string &name, long& val)
220 {
221  int rev = ezcaGet((char*) name.c_str(), ezcaLong, 1, &val);
222  if(rev!=EZCA_OK)
223  EOUT("%s", CA_ErrorString().c_str());
224  else
225  DOUT3("EpicsInput::CA_GetLong(%s) = %d",name.c_str(),val);
226  return rev;
227 }
228 
229 int ezca::Monitor::CA_GetDouble(const std::string &name, double& val)
230 {
231  int rev=ezcaGet((char*) name.c_str(), ezcaDouble, 1, &val);
232  if(rev!=EZCA_OK)
233  EOUT("%s", CA_ErrorString().c_str());
234  else
235  DOUT3("EpicsInput::CA_GetDouble(%s) = %f",name.c_str(),val);
236  return rev;
237 }
238 
239 std::string ezca::Monitor::CA_ErrorString()
240 {
241  std::string res;
242 
243  char *error_msg_buff(0);
244  ezcaGetErrorString(NULL, &error_msg_buff);
245  if (error_msg_buff!=0) res = error_msg_buff;
246  ezcaFree(error_msg_buff);
247 
248  return res;
249 }
250 
251 const char* ezca::Monitor::CA_RetCode(int ret)
252 {
253  switch (ret) {
254  case EZCA_OK: return "EZCA_OK";
255  case EZCA_INVALIDARG: return "EZCA_INVALIDARG";
256  case EZCA_FAILEDMALLOC: return "EZCA_FAILEDMALLOC";
257  case EZCA_CAFAILURE: return "EZCA_CAFAILURE";
258  case EZCA_UDFREQ: return "EZCA_UDFREQ";
259  case EZCA_NOTCONNECTED: return "EZCA_NOTCONNECTED";
260  case EZCA_NOTIMELYRESPONSE: return "EZCA_NOTIMELYRESPONSE";
261  case EZCA_INGROUP: return "EZCA_INGROUP";
262  case EZCA_NOTINGROUP: return "EZCA_NOTINGROUP";
263  case EZCA_ABORTED: return "EZCA_ABORTED";
264  }
265 
266  return "unknown";
267 }
Represents command with its arguments.
Definition: Command.h:99
Represents objects hierarchy of remote (or local) DABC process.
Definition: Hierarchy.h:285
Hierarchy CreateHChild(const std::string &name, bool allowslahes=false, bool sortorder=false)
Create child item in hierarchy with specified name If allowslahes enabled, instead of subfolders item...
Definition: Hierarchy.h:392
void EnableHistory(unsigned length=100, bool withchilds=false)
Activate history production for selected element and its childs.
Definition: Hierarchy.cxx:837
virtual void OnThreadAssigned()
Definition: Module.cxx:79
bool SetField(const std::string &name, const RecordField &v)
Definition: Record.h:516
virtual void OnThreadAssigned()
Initialize some EZCA settings, do it from worker thread.
Definition: Monitor.cxx:112
virtual void ProcessTimerEvent(unsigned timer)
Method called by framework when timer event is produced.
Definition: Monitor.cxx:129
int CA_GetDouble(const std::string &name, double &val)
Definition: Monitor.cxx:229
virtual unsigned GetRecRawSize()
Definition: Monitor.cxx:149
std::string fTopFolder
name of top folder, which should exists also in every variable
Definition: Monitor.h:43
std::string CA_ErrorString()
Return error string with error description.
Definition: Monitor.cxx:239
int CA_GetLong(const std::string &name, long &val)
Definition: Monitor.cxx:219
Monitor(const std::string &name, dabc::Command cmd=nullptr)
Definition: Monitor.cxx:31
std::string fNameSepar
separator symbol(s), which defines subfolder in epcis names
Definition: Monitor.h:42
const char * CA_RetCode(int ret)
Definition: Monitor.cxx:251
bool DoEpicsReadout()
Perform readout of all variables.
Definition: Monitor.cxx:162
std::string GetItemName(const std::string &ezcaname)
Definition: Monitor.cxx:91
virtual void ProcessTimerEvent(unsigned timer)
Method called by framework when timer event is produced.
#define DOUT0(args ...)
Definition: logging.h:156
#define DOUT3(args ...)
Definition: logging.h:176
#define EOUT(args ...)
Definition: logging.h:150
#define DBOOL(arg)
Definition: logging.h:191
TimeStamp Now()
Definition: timing.h:260
const char * prop_kind
Definition: Hierarchy.cxx:29
const char * xmlEzcaAutoError
indicates if error should be automatically printed
Definition: Factory.cxx:39
const char * xmlNameLongRecords
Definition: Factory.cxx:32
const char * xmlTimeout
Definition: Factory.cxx:34
const char * xmlEzcaDebug
retry counter for ezca operation
Definition: Factory.cxx:38
const char * xmlEzcaTimeout
timeout for ezca operation
Definition: Factory.cxx:36
const char * xmlEzcaRetryCount
retry counter for ezca operation
Definition: Factory.cxx:37
const char * xmlNameDoubleRecords
Definition: Factory.cxx:33
Support for MBS - standard GSI DAQ.
Definition: api.h:36
Class for acquiring and holding timestamps.
Definition: timing.h:40
double SpentTillNow() const
Method return time in second, spent from the time kept in TimeStamp instance If time was not set befo...
Definition: timing.h:144