OpcUaCanOpen
CANopen OPC-UA server
UaCalcItem.cxx
Go to the documentation of this file.
1 #include "UaCalcItem.h"
2 #include "boost/bind/bind.hpp"
3 #include "UaCanTrace.h"
4 #define _USE_MATH_DEFINES
5 #include <math.h>
6 
7 #ifdef WIN32
8 #define isnan(x) _isnan(x)
9 #define isinf(x) (!_finite(x))
10 #define fpu_error(x) (isinf(x) || isnan(x))
11 #endif
12 
13 namespace AddressSpace
14 {
15 // mapDataVariable UaCalcCompiler::pVariables;
16 
17 // UaStatus UaCalcCompiler::CreateItems()
18 // {
19 // UaString sName,sFullName,tName;
20 // std::string stdName;
21 // UaVariant defaultValue;
22 // UaStatus ret;
23 // UaDataValue dataValue;
24 // UaDateTime udt;
25 // UaNodeId uaId;
26 // UaVariant val;
27 // UaCalcItem* pUaCalcItem;
28 // UaVariant dv;
29 //
30 //
31 // /// sets of OpcUa server data variable where the key is name of the set
32 //
33 // // mapDataVariable pConditionVariables;
34 //
35 // for (unsigned int i = 0; i < m_vCCI.size(); i++)
36 // {
37 // UaCalcCompilerItem *ucci = m_vCCI[i];
38 // string formul = ucci->getFormula();
39 // string whenCondition = ucci->getWhenCondition();
40 // string statusCondition = ucci->getStatusCondition();
41 // OpcUa::BaseObjectType *pcn = ucci->getParentCalc();
42 // sName = ucci->getName().c_str();
43 // REGEXPR_sequence &regex = ucci->getRegExp();
44 // UaMutexRefCounted *pSharedMutex = ucci->getItemSharedMutex();
45 // OpcUa_Int32 minVar = 0xEFFFFFF;
46 // ret = createRegVariable(formul, ucci->getMapDataVariable(), pcn, regex, minVar);
47 // if (ret.isGood()) {
48 // ret = createRegVariable(whenCondition, ucci->getMapDataVariable(), pcn, regex, minVar);
49 // if (ret.isGood()) {
50 // ret = createRegVariable(statusCondition, ucci->getMapDataVariable(), pcn, regex, minVar);
51 // if (ret.isGood()) {
52 // if (minVar > 0 ) {
53 // for (OpcUa_Int32 j = 0; j < minVar; j++)
54 // {
55 // sFullName = UaString("%1_%2").arg(sName).arg(j);
56 // uaId = m_pNodeManager->getNewNodeId(pcn, sFullName);
57 //
58 // pUaCalcItem = new UaCalcItem(sFullName,uaId,m_pNodeManager,dv,formul,whenCondition,statusCondition,pSharedMutex);
59 // dataValue.setDataValue(dv,OpcUa_False,OpcUa_BadWaitingForInitialData,UaDateTime::now(),UaDateTime::now());
60 // pUaCalcItem->setValue(0,dataValue,OpcUa_False);
61 // ucci->addTempItem(pUaCalcItem);
62 // if (pcn == NULL) {
63 // ret = m_pNodeManager->addNodeAndReference( OpcUaId_ObjectsFolder, pUaCalcItem,OpcUaId_HasComponent);
64 // }
65 // else
66 // ret = m_pNodeManager->addNodeAndReference( pcn, pUaCalcItem,OpcUaId_HasComponent);
67 //
68 // UA_ASSERT(ret.isGood());
69 // }
70 //
71 // }
72 // else {
73 // uaId = m_pNodeManager->getNewNodeId(pcn, sName);
74 // pUaCalcItem = new UaCalcItem(sName,uaId,m_pNodeManager,dv,formul,whenCondition,statusCondition,pSharedMutex);
75 // dataValue.setDataValue(dv,OpcUa_False,OpcUa_BadWaitingForInitialData,UaDateTime::now(),UaDateTime::now());
76 // pUaCalcItem->setValue(0,dataValue,OpcUa_False);
77 // /*
78 // std::for_each(formul->sVariables.begin(),formul->sVariables.end(),[this,&ret,pUaCalcItem](std::string& str) {
79 // ret = CreateFormulaVariable(pUaCalcItem,str);
80 // UA_ASSERT(ret.isGood());
81 // } );
82 // */
83 // ucci->addTempItem(pUaCalcItem);
84 // if (pcn == NULL) {
85 // ret = m_pNodeManager->addNodeAndReference( OpcUaId_ObjectsFolder, pUaCalcItem,OpcUaId_HasComponent);
86 // }
87 // else
88 // ret = m_pNodeManager->addNodeAndReference( pcn, pUaCalcItem,OpcUaId_HasComponent);
89 //
90 // UA_ASSERT(ret.isGood());
91 // }
92 // }
93 // }
94 // }
95 // }
96 //
97 // for (unsigned int i = 0; i < m_vCCI.size(); i++)
98 // {
99 // UaStatus ret;
100 // ret = m_vCCI[i]->CreateLinks(m_pNodeManager);
101 // UA_ASSERT(ret.isGood());
102 // }
103 //
104 // return ret;
105 // }
106 //
107 // UaStatus UaCalcCompiler::createRegVariable(string *formul, mapDataVariable& pvariables,OpcUa::BaseObjectType *pcn, REGEXPR_sequence &regex, OpcUa_Int32 &minVar)
108 // {
109 // if (formul == 0) {
110 //
111 // return OpcUa_Good;
112 // }
113 // if (formul->hasVariables()) {
114 // OpcUa_Int32 nVar = 0;
115 //
116 // // scan throw the formula items to find the pattern
117 // for (vector<string>::iterator it = formul->sVariables.begin(); it != formul->sVariables.end(); it++) {
118 // UaControlVariableSet ucVariables;
119 // if (pvariables.find((*it)) == pvariables.end()) {
120 // CANBUS::REGEXPR_iterator r = find_if(regex.begin(), regex.end(), isName(*it));
121 // // CANBUS::REGEXPR_iterator r = regex.begin();
122 // /*
123 // while ( r != regex.end()) {
124 // if ((*r).name() == (*it)) break;
125 // r++;
126 // }
127 // */
128 //
129 // if (r == regex.end()) {
130 // LOG(Log::INF) << "Variable " << (*it) << " is not found!";
131 // cout << "Variable " << (*it) << " is not found!" << endl;
132 // return OpcUa_Bad;
133 // }
134 // nVar = m_pNodeManager->findUaVariables(pcn, (*r).value(), ucVariables);
135 // if (nVar == 0) {
136 // LOG(Log::INF) << "Variable " << (*it) << " is not defined!";
137 // cout << "Variable " << (*it) << " is not defined!" << endl;
138 // return OpcUa_Bad;
139 // }
140 // if (minVar > nVar) minVar = nVar; // minimum pattern result
141 // // if (pvariables.find((*it)) == pvariables.end())
142 // pvariables.insert(std::pair<string, UaControlVariableSet>((*it), ucVariables));
143 // }
144 // }
145 // }
146 // else
147 // minVar = 0;
148 // return OpcUa_Good;
149 // }
150 //
151 // void UaCalcCompiler::initCalculation()
152 // {
153 //
154 // for (unsigned int i = 0; i < m_vCCI.size(); i++)
155 // {
156 // UaCalcCompilerItem *uci = m_vCCI[i];
157 // uci->initCalculation();
158 // }
159 // }
160 //
161 // UaStatus UaCalcCompiler::CompileOneItem(string &name, REGEXPR_sequence &regex, ITEM_iterator &sit)
162 // {
163 // UaStatus ret = OpcUa_Good;
164 // /// compile the formula
165 // if (!formul->Compile(sit->value(),false)) {
166 // ret = OpcUa_Bad;
167 //
168 // return ret;
169 // }
170 // ucci->setFormula(formul);
171 // if (sit->when() != 0) {
172 // formul = new OpcUaFormula(); // create the whenCondition class
173 // if (!formul->Compile(sit->when().get(),true)) {
174 // ret = OpcUa_False;
175 // UA_ASSERT(ret.isGood());
176 // return ret;
177 // }
178 // ucci->setWhenCondition(formul);
179 // }
180 //
181 // if (sit->status() != 0) {
182 // formul = new OpcUaFormula(); // create the whenCondition class
183 // if (!formul->Compile(sit->status().get(),true)) {
184 // ret = OpcUa_False;
185 // UA_ASSERT(ret.isGood());
186 // return ret;
187 // }
188 // ucci->setStatusCondition(formul);
189 // }
190 //
191 // ret = addCalcCompilerItem(ucci);
193 // return ret;
194 // }
195 //
196 // UaStatus UaCalcCompiler::CompileItems(OpcUa::BaseObjectType *pParent,ITEM_sequence &itnd,REGEXPR_sequence &regex)
197 // {
198 // UaStatus ret = OpcUa_Good;
199 //
200 // for (ITEM_iterator sit=itnd.begin(); sit != itnd.end(); sit++)
201 // {
202 // OpcUaFormula *formul = new OpcUaFormula(); // create the formula class
203 // UaCalcCompilerItem * ucci = new UaCalcCompilerItem(sit->name(),pParent,regex);
204 // ret = CompileOneItem(formul,ucci,sit);
205 // if (ret.isBad())
206 // break;
207 // /*
208 // /// compile the formula
209 // if (!formul->Compile(sit->value(),false)) {
210 // ret = OpcUa_False;
211 // UA_ASSERT(ret.isGood());
212 // return ret;
213 // }
214 //
215 // ucci->setFormula(formul);
216 // if (sit->when() != 0) {
217 // formul = new OpcUaFormula(); // create the whenCondition class
218 // if (!formul->Compile(sit->when().get(),true)) {
219 // ret = OpcUa_False;
220 // UA_ASSERT(ret.isGood());
221 // return ret;
222 // }
223 // ucci->setWhenCondition(formul);
224 // }
225 //
226 // if (sit->status() != 0) {
227 // formul = new OpcUaFormula(); // create the whenCondition class
228 // if (!formul->Compile(sit->status().get(),true)) {
229 // ret = OpcUa_False;
230 // UA_ASSERT(ret.isGood());
231 // return ret;
232 // }
233 // ucci->setStatusCondition(formul);
234 // }
235 //
236 // m_vCCI.push_back(ucci);
237 // */
238 // }
239 // return ret;
240 // }
241 //
242 // UaStatus UaCalcCompiler::CompileItems(ITEM_sequence &itnd,REGEXPR_sequence &regex)
243 // {
244 // UaStatus ret = OpcUa_Good;
245 //
246 // for (ITEM_iterator sit=itnd.begin(); sit != itnd.end(); sit++)
247 // {
250 // ret = CompileOneItem(sit->name(), regex,sit);
251 // if (ret.isBad())
252 // break;
253 //
254 // /*
255 //
256 // /// compile the formula
257 // if (!formul->Compile(sit->value(),false)) {
258 // ret = OpcUa_False;
259 // UA_ASSERT(ret.isGood());
260 // exit(-1);
261 // }
262 //
263 // ucci->setFormula(formul);
264 // if (sit->when() != 0) {
265 // formul = new OpcUaFormula(); // create the whenCondition class
266 // if (!formul->Compile(sit->when().get(),true)) {
267 // ret = OpcUa_False;
268 // UA_ASSERT(ret.isGood());
269 // exit(-1);
270 // }
271 // ucci->setWhenCondition(formul);
272 // }
273 //
274 // if (sit->status() != 0) {
275 // formul = new OpcUaFormula(); // create the whenCondition class
276 // if (!formul->Compile(sit->status().get(),true)) {
277 // ret = OpcUa_False;
278 // UA_ASSERT(ret.isGood());
279 // exit(-1);
280 // }
281 // ucci->setStatusCondition(formul);
282 // }
283 //
284 // m_vCCI.push_back(ucci);
285 // */
286 // }
287 // return ret;
288 // }
289  UaCalcItem::UaCalcItem(const UaString &name, UaNodeId& uaId, const UaNode *parent,NmBuildingAutomation * pNodeConfig, UaVariant &dv, ITEM &citem, UaControlVariableMap &cvs, UaMutexRefCounted* pSharedMutex) :
290  UaControlVariable(name, uaId, pNodeConfig, dv, pSharedMutex), m_pNodeManager(pNodeConfig),m_pParent(parent)
291 
292 // UaCalcItem::UaCalcItem(const UaString &name,UaNodeId& uaId, NmBuildingAutomation * pNodeConfig, UaVariant &dv,string &formul,string &whenCondition,string &statusCondition,UaMutexRefCounted* pSharedMutex):
293 // UaControlVariable(name,uaId,pNodeConfig,dv,pSharedMutex), m_sFormul(formul), m_sWhenCondition(whenCondition), m_sStatusCondition(statusCondition),m_var(),m_whenVar(),m_statusVar()
294  {
295  int i = 0;
296 
297  string nname = citem.name();
298 
299  m_cExists = citem.when().present();
300  m_sFormul = citem.value();
301  m_fExists = true;
302  m_sExists = citem.status().present();
303 
304 // cout << "Create " << this->browseName().toString().toUtf8() << endl << flush;
305 
306  for (UaControlVariableMap::const_iterator vit = cvs.begin(); vit != cvs.end(); vit++)
307  {
308  string nn = (*vit).first;
309  UaControlVariable *uac = (*vit).second;
310 // cout << "Add Variable " << nn << " " << this->browseName().toString().toUtf8() << endl << flush;
311 
312  if (m_sFormul.find(nn) != string::npos)
313  pushDataVariable(nn, uac);
314  }
315  m_formul.EnableOptimizer(false);
316  m_formul.DefineConst("pi", M_PI);
317  m_formul.DefineConst("e", M_E);
318  m_formul.DefineFun("pow", PowFunc);
319 
320  m_formul.SetVarFactory(getValueFromItem, this);
321  m_formul.SetExpr(m_sFormul);
322 
323  if (m_cExists) {
324  m_sWhenCondition = citem.when().get();
325 
326  for (UaControlVariableMap::const_iterator vit = cvs.begin(); vit != cvs.end(); vit++)
327  {
328  string nn = (*vit).first;
329  UaControlVariable *uac = (*vit).second;
330  if (m_sWhenCondition.find(nn) != string::npos)
331  pushConditionVariable(nn, uac);
332  }
333  m_whenCondition.EnableOptimizer(false);
334  m_whenCondition.DefineConst("pi", M_PI);
335  m_whenCondition.DefineConst("e", M_E);
336  m_whenCondition.DefineFun("pow", PowFunc);
337 
338  m_whenCondition.SetVarFactory(getValueFromWhenItem, this);
339  m_whenCondition.SetExpr(m_sWhenCondition);
340  }
341 
342  if (m_sExists) {
343  m_sStatusCondition = citem.status().get();
344  for (UaControlVariableMap::const_iterator vit = cvs.begin(); vit != cvs.end(); vit++)
345  {
346  string nn = (*vit).first;
347  UaControlVariable *uac = (*vit).second;
348  if (m_sStatusCondition.find(nn) != string::npos)
349  pushStatusVariable(nn, uac);
350  }
351  m_statusFormula.EnableOptimizer(false);
352  m_statusFormula.DefineConst("pi", M_PI);
353  m_statusFormula.DefineConst("e", M_E);
354  m_statusFormula.DefineFun("pow", PowFunc);
355 
356  m_statusFormula.SetVarFactory(getValueFromStatusItem, this);
357  m_statusFormula.SetExpr(m_sStatusCondition);
358  }
359 // m_formul_table.add_constants();
360  setValueHandling(UaVariable_Value_CacheIsSource);
361  setUserData(NULL);
362  }
363 
364 /*
365  UaCalcItem::UaCalcItem(const UaString &name,UaNodeId& uaId, NmBuildingAutomation * pNodeConfig, UaVariant &dv,string formul,string whenCondition,string statusCondition,UaMutexRefCounted* pSharedMutex):
366  UaControlVariable(name,uaId,pNodeConfig,dv,pSharedMutex), m_sFormul(formul), m_sWhenCondition(whenCondition),m_sStatusCondition(statusCondition),m_var(),m_whenVar(),m_statusVar()
367  {
368 
369  setValueHandling(UaVariable_Value_CacheIsSource); //!< set change date by event
370  }
371 
372 */
373  void UaCalcItem::calculateOnChange(Session *pSession, const UaDataValue& dValue, OpcUa_Boolean checkAccessLevel)
374  {
375  boost::arg<1> _1;
376  UaDataValue dataValue;
377  UaDateTime udt, sdt;
378  UaStatus Status = OpcUa_Good;
379  OpcUa_StatusCode when_status;
380  OpcUa_StatusCode val_status;
381  OpcUa_StatusCode status_status;
382  mu::value_type res = 0.0;
383  mu::value_type cond = 0.0;
384  UaString sDiag;
385 // cout << "Start calc " << this->browseName().toString().toUtf8() << endl << flush;
386 
387  // TRACE1_DATA(SERVER_CORE, UA_T"<-- UaCalcItem::startCalculation %s",this->browseName().toString().toUtf8());
391  // m_formul->getValueFromItem = boost::bind(&AddressSpace::UaCalcItem::getValueFromItem,this,_1);
392 
393  if (m_cExists) {
394  // m_whenCondition->getValueFromItem = boost::bind(&AddressSpace::UaCalcItem::getValueFromWhenItem,this,_1);
395 // cout << "Conditions" << endl;
396  when_status = checkStatus(m_whenVar);
397  if (when_status != OpcUa_Good)
398  return;
399  cond = m_whenCondition.Eval();
400  if (cond < 1.0)
401  return;
402  }
403  try {
404  val_status = checkStatus(m_var);
405 // cout << "Main Block " << hex << val_status << endl << flush;
406  if (val_status != OpcUa_Good) {
407  sDiag = "Sensor is bad";
408  Status.setStatus(val_status, sDiag);
409 // cout << sDiag.toUtf8() << endl;
410  }
411  else {
412 
413  res = m_formul.Eval(); // calculation
414 // cout << "Result " << hex << res << endl;
415  if (m_sExists) {
416  status_status = checkStatus(m_statusVar);
417 // cout << "Status Status " << hex << status_status << endl << flush;
418  if (status_status != OpcUa_Good) {
419  sDiag = "Status sensor is bad";
420  Status.setStatus(status_status, sDiag);
421 // cout << sDiag.toUtf8() << endl;
422  }
423  else {
424  cond = m_statusFormula.Eval();
425 // cout << "Condition value " << cond << endl << flush;
426  if (cond < 1.0) {
427  sDiag = "Condition is false";
428  Status.setStatus(OpcUa_Bad, sDiag);
429 // cout << sDiag.toUtf8() << endl;
430  }
431  else {
432  sDiag = "OK";
433  Status.setStatus(OpcUa_Good, sDiag);
434 // cout << sDiag.toUtf8() << endl;
435  }
436  }
437  }
438  else {
439  sDiag = "OK";
440  Status.setStatus(OpcUa_Good, sDiag);
441 // cout << sDiag.toUtf8() << endl << flush;
442  }
443  }
444  }
445  catch (...)
446  {
447  sDiag = "Calculation Error";
448  Status.setStatus(OpcUa_BadUnexpectedError,sDiag);
449  }
450 
451  // TRACE1_DATA(SERVER_CORE, UA_T"<-- UaCalcItem::endCalculation %s",this->browseName().toString().toUtf8());
452  udt = dValue.sourceTimestamp();
453  sdt = UaDateTime::now();
454 
455  UaVariant val = res;
456 // if (Status.isGood()) {
457  if (isnan(res) || isinf(res)) {
458  dataValue.setDataValue(val, OpcUa_False, OpcUa_BadUnexpectedError, udt, sdt);
459  }
460  else
461  dataValue.setDataValue(val, OpcUa_False, Status.code(), udt, sdt);
462 
463 // cout << "Status Code final " << this->browseName().toString().toUtf8() << " " << hex << dataValue.statusCode() << endl << flush;
464  //}
465  //else
466  // if (Status.isNotGood())
467  // dataValue.setDataValue(val,OpcUa_False,Status.statusCode(),udt,sdt);
468  // else {
469  // sDiag = "Condition status error";
470  // Status.setStatus(OpcUa_BadDataEncodingInvalid, sDiag);
471  // dataValue.setDataValue(val, OpcUa_False, OpcUa_BadDataEncodingInvalid, udt, sdt);
472  // }
473 
474  Status = setValue(pSession, dataValue, checkAccessLevel);
475  }
476 
478  {
479  boost::arg<1> _1;
480  UaDataValue dataValue;
481  UaDateTime udt,sdt;
482  UaStatus Status = OpcUa_Good;
483  double res;
484  UaVariant val;
485 
490 // m_formul->getValueFromItem = boost::bind(&AddressSpace::UaCalcItem::getValueFromItem,this,_1);
491  calculateOnChange(0, dataValue, OpcUa_False);
492 
493  //try {
494  // res = m_formul.Eval(); // calculation
495  // val = res;
496  // udt = UaDateTime::now();
497  // sdt = UaDateTime::now();
498 
499  // if (isnan(res) || isinf(res)) {
500  // UaString sDiag = "Calculation Error";
501  // Status.setStatus(OpcUa_BadUnexpectedError, sDiag);
502  // }
503 
504  // dataValue.setDataValue(val, OpcUa_False, Status.statusCode(), udt, sdt);
505 
506  // Status = setValue(0, dataValue, OpcUa_False);
507  //}
508  //catch (...)
509  //{
510  // UaString sDiag = "No Initial Data";
511  // Status.setStatus(OpcUa_BadWaitingForInitialData, sDiag);
512 
513  //}
514 
515  }
516 
517 
518  /*
519  * Overload the virtual value() function to calculate data.
520  * when client read item it calculates the passes to client
521  * @param pSession ua-client session
522  UaDataValue UaCalcItem::value(Session* pSession)
523  {
524  boost::arg<1> _1; // boost placeholder for binding argument
525  UaDataValue dataValue;
526  UaDateTime udt,sdt;
527  UaStatus Status;
528 
532  TRACE1_DATA(SERVER_CORE, UA_T"<-- UaCalcItem::startCalculation %s",this->browseName().toString().toUtf8());
533  m_formul->getValueFromItem = boost::bind<double>(&AddressSpace::UaCalcItem::getValueFromItem,this,_1);
534 
535  double res = m_formul->eval(); // calculation
536 
537  TRACE1_DATA(SERVER_CORE, UA_T"<-- UaCalcItem::endCalculation %s",this->browseName().toString().toUtf8());
538  udt = UaGetSourceTimeStamp();
539  sdt = UaDateTime::now();
540 
541  UaVariant val = res;
542 
543  dataValue.setDataValue(val,OpcUa_False,OpcUa_Good,udt,sdt);
544  Status = setValue(0, dataValue, OpcUa_False);
545  return dataValue;
546  }
547  */
548 
556  {
557 // double res = 0.0;
558  UaCalcItem *uci = static_cast<UaCalcItem *>(pNode);
559  UaNodeId id = uci->m_pNodeManager->getNewNodeId(uci->m_pParent, ind);
560  UaControlVariable *ucv = dynamic_cast<UaControlVariable *>(uci->m_pNodeManager->findNode(id));
561  if (!ucv)
562  {
563  LOG(Log::INF) << "Variable " << ind << " is not found!";
564  exit(-1);
565  }
566  std::string nam = "$" + std::string(ind);
568 
569  uci->pushDataVariable(nam, ucv);
570  uci->convertToDouble(uci->value(0));
571 // variableSet::iterator vit = ((UaCalcItem*)pNode)->m_var.find(ind);
572 // if (vit != ((UaCalcItem*)pNode)->m_var.end() ) {
573 // vit->second->convertToDouble();
574 // }
575  return &ucv->curValue;
576  }
577 
578 
580  {
581 // double res = 0.0;
582 // variableSet::iterator vit = ((UaCalcItem*)pNode)->m_whenVar.find(ind);
583 // if (vit != ((UaCalcItem*)pNode)->m_whenVar.end() ) {
584 // vit->second->convertToDouble();
585 // }
586  UaCalcItem *uci = static_cast<UaCalcItem *>(pNode);
587  UaNodeId id = uci->m_pNodeManager->getNewNodeId(uci->m_pParent, ind);
588  UaControlVariable *ucv = dynamic_cast<UaControlVariable *>(uci->m_pNodeManager->findNode(id));
589  if (!ucv)
590  {
591  LOG(Log::INF) << "Variable " << ind << " is not found!";
592  exit(-1);
593  }
594  std::string nam = "$" + std::string(ind);
595 // std::replace(nam.begin(), nam.end(), '.', '_');
596  uci->pushConditionVariable(nam, ucv);
597  uci->convertToDouble(uci->value(0));
598  return &ucv->curValue;
599  }
600 
602  {
603 // double res = 0.0;
604 // variableSet::iterator vit = ((UaCalcItem*)pNode)->m_statusVar.find(ind);
605 // if (vit != ((UaCalcItem*)pNode)->m_statusVar.end() ) {
606 // vit->second->convertToDouble();
607 // }
608  UaCalcItem *uci = static_cast<UaCalcItem *>(pNode);
609  UaNodeId id = uci->m_pNodeManager->getNewNodeId(uci->m_pParent, ind);
610  UaControlVariable *ucv = dynamic_cast<UaControlVariable *>(uci->m_pNodeManager->findNode(id));
611  if (!ucv)
612  {
613  LOG(Log::INF) << "Variable " << ind << " is not found!";
614  exit(-1);
615  }
616  std::string nam = "$" + std::string(ind);
617 // std::replace(nam.begin(), nam.end(), '.', '_');
618  uci->pushStatusVariable(nam, ucv);
619  uci->convertToDouble(uci->value(0));
620  return &ucv->curValue;
621  }
622 
623  /*
624  double UaCalcItem::convertToDouble(variableSet::iterator &vit)
625  {
626  UaDataValue dataValue;
627  double res = 0.0;
628  dataValue = (*vit).second->value(0);
629  const OpcUa_Variant *val = dataValue.value();
630  switch (val->Datatype) {
631  case OpcUaType_Boolean:
632  res = val->Value.Boolean;
633  break;
634  case OpcUaType_SByte:
635  res = val->Value.SByte;
636  break;
637  case OpcUaType_Byte:
638  res = val->Value.Byte;
639  break;
640  case OpcUaType_Int16:
641  res = val->Value.Int16;
642  break;
643  case OpcUaType_UInt16:
644  res = val->Value.UInt16;
645  break;
646  case OpcUaType_Int32:
647  res = val->Value.Int32;
648  break;
649  case OpcUaType_UInt32:
650  res = val->Value.UInt32;
651  break;
652  case OpcUaType_Int64:
653  res = (double)val->Value.Int64;
654  break;
655  case OpcUaType_UInt64:
656  res = (double)val->Value.UInt64;
657  break;
658  case OpcUaType_Float:
659  res = val->Value.Float;
660  break;
661  case OpcUaType_Double:
662  res = val->Value.Double;
663  break;
664  default:
665 // throw 1;
666  res = 0.0;
667  };
668  return res;
669  }
670  */
674  /*
675  UaDateTime UaCalcItem::UaGetSourceTimeStamp()
676  {
677  UaDateTime udt=0,tudt;
678  UaDataValue dataValue;
679  for(variableSet::iterator vit = m_var.begin(); vit != m_var.end(); vit++ ) {
680  dataValue = (*vit).second->ucv->value(0);
681  tudt = dataValue.sourceTimestamp();
682  if (tudt > udt ) udt = tudt;
683  }
684  return udt;
685  }
686  */
687  //UaStatus UaCalcCompilerItem::findLinkToUaVariable(UaCalcItem *pcn,NmBuildingAutomation *pNodeManager,OpcUaFormula *formul,OpcUa_Int index,pushUaVariable puv)
688  //{
689 
690  // UaStatus ret = OpcUa_Good;
691  // if (formul) {
692  // for (operands_type_set::iterator it = formul->opt.begin(); it != formul->opt.end(); it++)
693  // {
694  // UaVariable* t_var;
695  // string stdName;
696  // UaString sName;
697  // UaNodeId uaId;
698  // if ((*it).which() == 3) {
699  // stdName = boost::get<std::string>((*it));
700  // sName = stdName.c_str();
701  // if (sName.at(0) == UaChar('$')) {
702  // if (isVariableMap(stdName))
703  // {
704  // UaControlVariableSet setOfVariable = getMapDataVariable().at(stdName);
705  // (pcn->*puv)(stdName, setOfVariable[index]);
706  // }
707  // else
708  // {
709  // ret = OpcUa_Bad;
710  // LOG(Log::INF) << "The variable is not defined " << stdName.c_str();
711  // UA_ASSERT(ret.isGood());
712  // return ret;
713  // }
714 
715  // }
716  // else {
717  // uaId = pNodeManager->getNewNodeId(getParentCalc(), sName);
718  // t_var = pNodeManager->getInstanceDeclarationVariable( uaId);
719  // if (t_var) {
720  // (pcn->*puv)(stdName,(UaControlVariable *)t_var);
721  // }
722  // else {
723  // uaId = pNodeManager->getNewNodeId(NULL, sName);
724  // t_var = pNodeManager->getInstanceDeclarationVariable( uaId);
725  // if (t_var) {
726  // (pcn->*puv)(stdName,(UaControlVariable *)t_var);
727  // }
728  // else {
729  // ret = OpcUa_Bad;
730  // LOG(Log::INF) << "Could not find the item " << stdName.c_str();
731  // UA_ASSERT(ret.isGood());
732  // return ret;
733  // }
734  // }
735  // }
736  // }
737  // }
738  // }
739  // return ret;
740  //}
741 
742  //UaStatus UaCalcCompilerItem::CreateLinks(NmBuildingAutomation *pNodeManager)
743  //{
744  // UaStatus ret;
745  // for (unsigned int i = 0; i < m_vCalcItem.size(); i++)
746  // {
747  // UaCalcItem *uci = m_vCalcItem[i];
748  // OpcUaFormula *formul = getFormula();
749  // OpcUaFormula *whenCondition = getWhenCondition();
750  // OpcUaFormula *statusCondition = getStatusCondition();
751 
752  // pushUaVariable puv = &UaCalcItem::pushDataVariable;
753  // ret = findLinkToUaVariable(uci,pNodeManager,formul,i,puv);
754  // UA_ASSERT(ret.isGood());
755  // if (ret.isBad())
756  // exit(-1);
757 
758  // puv = &UaCalcItem::pushConditionVariable;
759  // ret = findLinkToUaVariable(uci,pNodeManager,whenCondition,i,puv);
760  // UA_ASSERT(ret.isGood());
761  // if (ret.isBad())
762  // exit(-1);
763  //
764  // puv = &UaCalcItem::pushStatusVariable;
765  // ret = findLinkToUaVariable(uci,pNodeManager,statusCondition,i,puv);
766  // UA_ASSERT(ret.isGood());
767  // if (ret.isBad())
768  // exit(-1);
769 
770  // }
771  // return ret;
772  //}
773  //
774  //void UaCalcCompilerItem::initCalculation()
775  //{
776  // for (unsigned int i = 0; i < m_vCalcItem.size(); i++)
777  // {
778  // UaCalcItem *uci = m_vCalcItem[i];
779  // uci->initCalculation();
780  // }
781  //}
782 
783  //UaStatus UaCalcCompiler::addCalcCompilerItem(UaCalcCompilerItem *ucci)
784  //{
785  // UaStatus ret = OpcUa_Good;
786 
787  // m_vCCI.push_back(ucci);
788  // return ret;
789  //}
790 
791 }
792