OpcUaCanOpen
CANopen OPC-UA server
NmBuildingAutomation.cpp
Go to the documentation of this file.
1 //#include "BuildingAutomationTypeIds.h"
2 #include "NmBuildingAutomation.h"
3 #include "variablehandleuanode.h"
4 #include <opcua_dataitemtype.h>
5 #include "UaCanBusObject.h"
7 #include "UaControlDeviceItem.h"
8 #include "UaDeviceNodeType.h"
9 #include "UaCanNodeObject.h"
10 //#include "CanOpenConfigXML.h"
11 #include "srvtrace.h"
12 #include "UaDeviceNodeType.h"
13 #include "uadatetime.h"
14 #include "ControlInterface.h"
15 #include "opcua_builtintypes.h"
16 #include "CanOpenItem.h"
17 
18 #include <map>
19 #include <boost/xpressive/xpressive.hpp>
20 
21 using namespace std;
22 using namespace UserDevice;
23 
24 namespace AddressSpace
25 {
26 
32  NmBuildingAutomation::NmBuildingAutomation(shared_ptr<UserDevice::ControlInterface> conInterf,const UaString nameOfServer): NodeManagerBase(nameOfServer)
33  {
34  m_pControlInterface = conInterf;
35  }
36 
40  UaNodeId NmBuildingAutomation::getNewNodeId(const UaNode *pNode, const UaString name)
41  {
42  UaNodeId uNodeId;
43  UaString nTmp;
44 
45  if ((pNode != NULL) && (pNode->nodeId().identifierType() == OpcUa_IdentifierType_String)) {
46  nTmp = UaString("%1.%2").arg(pNode->nodeId().toString()).arg(name);
47  }
48  else
49  nTmp = name;
50  OpcUa_Int16 nidx = getNameSpaceIndex();
51  uNodeId = UaNodeId(nTmp,nidx);
52  return uNodeId;
53  }
54 
58  UaNodeId NmBuildingAutomation::getTopNodeId(const UaNode *pNode) const
59  {
60  UaNodeId uNodeId;
61  char buffer[1024];
62  string nTmp = pNode->nodeId().toString().toUtf8();
63  int nbus = nTmp.copy(buffer, nTmp.find_first_of('.'),0);
64  buffer[nbus] = '\0';
65  UaString bus = UaString(buffer);
66  uNodeId = UaNodeId(bus,getNameSpaceIndex());
67  return uNodeId;
68  }
69 
70  UaNode* NmBuildingAutomation::getUpNode(const UaNode *pNode) const
71  {
72  UaNodeId uNodeId;
73  string buffer;
74  string nTmp = pNode->nodeId().toString().toUtf8();
75  int lastpos = nTmp.find_last_of('.');
76  buffer = nTmp.substr(0,lastpos);
77  UaString sNode = UaString(buffer.c_str());
78 
79  uNodeId = UaNodeId(sNode,getNameSpaceIndex());
80  return findNode(uNodeId);
81  }
82 
87  {
88  }
89 
94  {
95  UaStatus ret = OpcUa_Good;
96 /*
97  ret = m_pControlInterface->CreateAddressSpace(this);
98  UA_ASSERT(ret.isGood());
99  if (ret.isGood())
100  ret = m_pControlInterface->initialize();
101 */
102  return ret;
103 
104  }
105 
106  //UaVariable* NmBuildingAutomation::getInstanceDeclarationVariable(const UaString name)
107  //{
108  // // Try to find the instance declaration node with the numeric identifier
109  // // and the namespace index of this node manager
110  // UaNode* pNode = findNode(UaNodeId(name, getNameSpaceIndex()));
111  // if (pNode != NULL) {
112  // int t = pNode->nodeClass();
113  // if (t == OpcUa_NodeClass_Variable)
114  // {
115  // // Return the node if valid and a variable
116  // return static_cast<UaVariable*>(pNode);
117  // }
118  // }
119 
120  // return NULL;
121  //}
122 
123  //UaVariable* NmBuildingAutomation::getInstanceDeclarationVariable(const UaNodeId &uanid)
124  //{
125  // // Try to find the instance declaration node with the numeric identifier
126  // // and the namespace index of this node manager
127  // UaNode* pNode = findNode(uanid);
128  // if (pNode != NULL) {
129  // int t = pNode->nodeClass();
130  // if (t == OpcUa_NodeClass_Variable)
131  // {
132  // // Return the node if valid and a variable
133  // }
134  // return static_cast<UaVariable*>(pNode);
135  // }
136  // return NULL;
137  //}
138 
139 
140  //UaVariable* NmBuildingAutomation::getInstanceDeclarationVariable(OpcUa_UInt32 numericIdentifier)
141  //{
142  // // Try to find the instance declaration node with the numeric identifier
143  // // and the namespace index of this node manager
144  // UaNode* pNode = findNode(UaNodeId(numericIdentifier, getNameSpaceIndex()));
145  // if (pNode != NULL) {
146  // int t = pNode->nodeClass();
147  // if (t == OpcUa_NodeClass_Variable)
148  // {
149  // // Return the node if valid and a variable
150  // return static_cast<UaVariable*>(pNode);
151  // }
152  // }
153  // return NULL;
154  //}
155 /*
156  UaObject* NmBuildingAutomation::getInstanceDeclarationObjectType(OpcUa_UInt32 numericIdentifier)
157  {
158  // Try to find the instance declaration node with the numeric identifier
159  // and the namespace index of this node manager
160  UaNode* pNode = findNode(UaNodeId(numericIdentifier, getNameSpaceIndex()));
161 
162  if (pNode != NULL) {
163  int t = pNode->nodeClass();
164  if (t == OpcUa_NodeClass_ObjectType)
165  {
166  // Return the node if valid and a variable
167  return (UaObject*)pNode;
168  }
169  }
170  return NULL;
171  }
172 */
173 // template<typename X>
174 // X* NmBuildingAutomation::getInstanceDeclaration(OpcUa_UInt32 numericIdentifier)
175  //{
176  // // Try to find the instance declaration node with the numeric identifier
177  // // and the namespace index of this node manager
178  // X* pNode = dynamic_cast<X *>(indNode(UaNodeId(numericIdentifier, getNameSpaceIndex())));
179  // return X;
180  //if (pNode != nullptr) {
181  // retu
182  // int t = pNode->nodeClass();
183  // switch (t)
184  // if (t == OpcUa_NodeClass_ObjectType)
185  // {
186  // case OpcUa_NodeClass_ObjectType:
187  // // Return the node if valid and a variable
188  // return dynamic_cast<UaObjectType*>(pNode);
189  // case OpcUa_NodeClass_Variable:
190  // // Return the node if valid and a variable
191  // return dynamic_cast<UaVariable*>(pNode);
192  // case OpcUa_NodeClass_Object:
193  // // Return the node if valid and a variable
194  // return dynamic_cast<UaObject*>(pNode);
195  // case OpcUa_NodeClass_Method:
196  // // Return the node if valid and a variable
197  // return dynamic_cast<UaMethod*>(pNode);
198 
199  // }
200  //}
201  //return nullptr;
202  //}
203 
205  {
206  UaStatus ret;
207 // delete m_pControlInterface;
208  return ret;
209  }
210 
211  //UaObject* NmBuildingAutomation::getInstanceDeclarationObject(OpcUa_UInt32 numericIdentifier)
212  //{
213  // // Try to find the instance declaration node with the numeric identifier
214  // // and the namespace index of this node manager
215  // UaNode* pNode = findNode(UaNodeId(numericIdentifier, getNameSpaceIndex()));
216  // if (pNode != NULL) {
217  // int t = pNode->nodeClass();
218  // if (t == OpcUa_NodeClass_Object)
219  // {
220  // // Return the node if valid and a variable
221  // return (UaObject*)pNode;
222  // }
223  // }
224  // return NULL;
225  //}
226 
227 
228  //UaMethod* NmBuildingAutomation::getInstanceDeclarationMethod(OpcUa_UInt32 numericIdentifier)
229  //{
230  // // Try to find the instance declaration node with the numeric identifier
231  // // and the namespace index of this node manager
232  // UaNode* pNode = findNode(UaNodeId(numericIdentifier, getNameSpaceIndex()));
233  // if ( (pNode != NULL) && (pNode->nodeClass() == OpcUa_NodeClass_Method) )
234  // {
235  // // Return the node if valid and a variable
236  // return (UaMethod*)pNode;
237  // }
238  // else
239  // {
240  // return NULL;
241  // }
242  //}
243 
244  UaStatus NmBuildingAutomation::readValues(const UaVariableArray &arrUaVariables, UaDataValueArray &arrDataValues)
245  {
246  UaStatus ret = OpcUa_Good;
247  OpcUa_UInt32 i;
248  OpcUa_UInt32 count = arrUaVariables.length();
249  UaDateTime timeStamp = UaDateTime::now();
250 
251  // Create result array
252  arrDataValues.create(count);
253 
254  for (i=0; i<count; i++)
255  {
256  // Set time stamps
257  arrDataValues[i].setServerTimestamp(timeStamp);
258  UaVariable* pVariable = arrUaVariables[i];
259  if (pVariable)
260  {
261  UaNodeId uu = pVariable->typeDefinitionId();
262 
263  if (m_pControlInterface->isTraceVariable(pVariable->nodeId()) || !m_pControlInterface->isDeviceVariable(uu))
264  {
265  arrDataValues[i] = pVariable->value(0);
266  }
267  else
268  {
269  ret = ((UaControlDeviceItem *)pVariable)->read();
270  arrDataValues[i] = pVariable->value(0);
271  arrDataValues[i].setStatusCode(ret.statusCode());
272  }
273  }
274  }
275  return ret;
276  }
277 
278  UaStatus NmBuildingAutomation::writeValues(const UaVariableArray &arrUaVariables, const PDataValueArray &arrpDataValues, UaStatusCodeArray &arrStatusCodes)
279  {
280  UaStatus gret = OpcUa_Good,ret = OpcUa_Good;
281  OpcUa_UInt32 i;
282 
283  OpcUa_UInt32 count = arrUaVariables.length();
284 
285  // Create result array
286  arrStatusCodes.create(count);
287 
288  for (i=0; i<count; i++)
289  {
290  UaVariable* pVariable = arrUaVariables[i];
291  if (pVariable)
292  {
296 
297  if (m_pControlInterface->isTraceVariable(pVariable->nodeId())) {
298  pVariable->setValue(0,*arrpDataValues[i] ,false);
299  m_pControlInterface->putTraceFunctions(arrpDataValues[i]);
300  }
301  else {
302 
306  OpcUa_BuiltInType cvtype = (OpcUa_BuiltInType)pVariable->dataType().identifierNumeric();
307  OpcUa_Variant tData,sData;
308 
309  OpcUa_DataValue dValue = *arrpDataValues[i];
310  sData = dValue.Value;
311 
312  if (CanOpen::CanOpenItem::convertOpcUaType(&sData, &tData, cvtype).isGood()) {
313  UaDataValue udttmp;
314  dValue.Value = tData;
315  udttmp = dValue;
316  pVariable->setValue(0, udttmp, false);
317  udttmp = pVariable->value(0);
318  ((UaControlVariable *)pVariable)->write(udttmp);
319  }
320  else {
321  arrStatusCodes[i] = OpcUa_BadDataEncodingInvalid;
322 
323 
324  }
325 
326  }
327  }
328  }
329 
330  return gret;
331  }
332 
333 
339  IOManager* NmBuildingAutomation::getIOManager(UaNode* pUaNode, OpcUa_Int32 attributeId) const
340  {
341  IOManager *iom = m_pControlInterface->getIOManager(pUaNode,attributeId);
342  if (iom == NULL)
343  iom = NodeManagerBase::getIOManager(pUaNode,attributeId);
344  return iom;
345 
346  }
347 
355  VariableHandle* NmBuildingAutomation::getVariableHandler(Session* session, VariableHandle::ServiceType serviceType, OpcUa_NodeId *nodeid, OpcUa_Int32 attributeId)
356  {
357  UaNodeId t_uanodeid;
358 
359  if ( (nodeid == NULL) || (nodeid->NamespaceIndex != m_nNamespaceIndex) )
360  {
361  return NULL;
362  }
363  VariableHandle* pVariableHandle = NULL;
364  pVariableHandle = m_pControlInterface->getVariableHandler(session, serviceType, nodeid, attributeId);
365  if (pVariableHandle == NULL)
366  pVariableHandle = NodeManagerBase::getVariableHandle(session,serviceType,nodeid,attributeId);
367 /*
368  VariableHandle* pVariableHandle = NULL;
369  if ( attributeId == OpcUa_Attributes_Value )
370  {
371  OpcUa_UInt32 idt;
372  // The value attribute is requested - we are using the IOManager
373  UaNode *pUaNode = findNode(*nodeid);
374  UaNodeId id = pUaNode->typeDefinitionId();
375  if (id.identifierType() == OpcUa_IdentifierType_Numeric) {
376  idt = id.identifierNumeric();
377  if (idt == Ba_SDOType_Item ||
378  idt == Ba_SDOType1_Item ||
379  idt == Ba_SDOType2_Item ||
380  idt == Ba_SDOType3_Item
381  )
382  {
383  pVariableHandle = new VariableHandleUaNode;
384  t_uanodeid = getCanNodeNodeId(pUaNode);
385  UaNode *pParNode = findNode(t_uanodeid);
386  pVariableHandle->m_pIOManager = ((UaCanNodeObject *)pParNode)->getSDOIOManager();
387  pVariableHandle->m_AttributeID = attributeId;
388  ((VariableHandleUaNode *)pVariableHandle)->setUaNode(pUaNode);
389  }
390  else {
391  if (idt == Ba_PDOType_Item)
392  {
393  if (((UaVariable *)pUaNode)->accessLevel() == Ua_AccessLevel_CurrentWrite) {
394  pVariableHandle = new VariableHandleUaNode;
395  t_uanodeid = getTopNodeId(pUaNode);
396  UaNode *pTopNode = findNode(t_uanodeid);
397  pVariableHandle->m_pIOManager = ((UaCanBusObject *)pTopNode)->getPDOIOManager();
398  pVariableHandle->m_AttributeID = attributeId;
399  ((VariableHandleUaNode *)pVariableHandle)->setUaNode(pUaNode);
400  }
401  else
402  pVariableHandle = NodeManagerBase::getVariableHandle(session,serviceType,nodeid,attributeId);
403  }
404  }
405  }
406  }
407  else
408 
409  pVariableHandle = NodeManagerBase::getVariableHandle(session,serviceType,nodeid,attributeId);
410  */
411  return pVariableHandle;
412  }
413 
420  OpcUa_Int32 NmBuildingAutomation::findUaVariables(const OpcUa::BaseObjectType *pParObj,string& pattern,UaControlVariableSet& storage)
421  {
422  OpcUa_Int32 nMatched = 0;
423  UaReference *pRefList = (UaReference *)pParObj->pTargetNodes();
424  UaString fPatten = UaString("%1.%2").arg(pParObj->getKey().toString()).arg(pattern.c_str());
425  string fullpatten = fPatten.toUtf8();
426  while (pRefList) {
427  nMatched = nMatched + findUaNodeVariables(pRefList->pTargetNode(),fullpatten,storage);
428  pRefList = pRefList->pNextForwardReference();
429  }
430  return nMatched;
431  }
432 
439  OpcUa_Int32 NmBuildingAutomation::findUaNodeVariables(UaNode *pNode,string & pattern,UaControlVariableSet& storage)
440  {
441  OpcUa_Int32 nMatched = 0;
442  boost::xpressive::sregex expression = boost::xpressive::sregex::compile(pattern);
443 
444  if (pNode->nodeClass() == OpcUa_NodeClass_Variable) {
445  UaNodeId nodeid = pNode->getKey();
446  if (nodeid.identifierType() == OpcUa_IdentifierType_String) {
447  boost::xpressive::smatch what;
448  string sName = nodeid.toString().toUtf8();
449  if (boost::xpressive::regex_match(sName,what,expression)) {
450  nMatched = 1;
451  storage.push_back((UaControlVariable *)pNode);
452  }
453  }
454  }
455  else {
456  if (pNode->nodeClass() == OpcUa_NodeClass_Object) {
457  UaReference *pRefList = (UaReference *)pNode->getUaReferenceLists()->pTargetNodes();
458  while (pRefList) {
459  nMatched = nMatched + findUaNodeVariables(pRefList->pTargetNode(),pattern,storage);
460  pRefList = pRefList->pNextForwardReference();
461  }
462  }
463  }
464  return nMatched;
465  }
466 
467 }