node.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (C) 2014-2014 Olivier Roulet-Dubonnet *
3  * olivier.roulet@gmail.com *
4  * *
5  * This library is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU Lesser General Public License as *
7  * published by the Free Software Foundation; version 3 of the License. *
8  * *
9  * This library is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU Lesser General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU Lesser General Public License *
15  * along with this library; if not, write to the *
16  * Free Software Foundation, Inc., *
17  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18  ******************************************************************************/
19 
20 
21 #include <iostream>
22 
23 #include <opc/ua/node.h>
24 
29 
30 namespace OpcUa
31 {
32 
33 Node::Node(Services::SharedPtr srv)
34  : Node(srv, NumericNodeId(0, 0))
35 {
36 }
37 
38 Node::Node(Services::SharedPtr srv, const NodeId & id)
39  : Server(srv)
40  , Id(id)
41 {
42 }
43 
44 Node::Node(const Node & other)
45  : Server(other.Server)
46  , Id(other.Id)
47 {
48 }
49 
51 {
52  return Id;
53 }
54 
56 {
57  if (!Server)
58  {
59  return DataValue();
60  }
61 
62  ReadParameters params;
63  ReadValueId attribute;
64  attribute.NodeId = Id;
65  attribute.AttributeId = attr;
66  params.AttributesToRead.push_back(attribute);
67  std::vector<DataValue> vec = Server->Attributes()->Read(params);
68 
69  if (vec.size() > 0)
70  {
71  return vec.front();
72  }
73 
74  else
75  {
76  return DataValue(); //FIXME: What does it mean when not value is found?
77  }
78 }
79 
80 std::vector<Variant> Node::CallMethod(const NodeId methodId, const std::vector<Variant> inputArguments) const
81 {
82  std::vector<NodeId> vec_methodId;
83  vec_methodId.push_back(methodId);
84 
85  std::vector<std::vector<Variant>> vec_inputArguments;
86  vec_inputArguments.push_back(inputArguments);
87 
88  std::vector<std::vector<Variant>> results = CallMethods(vec_methodId, vec_inputArguments);
89 
90  return results.front();
91 }
92 
93 std::vector<std::vector<Variant>> Node::CallMethods(const std::vector<NodeId> methodIds, const std::vector<std::vector<Variant>> inputArguments) const
94 {
95  std::vector<CallMethodRequest> methodsToCall;
96 
97  std::vector<NodeId>::const_iterator it1;
98  std::vector<std::vector<Variant>>::const_iterator it2;
99 
100  for (it1 = methodIds.begin(), it2 = inputArguments.begin();
101  it1 != methodIds.end() && it2 != inputArguments.end();
102  ++it1, ++it2)
103  {
104  CallMethodRequest callMethod;
105  callMethod.ObjectId = Id;
106  callMethod.MethodId = *it1;
107  callMethod.InputArguments = *it2;
108 
109  methodsToCall.push_back(callMethod);
110  }
111 
112  std::vector<CallMethodResult> results = Server->Method()->Call(methodsToCall);
113 
114  std::vector<std::vector<Variant>> ret;
115 
116  for (std::vector<CallMethodResult>::iterator it = results.begin(); it != results.end(); ++it)
117  {
118  CheckStatusCode(it->Status);
119  ret.push_back(it->OutputArguments);
120  }
121 
122  return ret;
123 }
124 
125 void Node::SetAttribute(AttributeId attr, const DataValue & dval) const
126 {
127  WriteValue attribute;
128  attribute.NodeId = Id;
129  attribute.AttributeId = attr;
130  attribute.Value = dval;
131  std::vector<StatusCode> codes = Server->Attributes()->Write(std::vector<WriteValue>(1, attribute));
132  CheckStatusCode(codes.front());
133 }
134 
135 void Node::SetValue(const Variant & val) const
136 {
137  DataValue dval(val);
139 }
140 
141 void Node::SetValue(const DataValue & dval) const
142 {
144 }
145 
146 void Node::_GetChildren(const ReferenceId & refid, std::vector<Node>& nodes) const
147 {
149  description.NodeToBrowse = Id;
150  description.Direction = BrowseDirection::Forward;
151  description.IncludeSubtypes = true;
152  description.NodeClasses = NodeClass::Unspecified;
153  description.ResultMask = BrowseResultMask::All;
154  description.ReferenceTypeId = refid;
155 
156  NodesQuery query;
157  query.NodesToBrowse.push_back(description);
158  query.MaxReferenciesPerNode = 100;
159  std::vector<BrowseResult> results = Server->Views()->Browse(query);
160 
161  if (results.empty())
162  {
163  return;
164  }
165 
166  while (!results[0].Referencies.empty())
167  {
168  for (auto refIt : results[0].Referencies)
169  {
170  Node node(Server, refIt.TargetNodeId);
171  nodes.push_back(node);
172  }
173 
174  results = Server->Views()->BrowseNext();
175 
176  if (results.empty())
177  {
178  return;
179  }
180  }
181 }
182 
184 {
185  if (!Server) {
186  return Node();
187  }
189  description.NodeToBrowse = Id;
190  description.Direction = BrowseDirection::Inverse;
191  description.IncludeSubtypes = true;
192  description.NodeClasses = NodeClass::Unspecified;
193  description.ResultMask = BrowseResultMask::All;
195 
196  NodesQuery query;
197  query.NodesToBrowse.push_back(description);
198  query.MaxReferenciesPerNode = 100;
199  std::vector<BrowseResult> results = Server->Views()->Browse(query);
200 
201  if (results.empty())
202  {
203  return Node();
204  }
205  if (!results[0].Referencies.empty())
206  {
207  for (auto refIt : results[0].Referencies)
208  {
209  return Node(Server, refIt.TargetNodeId);
210  }
211  }
212  return Node();
213 }
214 
215 std::vector<Node> Node::GetChildren(const ReferenceId & refid) const
216 {
217  std::vector<Node> nodes;
218  _GetChildren(refid, nodes);
219  return nodes;
220 }
221 
222 std::vector<Node> Node::GetChildren() const
223 {
225 }
226 
228 {
230 
231  if (var.Type() != VariantType::QUALIFIED_NAME)
232  {
233  throw std::runtime_error("Could not retrieve browse name.");
234  }
235 
236  return var.As<QualifiedName>();
237 }
238 
239 std::vector<AddNodesResult> Node::AddNodes(std::vector<AddNodesItem> items) const
240 {
241  return Server->NodeManagement()->AddNodes(items);
242 }
243 
244 std::vector<StatusCode> Node::AddReferences(std::vector<AddReferencesItem> items) const
245 {
246  return Server->NodeManagement()->AddReferences(items);
247 }
248 
249 Node Node::GetChild(const std::string & browsename) const
250 {
251  return GetChild(std::vector<std::string>({browsename}));
252 }
253 
254 Node Node::GetChild(const std::vector<std::string> & path) const
255 {
256  std::vector<QualifiedName> vec;
257  uint16_t namespaceIdx = Id.GetNamespaceIndex();
258 
259  for (std::string str : path)
260  {
261  QualifiedName qname = ToQualifiedName(str, namespaceIdx);
262  namespaceIdx = qname.NamespaceIndex;
263  vec.push_back(qname);
264  }
265 
266  return GetChild(vec);
267 }
268 
269 
270 Node Node::GetChild(const std::vector<QualifiedName> & path) const
271 {
272  std::vector<RelativePathElement> rpath;
273 
274  for (QualifiedName qname : path)
275  {
277  el.TargetName = qname;
278  rpath.push_back(el);
279  }
280 
281  BrowsePath bpath;
282  bpath.Path.Elements = rpath;
283  bpath.StartingNode = Id;
284  std::vector<BrowsePath> bpaths;
285  bpaths.push_back(bpath);
287  params.BrowsePaths = bpaths;
288 
289  std::vector<BrowsePathResult> result = Server->Views()->TranslateBrowsePathsToNodeIds(params);
290  CheckStatusCode(result.front().Status);
291 
292  NodeId node = result.front().Targets.front().Node ;
293  return Node(Server, node);
294 }
295 
296 std::vector<Node> Node::GetProperties() const
297 {
298  std::vector<Node> result;
301  {
302  return result;
303  }
304  Node parent = GetParent();
305  while (!parent.GetId().IsNull()) {
306  if (parent.GetNodeClass() != NodeClass::ObjectType)
307  {
308  return result;
309  }
311  parent = parent.GetParent();
312  }
313  return result;
314 }
315 
317 {
318  std::ostringstream os;
319  os << "Node(" << Id << ")";
320  return os.str();
321 }
322 
323 Node Node::AddFolder(const std::string & nodeid, const std::string & browsename) const
324 {
325  NodeId node = ToNodeId(nodeid, this->Id.GetNamespaceIndex());
326  QualifiedName qn = ToQualifiedName(browsename, GetBrowseName().NamespaceIndex);
327  return AddFolder(node, qn);
328 }
329 
330 Node Node::AddFolder(uint32_t namespaceIdx, const std::string & name) const
331 {
332  NodeId nodeid = NumericNodeId(0, namespaceIdx);
333  QualifiedName qn = ToQualifiedName(name, namespaceIdx);
334  return AddFolder(nodeid, qn);
335 }
336 
337 Node Node::AddFolder(const NodeId & nodeid, const QualifiedName & browsename) const
338 {
339 
340  AddNodesItem item;
341  item.BrowseName = browsename;
342  item.ParentNodeId = this->Id;
343  item.RequestedNewNodeId = nodeid;
344  item.Class = NodeClass::Object;
347  ObjectAttributes attr;
348  attr.DisplayName = LocalizedText(browsename.Name);
349  attr.Description = LocalizedText(browsename.Name);
350  attr.WriteMask = 0;
351  attr.UserWriteMask = 0;
352  attr.EventNotifier = 0;
353  item.Attributes = attr;
354 
355  std::vector<AddNodesResult> addnodesresults = Server->NodeManagement()->AddNodes(std::vector<AddNodesItem>({item}));
356  AddNodesResult res = addnodesresults.front(); //This should always work
357  CheckStatusCode(res.Status);
358 
359  return Node(Server, res.AddedNodeId);
360 }
361 
362 Node Node::AddObject(const std::string & nodeid, const std::string & browsename) const
363 {
364  NodeId node = ToNodeId(nodeid, this->Id.GetNamespaceIndex());
365  QualifiedName qn = ToQualifiedName(browsename, GetBrowseName().NamespaceIndex);
366  return AddObject(node, qn);
367 }
368 
369 Node Node::AddObject(uint32_t namespaceIdx, const std::string & name) const
370 {
371  //FIXME: should default namespace be the onde from the parent of the browsename?
372  NodeId nodeid = NumericNodeId(0, namespaceIdx);
373  QualifiedName qn = ToQualifiedName(name, namespaceIdx);
374  return AddObject(nodeid, qn);
375 }
376 
377 Node Node::AddObject(const NodeId & nodeid, const QualifiedName & browsename) const
378 {
379  AddNodesItem item;
380  item.BrowseName = browsename;
381  item.ParentNodeId = this->Id;
382  item.RequestedNewNodeId = nodeid;
383  item.Class = NodeClass::Object;
386  ObjectAttributes attr;
387  attr.DisplayName = LocalizedText(browsename.Name);
388  attr.Description = LocalizedText(browsename.Name);
389  attr.WriteMask = 0;
390  attr.UserWriteMask = 0;
391  attr.EventNotifier = 0;
392  item.Attributes = attr;
393 
394  std::vector<AddNodesResult> addnodesresults = Server->NodeManagement()->AddNodes(std::vector<AddNodesItem>({item}));
395 
396  AddNodesResult res = addnodesresults.front(); //This should always work
397  CheckStatusCode(res.Status);
398 
399  return Node(Server, res.AddedNodeId);
400 }
401 
402 Node Node::AddVariable(uint32_t namespaceIdx, const std::string & name, const Variant & val) const
403 {
404  NodeId nodeid = NumericNodeId(0, namespaceIdx);
405  QualifiedName qn = ToQualifiedName(name, namespaceIdx);
406  return AddVariable(nodeid, qn, val);
407 }
408 
409 Node Node::AddVariable(const std::string & nodeid, const std::string & browsename, const Variant & val) const
410 {
411  NodeId node = ToNodeId(nodeid, this->Id.GetNamespaceIndex());
412  QualifiedName qn = ToQualifiedName(browsename, GetBrowseName().NamespaceIndex);
413  return AddVariable(node, qn, val);
414 }
415 
416 Node Node::AddVariable(const NodeId & nodeid, const QualifiedName & browsename, const Variant & val) const
417 {
419 
420  AddNodesItem item;
421  item.BrowseName = browsename;
422  item.ParentNodeId = this->Id;
423  item.RequestedNewNodeId = nodeid;
424  item.Class = NodeClass::Variable;
425  item.ReferenceTypeId = ReferenceId::HasComponent;
426  item.TypeDefinition = ObjectId::BaseDataVariableType;
427  VariableAttributes attr;
428  attr.DisplayName = LocalizedText(browsename.Name);
429  attr.Description = LocalizedText(browsename.Name);
430 
431  // this seems to be invalid - for WriteMask we have to use
432  // OpcUa::AttributeWriteMask enum
433  attr.WriteMask = (uint32_t)OpenFileMode::Read;
434  attr.UserWriteMask = (uint32_t)OpenFileMode::Read;
435 
436  attr.Value = val;
437  attr.Type = datatype;
438  attr.Rank = -1;
439  attr.Dimensions = val.Dimensions;
442  attr.MinimumSamplingInterval = 1;
443  attr.Historizing = 0;
444  item.Attributes = attr;
445 
446  std::vector<AddNodesResult> addnodesresults = Server->NodeManagement()->AddNodes(std::vector<AddNodesItem>({item}));
447 
448  AddNodesResult res = addnodesresults.front(); //This should always work
449  CheckStatusCode(res.Status);
450 
451  return Node(Server, res.AddedNodeId);
452 }
453 
454 
455 Node Node::AddProperty(uint32_t namespaceIdx, const std::string & name, const Variant & val) const
456 {
457  NodeId nodeid = NumericNodeId(0, namespaceIdx);
458  const QualifiedName & qname = ToQualifiedName(name, namespaceIdx);
459  return AddProperty(nodeid, qname, val);
460 }
461 
462 Node Node::AddProperty(const std::string & nodeid, const std::string & browsename, const Variant & val) const
463 {
464  NodeId node = ToNodeId(nodeid, this->Id.GetNamespaceIndex());
465  QualifiedName qn = ToQualifiedName(browsename, GetBrowseName().NamespaceIndex);
466  return AddProperty(node, qn, val);
467 }
468 
469 Node Node::AddProperty(const NodeId & nodeid, const QualifiedName & browsename, const Variant & val) const
470 {
471 
473 
474  AddNodesItem item;
475  item.BrowseName = browsename;
476  item.ParentNodeId = this->Id;
477  item.RequestedNewNodeId = nodeid;
478  item.Class = NodeClass::Variable;
479  item.ReferenceTypeId = ReferenceId::HasProperty;
480  item.TypeDefinition = ObjectId::PropertyType;
481  VariableAttributes attr;
482  attr.DisplayName = LocalizedText(browsename.Name);
483  attr.Description = LocalizedText(browsename.Name);
484  attr.WriteMask = 0;
485  attr.UserWriteMask = 0;
486  attr.Value = val;
487  attr.Type = datatype;
488  attr.Rank = 0;
489  attr.Dimensions = val.Dimensions;
492  attr.MinimumSamplingInterval = 0;
493  attr.Historizing = 0;
494  item.Attributes = attr;
495 
496  std::vector<AddNodesResult> addnodesresults = Server->NodeManagement()->AddNodes(std::vector<AddNodesItem>({item}));
497 
498  AddNodesResult res = addnodesresults.front(); //This should always work
499  CheckStatusCode(res.Status);
500 
501  return Node(Server, res.AddedNodeId);
502 
503 }
504 
505 Node Node::AddMethod(uint32_t namespaceIdx, const std::string & name, std::function<std::vector<OpcUa::Variant> (NodeId context, std::vector<OpcUa::Variant> arguments)> method) const
506 {
507  NodeId nodeid = NumericNodeId(0, namespaceIdx);
508  QualifiedName qn = ToQualifiedName(name, namespaceIdx);
509  return AddMethod(nodeid, qn, method);
510 }
511 
512 Node Node::AddMethod(const std::string & nodeid, const std::string & browsename, std::function<std::vector<OpcUa::Variant> (NodeId context, std::vector<OpcUa::Variant> arguments)> method) const
513 {
514  NodeId node = ToNodeId(nodeid, this->Id.GetNamespaceIndex());
515  QualifiedName qn = ToQualifiedName(browsename, GetBrowseName().NamespaceIndex);
516  return AddMethod(node, qn, method);
517 }
518 
519 Node Node::AddMethod(const NodeId & nodeid, const QualifiedName & browsename, std::function<std::vector<OpcUa::Variant> (NodeId context, std::vector<OpcUa::Variant> arguments)> method) const
520 {
521  AddNodesItem item;
522  item.BrowseName = browsename;
523  item.ParentNodeId = this->Id;
524  item.RequestedNewNodeId = nodeid;
525  item.Class = NodeClass::Method;
527  //item.TypeDefinition = ObjectId::BaseDataVariableType;
528  MethodAttributes attr;
529  attr.DisplayName = LocalizedText(browsename.Name);
530  attr.Description = LocalizedText(browsename.Name);
531  attr.WriteMask = 0;
532  attr.UserWriteMask = 0;
533  attr.Executable = true;
534  attr.UserExecutable = true;
535  item.Attributes = attr;
536 
537  std::vector<AddNodesResult> addnodesresults = Server->NodeManagement()->AddNodes(std::vector<AddNodesItem>({item}));
538 
539  AddNodesResult res = addnodesresults.front(); //This should always work
540  CheckStatusCode(res.Status);
541  Server->Method()->SetMethod(res.AddedNodeId, method);
542 
543  return Node(Server, res.AddedNodeId);
544 }
545 
546 
547 
549 {
551 }
552 
554 {
556 }
557 
559 {
561 }
562 
563 } // namespace OpcUa
564 
565 
566 std::ostream & OpcUa::operator<<(std::ostream & os, const Node & node)
567 {
568  os << node.ToString();
569  return os;
570 }
571 
std::string ToString() const
Definition: node.cpp:316
std::vector< OpcUa::ReadValueId > AttributesToRead
std::vector< Node > GetChildren() const
Get ghildren by hierarchal referencies.
Definition: node.cpp:222
uint32_t GetNamespaceIndex() const
Definition: nodeid.cpp:118
void CheckStatusCode(StatusCode code)
OpcUa Error codes. GNU LGPL.
QualifiedName GetBrowseName() const
Definition: node.cpp:227
DataValue GetDataValue() const
Definition: node.cpp:553
Variant GetDataType() const
Definition: node.cpp:558
Node AddVariable(const NodeId &variableId, const QualifiedName &browsename, const Variant &val) const
Definition: node.cpp:416
Node AddMethod(const NodeId &variableId, const QualifiedName &browsename, std::function< std::vector< OpcUa::Variant >(NodeId context, std::vector< OpcUa::Variant > arguments)> method) const
Definition: node.cpp:519
std::vector< BrowseDescription > NodesToBrowse
Definition: protocol/view.h:50
std::vector< StatusCode > AddReferences(std::vector< AddReferencesItem > items) const
Definition: node.cpp:244
Node AddFolder(const NodeId &folderId, const QualifiedName &browseName) const
Definition: node.cpp:337
std::vector< BrowsePath > BrowsePaths
std::vector< OpcUa::Variant > InputArguments
OpcUa::Services::SharedPtr Server
Definition: node.h:165
std::vector< AddNodesResult > AddNodes(std::vector< AddNodesItem > items) const
Definition: node.cpp:239
boost::any Value
Definition: variant.h:160
std::vector< Node > GetProperties() const
Definition: node.cpp:296
uint16_t NamespaceIndex
Definition: types.h:73
name
Definition: setup.py:38
void SetAttribute(AttributeId attr, const DataValue &dval) const
Definition: node.cpp:125
NodeId GetId() const
Definition: node.cpp:50
bool IsNull() const
Definition: nodeid.cpp:375
ObjectId VariantTypeToDataType(VariantType vt)
description
Definition: setup.py:43
const char * datatype()
ObjectId
Definition: object_ids.h:12
Node()
Definition: node.h:49
std::vector< RelativePathElement > Elements
Definition: types.h:125
RelativePath Path
VariantType Type() const
OPC UA Address space part. GNU LGPL.
DataValue GetAttribute(const AttributeId attr) const
Definition: node.cpp:55
NodeId Id
Definition: node.h:166
Node AddObject(const NodeId &folderId, const QualifiedName &browseName) const
Definition: node.cpp:377
std::vector< uint32_t > Dimensions
Definition: variant.h:163
void _GetChildren(const OpcUa::ReferenceId &refid, std::vector< Node > &nodes) const
Definition: node.cpp:146
Node GetChild(const std::vector< OpcUa::QualifiedName > &path) const
Definition: node.cpp:270
std::vector< std::vector< Variant > > CallMethods(std::vector< NodeId > methodIds, std::vector< std::vector< Variant >> inputArguments) const
Definition: node.cpp:93
Variant GetValue() const
Definition: node.cpp:548
QualifiedName ToQualifiedName(const std::string &str, uint32_t default_ns=0)
Node GetParent() const
Definition: node.cpp:183
std::vector< Variant > CallMethod(NodeId methodId, std::vector< Variant > inputArguments) const
Definition: node.cpp:80
BrowseResultMask ResultMask
Definition: protocol/view.h:41
A Node object represent an OPC-UA node. It is high level object intended for developper who want to e...
Definition: node.h:42
std::string Name
Definition: types.h:74
NodeId ToNodeId(const std::string &str, uint32_t defaultNamespace=0)
uint32_t MaxReferenciesPerNode
Definition: protocol/view.h:49
BrowseDirection Direction
Definition: protocol/view.h:37
void SetValue(const Variant &val) const
Definition: node.cpp:135
std::ostream & operator<<(std::ostream &os, const Node &node)
Definition: node.cpp:566
OpcUa::AttributeId AttributeId
NodeClass GetNodeClass() const
Definition: node.h:105
OpcUa::DataValue Value
T As() const
Definition: variant.h:271
NodeId NumericNodeId(uint32_t value, uint16_t namespaceIndex=0)
Definition: nodeid.h:218
std::vector< uint32_t > Dimensions
OpcUa::NodeId NodeId
OpcUa::NodeId NodeId
Node AddProperty(const NodeId &propertyId, const QualifiedName &browsename, const Variant &val) const
Definition: node.cpp:469
OpcUa::AttributeId AttributeId
QualifiedName TargetName
Definition: types.h:120


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Tue Jan 19 2021 03:12:06