pvaClientCPP  4.8.1-dev
pvaClientNTMultiData.cpp
Go to the documentation of this file.
1 /* pvaClientNTMultiData.cpp */
12 #include <epicsMath.h>
13 
14 #define epicsExportSharedSymbols
15 
17 
18 using namespace epics::pvData;
19 using namespace epics::pvAccess;
20 using namespace epics::nt;
21 using namespace std;
22 
23 namespace epics { namespace pvaClient {
24 
25 PvaClientNTMultiDataPtr PvaClientNTMultiData::create(
26  UnionConstPtr const & u,
27  PvaClientMultiChannelPtr const &pvaMultiChannel,
28  PvaClientChannelArray const &pvaClientChannelArray,
29  PVStructurePtr const & pvRequest)
30 {
32  new PvaClientNTMultiData(u,pvaMultiChannel,pvaClientChannelArray,pvRequest));
33 }
34 
35 PvaClientNTMultiData::PvaClientNTMultiData(
36  UnionConstPtr const & u,
37  PvaClientMultiChannelPtr const &pvaClientMultiChannel,
38  PvaClientChannelArray const &pvaClientChannelArray,
39  PVStructurePtr const & pvRequest)
40 : pvaClientMultiChannel(pvaClientMultiChannel),
41  pvaClientChannelArray(pvaClientChannelArray),
42  nchannel(pvaClientChannelArray.size()),
43  gotAlarm(false),
44  gotTimeStamp(false)
45 
46 {
47  if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::PvaClientNTMultiData()\n";
48  changeFlags = shared_vector<epics::pvData::boolean>(nchannel);
49  topPVStructure.resize(nchannel);
50 
51  unionValue.resize(nchannel);
52  PVDataCreatePtr pvDataCreate = getPVDataCreate();
53  for(size_t i=0; i< nchannel; ++i) {
54  topPVStructure[i] = PVStructurePtr();
55  unionValue[i] = pvDataCreate->createPVUnion(u);
56  }
57  NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder();
58  builder->value(u)->addIsConnected();
59  if(pvRequest->getSubField("field.alarm"))
60  {
61  gotAlarm = true;
62  builder->addAlarm();
63  builder->addSeverity();
64  builder->addStatus();
65  builder->addMessage();
66  severity.resize(nchannel);
67  status.resize(nchannel);
68  message.resize(nchannel);
69 
70  }
71  if(pvRequest->getSubField("field.timeStamp")) {
72  gotTimeStamp = true;
73  builder->addTimeStamp();
74  builder->addSecondsPastEpoch();
75  builder->addNanoseconds();
76  builder->addUserTag();
77  secondsPastEpoch.resize(nchannel);
78  nanoseconds.resize(nchannel);
79  userTag.resize(nchannel);
80  }
81  ntMultiChannelStructure = builder->createStructure();
82 }
83 
84 
85 PvaClientNTMultiData::~PvaClientNTMultiData()
86 {
87  if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::~PvaClientNTMultiData()\n";
88 }
89 
90 void PvaClientNTMultiData::setPVStructure(
91  PVStructurePtr const &pvStructure,size_t index)
92 {
93  topPVStructure[index] = pvStructure;
94 }
95 
96 shared_vector<epics::pvData::boolean> PvaClientNTMultiData::getChannelChangeFlags()
97 {
98  return changeFlags;
99 }
100 
101 size_t PvaClientNTMultiData::getNumber()
102 {
103  return nchannel;
104 }
105 
106 
107 
108 void PvaClientNTMultiData::startDeltaTime()
109 {
110  for(size_t i=0; i<nchannel; ++i)
111  {
112  topPVStructure[i] = PVStructurePtr();
113  if(gotAlarm)
114  {
115  alarm.setSeverity(noAlarm);
116  alarm.setStatus(noStatus);
117  alarm.setMessage("");
118  severity[i] = invalidAlarm;
119  status[i] = undefinedStatus;
120  message[i] = "not connected";
121  }
122  if(gotTimeStamp)
123  {
124  timeStamp.getCurrent();
125  secondsPastEpoch[i] = 0;
126  nanoseconds[i] = 0;
127  userTag[i] = 0;
128  }
129  }
130 }
131 
132 
133 void PvaClientNTMultiData::endDeltaTime(bool valueOnly)
134 {
135  for(size_t i=0; i<nchannel; ++i)
136  {
137  PVStructurePtr pvst = topPVStructure[i];
138  changeFlags[i] = false;
139  if(pvst&&unionValue[i]) {
140  changeFlags[i] = true;
141  if(valueOnly) {
142  PVFieldPtr pvValue = pvst->getSubField("value");
143  if(pvValue) {
144  unionValue[i]->set(pvst->getSubField("value"));
145  }
146  } else {
147  unionValue[i]->set(pvst);
148  }
149  if(gotAlarm)
150  {
151  PVIntPtr pvSeverity = pvst->getSubField<PVInt>("alarm.severity");
152  PVIntPtr pvStatus = pvst->getSubField<PVInt>("alarm.status");
153  PVStringPtr pvMessage = pvst->getSubField<PVString>("alarm.message");
154  if(pvSeverity&&pvStatus&&pvMessage) {
155  severity[i] = pvSeverity->get();
156  status[i] = pvStatus->get();
157  message[i] = pvMessage->get();
158  } else {
159  severity[i] = undefinedAlarm;
160  status[i] = undefinedStatus;
161  message[i] = "no alarm field";
162  }
163  }
164  if(gotTimeStamp)
165  {
166  PVLongPtr pvEpoch = pvst->getSubField<PVLong>("timeStamp.secondsPastEpoch");
167  PVIntPtr pvNano = pvst->getSubField<PVInt>("timeStamp.nanoseconds");
168  PVIntPtr pvTag = pvst->getSubField<PVInt>("timeStamp.userTag");
169  if(pvEpoch&&pvNano&&pvTag) {
170  secondsPastEpoch[i] = pvEpoch->get();
171  nanoseconds[i] = pvNano->get();
172  userTag[i] = pvTag->get();
173  }
174  }
175  }
176  }
177 }
178 
179 TimeStamp PvaClientNTMultiData::getTimeStamp()
180 {
181  pvTimeStamp.get(timeStamp);
182  return timeStamp;
183 }
184 
185 NTMultiChannelPtr PvaClientNTMultiData::getNTMultiChannel()
186 {
187  PVStructurePtr pvStructure = getPVDataCreate()->createPVStructure(ntMultiChannelStructure);
188  NTMultiChannelPtr ntMultiChannel = NTMultiChannel::wrap(pvStructure);
189  ntMultiChannel->getChannelName()->replace(pvaClientMultiChannel->getChannelNames());
190  shared_vector<PVUnionPtr> val(nchannel);
191  for(size_t i=0; i<nchannel; ++i) val[i] = unionValue[i];
192  ntMultiChannel->getValue()->replace(freeze(val));
193  shared_vector<epics::pvData::boolean> connected = pvaClientMultiChannel->getIsConnected();
194  shared_vector<epics::pvData::boolean> isConnected(nchannel);
195  for(size_t i=0; i<nchannel; ++i) isConnected[i] = connected[i];
196  ntMultiChannel->getIsConnected()->replace(freeze(isConnected));
197  if(gotAlarm)
198  {
199  shared_vector<int32> sev(nchannel);
200  for(size_t i=0; i<nchannel; ++i) sev[i] = severity[i];
201  ntMultiChannel->getSeverity()->replace(freeze(sev));
202  shared_vector<int32> sta(nchannel);
203  for(size_t i=0; i<nchannel; ++i) sta[i] = status[i];
204  ntMultiChannel->getStatus()->replace(freeze(sta));
205  shared_vector<string> mes(nchannel);
206  for(size_t i=0; i<nchannel; ++i) mes[i] = message[i];
207  ntMultiChannel->getMessage()->replace(freeze(mes));
208  }
209  if(gotTimeStamp)
210  {
211  shared_vector<int64> sec(nchannel);
212  for(size_t i=0; i<nchannel; ++i) sec[i] = secondsPastEpoch[i];
213  ntMultiChannel->getSecondsPastEpoch()->replace(freeze(sec));
214  shared_vector<int32> nano(nchannel);
215  for(size_t i=0; i<nchannel; ++i) nano[i] = nanoseconds[i];
216  ntMultiChannel->getNanoseconds()->replace(freeze(nano));
217  shared_vector<int32> tag(nchannel);
218  for(size_t i=0; i<nchannel; ++i) tag[i] = userTag[i];
219  ntMultiChannel->getUserTag()->replace(freeze(tag));
220  }
221  return ntMultiChannel;
222 }
223 
224 }}
epics::pvData::shared_vector< PvaClientChannelPtr > PvaClientChannelArray
STL namespace.
std::tr1::shared_ptr< PvaClientNTMultiData > PvaClientNTMultiDataPtr
std::tr1::shared_ptr< PvaClientMultiChannel > PvaClientMultiChannelPtr
Provides NTMultiChannel data for both PvaClientNTMultiGet and PvaClientNTMultiMonitor.