node.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  *   Copyright (C) 2014-2014 Olivier Roulet-Dubonnet          *
00003  *   olivier.roulet@gmail.com          *
00004  *                      *
00005  *   This library is free software; you can redistribute it and/or modify   *
00006  *   it under the terms of the GNU Lesser General Public License as      *
00007  *   published by the Free Software Foundation; version 3 of the License.   *
00008  *                      *
00009  *   This library is distributed in the hope that it will be useful,      *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of      *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *
00012  *   GNU Lesser General Public License for more details.        *
00013  *                      *
00014  *   You should have received a copy of the GNU Lesser General Public License *
00015  *   along with this library; if not, write to the          *
00016  *   Free Software Foundation, Inc.,              *
00017  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.        *
00018  ******************************************************************************/
00019 
00020 
00021 #include <iostream>
00022 
00023 #include <opc/ua/node.h>
00024 
00025 #include <opc/ua/protocol/node_management.h>
00026 #include <opc/ua/protocol/strings.h>
00027 #include <opc/ua/protocol/string_utils.h>
00028 #include <opc/ua/protocol/variable_access_level.h>
00029 
00030 namespace OpcUa
00031 {
00032 
00033   Node::Node(Services::SharedPtr srv)
00034     : Node(srv, NumericNodeId(0, 0))
00035   {
00036   }
00037 
00038   Node::Node(Services::SharedPtr srv, const NodeId& id)
00039     : Server(srv)
00040     , Id(id)
00041   {
00042   }
00043 
00044   Node::Node(const Node& other)
00045     : Server(other.Server)
00046     , Id(other.Id)
00047   {
00048   }
00049 
00050   NodeId Node::GetId() const
00051   {
00052     return Id;
00053   }
00054 
00055   DataValue Node::GetAttribute(const AttributeId attr) const
00056   {
00057     ReadParameters params;
00058     ReadValueId attribute;
00059     attribute.NodeId = Id;
00060     attribute.AttributeId = attr;
00061     params.AttributesToRead.push_back(attribute);
00062     std::vector<DataValue> vec =  Server->Attributes()-> Read(params);
00063     if ( vec.size() > 0 )
00064     {
00065        return vec.front();
00066     }
00067     else
00068     {
00069       return DataValue(); //FIXME: What does it mean when not value is found?
00070     }
00071   }
00072 
00073   std::vector<Variant> Node::CallMethod(const NodeId methodId, const std::vector<Variant> inputArguments) const
00074   {
00075     std::vector<NodeId> vec_methodId;
00076     vec_methodId.push_back(methodId);
00077 
00078     std::vector<std::vector<Variant>> vec_inputArguments;
00079     vec_inputArguments.push_back(inputArguments);
00080 
00081     std::vector<std::vector<Variant>> results = CallMethods(vec_methodId, vec_inputArguments);
00082 
00083     return results.front();
00084   }
00085 
00086   std::vector<std::vector<Variant>> Node::CallMethods(const std::vector<NodeId> methodIds, const std::vector<std::vector<Variant>> inputArguments) const
00087   {
00088     std::vector<CallMethodRequest> methodsToCall;
00089 
00090     std::vector<NodeId>::const_iterator it1;
00091     std::vector<std::vector<Variant>>::const_iterator it2;
00092     for (it1 = methodIds.begin(), it2 = inputArguments.begin();
00093          it1 != methodIds.end() && it2 != inputArguments.end();
00094          ++it1, ++it2)
00095     {
00096       CallMethodRequest callMethod;
00097       callMethod.ObjectId = Id;
00098       callMethod.MethodId = *it1;
00099       callMethod.InputArguments = *it2;
00100 
00101       methodsToCall.push_back(callMethod);
00102     }
00103 
00104     std::vector<CallMethodResult> results = Server->Method()->Call(methodsToCall);
00105 
00106     std::vector<std::vector<Variant>> ret;
00107     for (std::vector<CallMethodResult>::iterator it = results.begin(); it != results.end(); ++it)
00108     {
00109       CheckStatusCode(it->Status);
00110       ret.push_back(it->OutputArguments);
00111     }
00112 
00113     return ret;
00114   }
00115 
00116   void Node::SetAttribute(AttributeId attr, const DataValue &dval) const
00117   {
00118     WriteValue attribute;
00119     attribute.NodeId = Id;
00120     attribute.AttributeId = attr;
00121     attribute.Value = dval;
00122     std::vector<StatusCode> codes = Server->Attributes()->Write(std::vector<WriteValue>(1, attribute));
00123     CheckStatusCode(codes.front());
00124   }
00125 
00126   void Node::SetValue(const Variant& val) const
00127   {
00128     DataValue dval(val);
00129     SetAttribute(AttributeId::Value, dval);
00130   }
00131 
00132   void Node::SetValue(const DataValue &dval) const
00133   {
00134     SetAttribute(AttributeId::Value, dval);
00135   }
00136 
00137 
00138   std::vector<Node> Node::GetChildren(const ReferenceId& refid) const
00139   {
00140     BrowseDescription description;
00141     description.NodeToBrowse = Id;
00142     description.Direction = BrowseDirection::Forward;
00143     description.IncludeSubtypes = true;
00144     description.NodeClasses = NodeClass::Unspecified;
00145     description.ResultMask = BrowseResultMask::All;
00146     description.ReferenceTypeId =  refid;
00147 
00148     NodesQuery query;
00149     query.NodesToBrowse.push_back(description);
00150     query.MaxReferenciesPerNode = 100;
00151     std::vector<Node> nodes;
00152     std::vector<BrowseResult> results = Server->Views()->Browse(query);
00153     if ( results.empty() )
00154     {
00155       return nodes;
00156     }
00157     while(!results[0].Referencies.empty())
00158     {
00159       for (auto refIt : results[0].Referencies)
00160       {
00161         Node node(Server, refIt.TargetNodeId);
00162         nodes.push_back(node);
00163       }
00164       results = Server->Views()->BrowseNext();
00165       if ( results.empty() )
00166       {
00167         return nodes;
00168       }
00169     }
00170     return nodes;
00171   }
00172 
00173   std::vector<Node> Node::GetChildren() const
00174   {
00175     return GetChildren(ReferenceId::HierarchicalReferences);
00176   }
00177 
00178   QualifiedName Node::GetBrowseName() const
00179   {
00180     Variant var = GetAttribute(AttributeId::BrowseName).Value;
00181     if (var.Type() != VariantType::QUALIFIED_NAME)
00182     {
00183       throw std::runtime_error("Could not retrieve browse name.");
00184     }
00185     return var.As<QualifiedName>();
00186   }
00187 
00188   std::vector<AddNodesResult> Node::AddNodes(std::vector<AddNodesItem> items) const
00189   {
00190     return Server->NodeManagement()->AddNodes(items);
00191   }
00192 
00193   std::vector<StatusCode> Node::AddReferences(std::vector<AddReferencesItem> items) const
00194   {
00195     return Server->NodeManagement()->AddReferences(items);
00196   }
00197 
00198   Node Node::GetChild(const std::string& browsename) const
00199   {
00200     return GetChild(std::vector<std::string>({browsename}));
00201   }
00202 
00203   Node Node::GetChild(const std::vector<std::string>& path) const
00204   {
00205     std::vector<QualifiedName> vec;
00206     uint16_t namespaceIdx = Id.GetNamespaceIndex();
00207     for (std::string str: path)
00208     {
00209       QualifiedName qname = ToQualifiedName(str, namespaceIdx);
00210       namespaceIdx = qname.NamespaceIndex;
00211       vec.push_back(qname);
00212     }
00213     return GetChild(vec);
00214   }
00215 
00216 
00217   Node Node::GetChild(const std::vector<QualifiedName>& path) const
00218   {
00219     std::vector<RelativePathElement> rpath;
00220     for (QualifiedName qname: path)
00221     {
00222       RelativePathElement el;
00223       el.TargetName = qname;
00224       rpath.push_back(el);
00225     }
00226     BrowsePath bpath;
00227     bpath.Path.Elements = rpath;
00228     bpath.StartingNode = Id;
00229     std::vector<BrowsePath> bpaths;
00230     bpaths.push_back(bpath);
00231     TranslateBrowsePathsParameters params;
00232     params.BrowsePaths = bpaths;
00233 
00234     std::vector<BrowsePathResult> result = Server->Views()->TranslateBrowsePathsToNodeIds(params);
00235     CheckStatusCode(result.front().Status);
00236 
00237     NodeId node =result.front().Targets.front().Node ;
00238     return Node(Server, node);
00239   }
00240 
00241   std::string Node::ToString() const
00242   {
00243     std::ostringstream os;
00244     os << "Node(" << Id << ")";
00245     return os.str();
00246   }
00247 
00248   Node Node::AddFolder(const std::string& nodeid, const std::string& browsename) const
00249    {
00250      NodeId node = ToNodeId(nodeid, this->Id.GetNamespaceIndex());
00251      QualifiedName qn = ToQualifiedName(browsename, GetBrowseName().NamespaceIndex);
00252      return AddFolder(node, qn);
00253    }
00254 
00255   Node Node::AddFolder(uint32_t namespaceIdx, const std::string& name) const
00256   {
00257     NodeId nodeid = NumericNodeId(0, namespaceIdx);
00258     QualifiedName qn = ToQualifiedName(name, namespaceIdx);
00259     return AddFolder(nodeid, qn);
00260   }
00261 
00262   Node Node::AddFolder(const NodeId& nodeid, const QualifiedName& browsename) const
00263   {
00264 
00265     AddNodesItem item;
00266     item.BrowseName = browsename;
00267     item.ParentNodeId = this->Id;
00268     item.RequestedNewNodeId = nodeid;
00269     item.Class = NodeClass::Object;
00270     item.ReferenceTypeId = ReferenceId::Organizes;
00271     item.TypeDefinition = ObjectId::FolderType;
00272     ObjectAttributes attr;
00273     attr.DisplayName = LocalizedText(browsename.Name);
00274     attr.Description = LocalizedText(browsename.Name);
00275     attr.WriteMask = 0;
00276     attr.UserWriteMask = 0;
00277     attr.EventNotifier = 0;
00278     item.Attributes = attr;
00279 
00280     std::vector<AddNodesResult> addnodesresults = Server->NodeManagement()->AddNodes(std::vector<AddNodesItem>({item}));
00281     AddNodesResult res = addnodesresults.front(); //This should always work
00282     CheckStatusCode(res.Status);
00283 
00284     return Node(Server, res.AddedNodeId);
00285   }
00286 
00287   Node Node::AddObject(const std::string& nodeid, const std::string& browsename) const
00288    {
00289      NodeId node = ToNodeId(nodeid, this->Id.GetNamespaceIndex());
00290      QualifiedName qn = ToQualifiedName(browsename, GetBrowseName().NamespaceIndex);
00291      return AddObject(node, qn);
00292    }
00293 
00294   Node Node::AddObject(uint32_t namespaceIdx, const std::string& name) const
00295   {
00296     //FIXME: should default namespace be the onde from the parent of the browsename?
00297     NodeId nodeid = NumericNodeId(0, namespaceIdx);
00298     QualifiedName qn = ToQualifiedName(name, namespaceIdx);
00299     return AddObject(nodeid, qn);
00300   }
00301 
00302   Node Node::AddObject(const NodeId& nodeid, const QualifiedName& browsename) const
00303   {
00304     AddNodesItem item;
00305     item.BrowseName = browsename;
00306     item.ParentNodeId = this->Id;
00307     item.RequestedNewNodeId = nodeid;
00308     item.Class = NodeClass::Object;
00309     item.ReferenceTypeId = ReferenceId::HasComponent;
00310     item.TypeDefinition = ObjectId::BaseObjectType;
00311     ObjectAttributes attr;
00312     attr.DisplayName = LocalizedText(browsename.Name);
00313     attr.Description = LocalizedText(browsename.Name);
00314     attr.WriteMask = 0;
00315     attr.UserWriteMask = 0;
00316     attr.EventNotifier = 0;
00317     item.Attributes = attr;
00318 
00319     std::vector<AddNodesResult> addnodesresults = Server->NodeManagement()->AddNodes(std::vector<AddNodesItem>({item}));
00320 
00321     AddNodesResult res = addnodesresults.front(); //This should always work
00322     CheckStatusCode(res.Status);
00323 
00324     return Node(Server, res.AddedNodeId);
00325   }
00326 
00327   Node Node::AddVariable(uint32_t namespaceIdx, const std::string& name, const Variant& val) const
00328   {
00329     NodeId nodeid = NumericNodeId(0, namespaceIdx);
00330     QualifiedName qn = ToQualifiedName(name, namespaceIdx);
00331     return AddVariable(nodeid, qn, val);
00332   }
00333 
00334   Node Node::AddVariable(const std::string& nodeid, const std::string& browsename, const Variant& val) const
00335   {
00336     NodeId node = ToNodeId(nodeid, this->Id.GetNamespaceIndex());
00337     QualifiedName qn = ToQualifiedName(browsename, GetBrowseName().NamespaceIndex);
00338     return AddVariable(node, qn, val);
00339   }
00340 
00341   Node Node::AddVariable(const NodeId& nodeid, const QualifiedName& browsename, const Variant& val) const
00342   {
00343     ObjectId datatype = VariantTypeToDataType(val.Type());
00344 
00345     AddNodesItem item;
00346     item.BrowseName = browsename;
00347     item.ParentNodeId = this->Id;
00348     item.RequestedNewNodeId = nodeid;
00349     item.Class = NodeClass::Variable;
00350     item.ReferenceTypeId = ReferenceId::HasComponent;
00351     item.TypeDefinition = ObjectId::BaseDataVariableType;
00352     VariableAttributes attr;
00353     attr.DisplayName = LocalizedText(browsename.Name);
00354     attr.Description = LocalizedText(browsename.Name);
00355     attr.WriteMask = (uint32_t)OpenFileMode::Read;
00356     attr.UserWriteMask = (uint32_t)OpenFileMode::Read;
00357     attr.Value = val;
00358     attr.Type = datatype;
00359     attr.Rank  = -1;
00360     attr.Dimensions = val.Dimensions;
00361     attr.AccessLevel = VariableAccessLevel::CurrentRead;
00362     attr.UserAccessLevel = VariableAccessLevel::CurrentRead;
00363     attr.MinimumSamplingInterval = 1;
00364     attr.Historizing = 0;
00365     item.Attributes = attr;
00366 
00367     std::vector<AddNodesResult> addnodesresults = Server->NodeManagement()->AddNodes(std::vector<AddNodesItem>({item}));
00368 
00369     AddNodesResult res = addnodesresults.front(); //This should always work
00370     CheckStatusCode(res.Status);
00371 
00372     return Node(Server, res.AddedNodeId);
00373   }
00374 
00375 
00376   Node Node::AddProperty(uint32_t namespaceIdx, const std::string& name, const Variant& val) const
00377   {
00378     NodeId nodeid = NumericNodeId(0, namespaceIdx);
00379     const QualifiedName& qname = ToQualifiedName(name, namespaceIdx);
00380     return AddProperty(nodeid, qname, val);
00381   }
00382 
00383   Node Node::AddProperty(const std::string& nodeid, const std::string& browsename, const Variant& val) const
00384   {
00385     NodeId node = ToNodeId(nodeid, this->Id.GetNamespaceIndex());
00386     QualifiedName qn = ToQualifiedName(browsename, GetBrowseName().NamespaceIndex);
00387     return AddProperty(node, qn, val);
00388   }
00389 
00390   Node Node::AddProperty(const NodeId& nodeid, const QualifiedName& browsename, const Variant& val) const
00391   {
00392 
00393     ObjectId datatype = VariantTypeToDataType(val.Type());
00394 
00395     AddNodesItem item;
00396     item.BrowseName = browsename;
00397     item.ParentNodeId = this->Id;
00398     item.RequestedNewNodeId = nodeid;
00399     item.Class = NodeClass::Variable;
00400     item.ReferenceTypeId = ReferenceId::HasProperty;
00401     item.TypeDefinition = ObjectId::PropertyType;
00402     VariableAttributes attr;
00403     attr.DisplayName = LocalizedText(browsename.Name);
00404     attr.Description = LocalizedText(browsename.Name);
00405     attr.WriteMask = 0;
00406     attr.UserWriteMask = 0;
00407     attr.Value = val;
00408     attr.Type = datatype;
00409     attr.Rank  = 0;
00410     attr.Dimensions = val.Dimensions;
00411     attr.AccessLevel = VariableAccessLevel::CurrentRead;
00412     attr.UserAccessLevel = VariableAccessLevel::CurrentRead;
00413     attr.MinimumSamplingInterval = 0;
00414     attr.Historizing = 0;
00415     item.Attributes = attr;
00416 
00417     std::vector<AddNodesResult> addnodesresults = Server->NodeManagement()->AddNodes(std::vector<AddNodesItem>({item}));
00418 
00419     AddNodesResult res = addnodesresults.front(); //This should always work
00420     CheckStatusCode(res.Status);
00421 
00422     return Node(Server, res.AddedNodeId);
00423 
00424   }
00425 
00426   Node Node::AddMethod(uint32_t namespaceIdx, const std::string& name,  std::function<std::vector<OpcUa::Variant> (std::vector<OpcUa::Variant> arguments)> method) const
00427   {
00428     NodeId nodeid = NumericNodeId(0, namespaceIdx);
00429     QualifiedName qn = ToQualifiedName(name, namespaceIdx);
00430     return AddVariable(nodeid, qn, method);
00431   }
00432 
00433   Node Node::AddMethod(const std::string& nodeid, const std::string& browsename, std::function<std::vector<OpcUa::Variant> (std::vector<OpcUa::Variant> arguments)> method) const
00434   {
00435     NodeId node = ToNodeId(nodeid, this->Id.GetNamespaceIndex());
00436     QualifiedName qn = ToQualifiedName(browsename, GetBrowseName().NamespaceIndex);
00437     return AddVariable(node, qn, method);
00438   }
00439 
00440   Node Node::AddMethod(const NodeId& nodeid, const QualifiedName& browsename, std::function<std::vector<OpcUa::Variant> (std::vector<OpcUa::Variant> arguments)> method) const
00441   {
00442     AddNodesItem item;
00443     item.BrowseName = browsename;
00444     item.ParentNodeId = this->Id;
00445     item.RequestedNewNodeId = nodeid;
00446     item.Class = NodeClass::Method;
00447     item.ReferenceTypeId = ReferenceId::HasComponent;
00448     //item.TypeDefinition = ObjectId::BaseDataVariableType;
00449     MethodAttributes attr;
00450     attr.DisplayName = LocalizedText(browsename.Name);
00451     attr.Description = LocalizedText(browsename.Name);
00452     attr.WriteMask = 0;
00453     attr.UserWriteMask = 0;
00454     attr.Executable = true;
00455     attr.UserExecutable = true;
00456     item.Attributes = attr;
00457 
00458     std::vector<AddNodesResult> addnodesresults = Server->NodeManagement()->AddNodes(std::vector<AddNodesItem>({item}));
00459 
00460     AddNodesResult res = addnodesresults.front(); //This should always work
00461     CheckStatusCode(res.Status);
00462     //addressspace.SetMethod(res.AddedNodeId, method);
00463 
00464     return Node(Server, res.AddedNodeId);
00465   }
00466 
00467 
00468 
00469   Variant Node::GetValue() const
00470   {
00471     return (GetAttribute(AttributeId::Value)).Value;
00472   }
00473 
00474   DataValue Node::GetDataValue() const
00475   {
00476     return GetAttribute(AttributeId::Value);
00477   }
00478 
00479   Variant Node::GetDataType() const
00480   {
00481     return (GetAttribute(AttributeId::DataType)).Value;
00482   }
00483 
00484 } // namespace OpcUa
00485 
00486 
00487 std::ostream& OpcUa::operator<<(std::ostream& os, const Node& node)
00488 {
00489   os << node.ToString();
00490   return os;
00491 }
00492 


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Sat Jun 8 2019 18:24:56