model_object.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (C) 2013-2014 by Alexander Rykovanov *
3  * rykovanov.as@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 #include "model_impl.h"
21 
22 #include <opc/ua/model.h>
23 
24 namespace OpcUa
25 {
26 namespace Model
27 {
28 
29 Object::Object(NodeId objectId, Services::SharedPtr services)
30  : Node(services)
31 {
32  Id = objectId;
33  ReadParameters attrs;
34  attrs.AttributesToRead.push_back(ToReadValueId(objectId, AttributeId::DisplayName));
35  attrs.AttributesToRead.push_back(ToReadValueId(objectId, AttributeId::BrowseName));
36  std::vector<DataValue> values = services->Attributes()->Read(attrs);
37  DisplayName = values[0].Value.As<LocalizedText>();
38  BrowseName = values[1].Value.As<QualifiedName>();
39 }
40 
42  : Node(std::move(object.OpcUaServices))
43 {
44  Id = std::move(object.Id);
47 }
48 
49 Object::Object(const Object & object)
50  : Node(object.OpcUaServices)
51 {
52  Id = object.Id;
53  DisplayName = object.DisplayName;
54  BrowseName = object.BrowseName;
55 }
56 
57 Object::Object(Services::SharedPtr services)
58  : Node(services)
59 {
60 }
61 
63 {
65 }
66 
67 std::vector<Variable> Object::GetVariables() const
68 {
69  return Browse<Variable>(GetId(), NodeClass::Variable, GetServices());
70 }
71 
73 {
76  element.IncludeSubtypes = true;
77  element.TargetName = name;
78 
80  path.Elements.push_back(element);
81  return GetVariable(path);
82 }
83 
84 Variable Object::GetVariable(const RelativePath & relativePath) const
85 {
86  OpcUa::BrowsePath browsePath;
87  browsePath.StartingNode = GetId();
88  browsePath.Path = relativePath;
90  params.BrowsePaths.push_back(browsePath);
91  const std::vector<OpcUa::BrowsePathResult> & result = GetServices()->Views()->TranslateBrowsePathsToNodeIds(params);
92 
93  if (result.size() != 1)
94  { throw std::runtime_error("object_model| Server returned more than one browse paths on TranslateBrowsePathsToNodeIds request."); }
95 
96  const OpcUa::BrowsePathResult & resultPath = result.back();
97  OpcUa::CheckStatusCode(resultPath.Status);
98 
99  if (resultPath.Targets.size() != 1)
100  { throw std::runtime_error("object_model| Server returned too many target elements on TranslateBrowsePathsToNodeIds request."); }
101 
102  return Variable(resultPath.Targets.back().Node, GetServices());
103 }
104 
105 
106 std::vector<Object> Object::GetObjects() const
107 {
108  return Browse<Object>(GetId(), NodeClass::Object, GetServices());
109 }
110 
112 {
113  return Object(ObjectId::Null, GetServices());
114 }
115 
117 {
118  return Object(ObjectId::Null, GetServices());
119 }
120 
121 Object Object::CreateObject(const ObjectType & type, const QualifiedName & browseName)
122 {
123  return CreateObject(NodeId(), type, browseName);
124 }
125 
126 Object Object::CreateObject(const NodeId & newNodeId, const ObjectType & nodeType, const QualifiedName & browseName)
127 {
128  return CreateObject(newNodeId, GetId(), nodeType.GetId(), browseName, browseName.Name);
129 }
130 
131 Object Object::CreateObject(const ObjectType & type, const QualifiedName & browseName, const std::string & displayName)
132 {
133  return CreateObject(NodeId(), GetId(), type.GetId(), browseName, displayName);
134 }
135 
136 Object Object::CreateObject(const NodeId & newNodeId, const NodeId & parentNode, const NodeId & typeId, const QualifiedName & browseName, const std::string & displayName)
137 {
138  Object object(GetServices());
139  object.Id = InstantiateType(newNodeId, parentNode, typeId, NodeClass::Object, browseName, displayName);
140  object.BrowseName = browseName;
141  object.DisplayName = LocalizedText(displayName);
142  return object;
143 
144 }
145 
146 NodeId Object::InstantiateType(const NodeId & newNodeId, const NodeId & parentNode, const NodeId & typeId, NodeClass nodeClass, const QualifiedName & browseName, const std::string & displayName)
147 {
148  // Creating new node for object
149  AddNodesItem newNodeRequest;
150  newNodeRequest.BrowseName = browseName;
151  newNodeRequest.RequestedNewNodeId = newNodeId;
152  newNodeRequest.Class = nodeClass;
153  newNodeRequest.ParentNodeId = parentNode;
155  newNodeRequest.TypeDefinition = typeId;
156  ObjectAttributes attrs;
157  attrs.Description = LocalizedText(displayName);
158  attrs.DisplayName = LocalizedText(displayName);
159  newNodeRequest.Attributes = attrs;
160 
161  NodeManagementServices::SharedPtr nodes = GetServices()->NodeManagement();
162  std::vector<AddNodesResult> newObjectNode = nodes->AddNodes({newNodeRequest});
163 
164  if (newObjectNode.size() != 1)
165  {
166  throw std::runtime_error("opcua_model| Server returned wrong number new nodes results.");
167  }
168 
169  OpcUa::CheckStatusCode(newObjectNode[0].Status);
170 
171  std::map<NodeId, std::vector<ReferenceDescription>> nextRefs;
172  nextRefs.insert({newObjectNode[0].AddedNodeId, BrowseObjectsAndVariables(typeId)});
173 
174  while (!nextRefs.empty())
175  {
176  std::map<NodeId, std::vector<ReferenceDescription>> newRefs;
177 
178  for (auto idRefs : nextRefs)
179  {
180  std::map<NodeId, std::vector<ReferenceDescription>> tmpRefs = CopyObjectsAndVariables(idRefs.first, idRefs.second);
181  newRefs.insert(tmpRefs.begin(), tmpRefs.end());
182  }
183 
184  nextRefs = std::move(newRefs);
185  }
186 
187  return newObjectNode[0].AddedNodeId;
188 }
189 
190 std::vector<ReferenceDescription> Object::BrowseObjectsAndVariables(const NodeId & id)
191 {
192  // Id of the new node.
193  BrowseDescription desc;
195  desc.IncludeSubtypes = true;
198  desc.NodeToBrowse = id;
200 
201  // browse sub objects and variables.
202  NodesQuery query;
203  query.NodesToBrowse.push_back(desc);
204  ViewServices::SharedPtr views = GetServices()->Views();
205  return views->Browse(query)[0].Referencies; //FIME: this method should return BrowseResults
206 }
207 
208 std::map<NodeId, std::vector<ReferenceDescription>> Object::CopyObjectsAndVariables(const NodeId & targetNode, const std::vector<ReferenceDescription> & refs)
209 {
210  std::map<NodeId, std::vector<ReferenceDescription>> nextCopyData;
211 
212  for (const ReferenceDescription & ref : refs)
213  {
214  std::vector<AddNodesResult> result;
215  std::vector<AddNodesItem> newNodeRequest;
216 
217  switch (ref.TargetNodeClass)
218  {
219  case NodeClass::Object:
220  {
221  if (ref.TargetNodeTypeDefinition != ObjectId::Null)
222  {
223  InstantiateType(NodeId(), targetNode, ref.TargetNodeTypeDefinition, NodeClass::Object, ref.BrowseName, ref.DisplayName.Text);
224  }
225 
226  else
227  {
228  newNodeRequest = {CreateObjectCopy(targetNode, ref)};
229  }
230 
231  break;
232  }
233 
234  case NodeClass::Variable:
235  {
236  newNodeRequest = {CreateVariableCopy(targetNode, ref)};
237  break;
238  }
239 
240  default:
241  {
242  continue;
243  }
244  }
245 
246  if (newNodeRequest.empty())
247  {
248  continue;
249  }
250 
251  result = GetServices()->NodeManagement()->AddNodes(newNodeRequest);
252  std::vector<ReferenceDescription> newRefs = BrowseObjectsAndVariables(ref.TargetNodeId);
253  nextCopyData.insert({result[0].AddedNodeId, newRefs});
254  }
255 
256  return nextCopyData;
257 }
258 
259 Variable Object::CreateVariable(const QualifiedName & browseName, const Variant & value)
260 {
261  return CreateVariable(NodeId(), browseName, value);
262 }
263 
264 Variable Object::CreateVariable(const NodeId & newVariableId, const QualifiedName & browseName, const Variant & value)
265 {
266  // Creating new node for object
267  AddNodesItem newNodeRequest;
268  newNodeRequest.BrowseName = browseName;
269  newNodeRequest.RequestedNewNodeId = newVariableId;
270  newNodeRequest.Class = NodeClass::Variable;
271  newNodeRequest.ParentNodeId = GetId();
272  newNodeRequest.ReferenceTypeId = ObjectId::HasProperty;
273  newNodeRequest.TypeDefinition = NodeId();
274  VariableAttributes attrs;
275  attrs.Description = LocalizedText(browseName.Name);
276  attrs.DisplayName = LocalizedText(browseName.Name);
277  attrs.Value = value;
278  attrs.Type = OpcUa::VariantTypeToDataType(value.Type());
279  newNodeRequest.Attributes = attrs;
280 
281  NodeManagementServices::SharedPtr nodes = GetServices()->NodeManagement();
282  std::vector<AddNodesResult> newNode = nodes->AddNodes({newNodeRequest});
283 
284  if (newNode.size() != 1)
285  {
286  throw std::runtime_error("opcua_model| Server returned wrong number new nodes results.");
287  }
288 
289  OpcUa::CheckStatusCode(newNode[0].Status);
290  Variable newVariable(GetServices());
291  newVariable.Id = newNode[0].AddedNodeId;
292  newVariable.BrowseName = browseName;
293  newVariable.DisplayName = attrs.Description;
294  newVariable.DataType = value.Type();
295  newVariable.TypeId = newNodeRequest.TypeDefinition;
296  return newVariable;
297 }
298 
300 {
301  return Variable(GetServices());
302 }
303 
304 Variable Object::CreateVariable(const NodeId & newVariableId, const QualifiedName & browseName, const VariableType & type)
305 {
306  return Variable(GetServices());
307 }
308 
310 {
311  const NodeId & nodeId = ref.TargetNodeId;
312 
313  ReadParameters readParams;
314  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::DisplayName));
315  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Description));
316  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Value));
317  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::DataType));
318  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::ValueRank));
319  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::ArrayDimensions));
320  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::AccessLevel));
321  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::UserAccessLevel));
323  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Historizing));
324  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::WriteMask));
325  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::UserWriteMask));
326  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::BrowseName));
327  std::vector<DataValue> values = GetServices()->Attributes()->Read(readParams);
328 
329  VariableAttributes attrs;
330  attrs.DisplayName = values[0].Value.As<LocalizedText>();
331  attrs.Description = values[1].Value.As<LocalizedText>();
332  attrs.Value = values[2].Value;
333  attrs.Type = values[3].Value.As<NodeId>();
334  attrs.Rank = values[4].Value.As<int32_t>();
335  attrs.Dimensions = values[5].Value.As<std::vector<uint32_t>>();
336  attrs.AccessLevel = static_cast<VariableAccessLevel>(values[6].Value.As<uint8_t>());
337  attrs.UserAccessLevel = static_cast<VariableAccessLevel>(values[7].Value.As<uint8_t>());
338  attrs.MinimumSamplingInterval = values[8].Value.As<Duration>();
339  attrs.Historizing = values[9].Value.As<bool>();
340  attrs.WriteMask = values[10].Value.As<uint32_t>();
341  attrs.UserWriteMask = values[11].Value.As<uint32_t>();
342 
343  AddNodesItem newNode;
344  newNode.BrowseName = values[12].Value.As<QualifiedName>();
345  newNode.Class = NodeClass::Variable;
346  newNode.ParentNodeId = parentId;
347  newNode.ReferenceTypeId = ref.ReferenceTypeId;
348  newNode.TypeDefinition = ref.TargetNodeTypeDefinition;
349  newNode.Attributes = attrs;
350  return newNode;
351 }
352 
354 {
355  const NodeId & nodeId = ref.TargetNodeId;
356 
357  ReadParameters readParams;
358  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::DisplayName));
359  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Description));
360  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::WriteMask));
361  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::UserWriteMask));
362  readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::BrowseName));
363  std::vector<DataValue> values = GetServices()->Attributes()->Read(readParams);
364 
365  ObjectAttributes attrs;
366  attrs.DisplayName = values[0].Value.As<LocalizedText>();
367  attrs.Description = values[1].Value.As<LocalizedText>();
368  attrs.WriteMask = values[2].Value.As<uint32_t>();
369  attrs.UserWriteMask = values[3].Value.As<uint32_t>();
370 
371  AddNodesItem newNode;
372  newNode.BrowseName = values[4].Value.As<QualifiedName>();
373  newNode.Class = NodeClass::Object;
374  newNode.ParentNodeId = parentId;
375  newNode.ReferenceTypeId = ref.ReferenceTypeId;
376  newNode.TypeDefinition = ref.TargetNodeTypeDefinition;
377  newNode.Attributes = attrs;
378  return newNode;
379 }
380 
381 } // namespace Model
382 } // namespace OpcUa
NodeId InstantiateType(const NodeId &newNodeId, const NodeId &parentNode, const NodeId &typeId, NodeClass nodeClass, const QualifiedName &browseName, const std::string &displayName)
std::vector< OpcUa::ReadValueId > AttributesToRead
void CheckStatusCode(StatusCode code)
OpcUa Error codes. GNU LGPL.
QualifiedName BrowseName
Definition: model.h:57
AddNodesItem CreateObjectCopy(const NodeId &parentId, const ReferenceDescription &ref)
ReadValueId ToReadValueId(NodeId id, AttributeId attr)
Definition: protocol.h:7
std::vector< BrowseDescription > NodesToBrowse
Definition: protocol/view.h:50
std::vector< Variable > GetVariables() const
Get variables of the object.
double Duration
Definition: datetime.h:53
std::vector< BrowsePath > BrowsePaths
boost::any Value
Definition: variant.h:160
name
Definition: setup.py:38
ObjectType GetType() const
Object(NodeId objectId, Services::SharedPtr services)
AddNodesItem CreateVariableCopy(const NodeId &parentId, const ReferenceDescription &ref)
Variable CreateVariable(const QualifiedName &browseName, const Variant &value)
Create a new variable.
fmt::BufferedFile & move(fmt::BufferedFile &f)
Definition: posix.h:432
ObjectId VariantTypeToDataType(VariantType vt)
std::vector< RelativePathElement > Elements
Definition: types.h:125
RelativePath Path
VariantType Type() const
OPC UA Address space part. GNU LGPL.
std::vector< Object > GetObjects() const
BrowseResultMask ResultMask
Definition: protocol/view.h:41
NodeClass
Definition: enums.h:39
std::string Name
Definition: types.h:74
Variable GetVariable(const QualifiedName &name) const
Get variable of the object by it name.
LocalizedText DisplayName
Definition: model.h:58
Object GetObject(const QualifiedName &name) const
BrowseDirection Direction
Definition: protocol/view.h:37
Object CreateObject(const ObjectType &type, const QualifiedName &browseName)
std::vector< BrowsePathTarget > Targets
Services::SharedPtr GetServices() const
Definition: model.h:47
std::vector< uint32_t > Dimensions
std::vector< ReferenceDescription > BrowseObjectsAndVariables(const NodeId &id)
NodeId GetId() const
Definition: model_node.cpp:43
std::map< NodeId, std::vector< ReferenceDescription > > CopyObjectsAndVariables(const NodeId &targetNode, const std::vector< ReferenceDescription > &refs)
Services::SharedPtr OpcUaServices
Definition: model.h:59
VariantType DataType
Definition: model.h:154
QualifiedName TargetName
Definition: types.h:120


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