model_object.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  *   Copyright (C) 2013-2014 by Alexander Rykovanov                        *
00003  *   rykovanov.as@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 #include "model_impl.h"
00021 
00022 #include <opc/ua/model.h>
00023 
00024 namespace OpcUa
00025 {
00026   namespace Model
00027   {
00028 
00029     Object::Object(NodeId objectId, Services::SharedPtr services)
00030       : Node(services)
00031     {
00032       Id = objectId;
00033       ReadParameters attrs;
00034       attrs.AttributesToRead.push_back(ToReadValueId(objectId, AttributeId::DisplayName));
00035       attrs.AttributesToRead.push_back(ToReadValueId(objectId, AttributeId::BrowseName));
00036       std::vector<DataValue> values = services->Attributes()->Read(attrs);
00037       DisplayName = values[0].Value.As<LocalizedText>();
00038       BrowseName = values[1].Value.As<QualifiedName>();
00039     }
00040 
00041     Object::Object(Object&& object)
00042       : Node(std::move(object.OpcUaServices))
00043     {
00044       Id = std::move(object.Id);
00045       DisplayName = std::move(object.DisplayName);
00046       BrowseName = std::move(object.BrowseName);
00047     }
00048 
00049     Object::Object(const Object& object)
00050       : Node(object.OpcUaServices)
00051     {
00052       Id = object.Id;
00053       DisplayName = object.DisplayName;
00054       BrowseName = object.BrowseName;
00055     }
00056 
00057     Object::Object(Services::SharedPtr services)
00058       : Node(services)
00059     {
00060     }
00061 
00062     ObjectType Object::GetType() const
00063     {
00064       return ObjectType(ObjectId::Null, GetServices());
00065     }
00066 
00067     std::vector<Variable> Object::GetVariables() const
00068     {
00069       return Browse<Variable>(GetId(), NodeClass::Variable, GetServices());
00070     }
00071 
00072     Variable Object::GetVariable(const QualifiedName& name) const
00073     {
00074       OpcUa::RelativePathElement element;
00075       element.ReferenceTypeId = OpcUa::ObjectId::HierarchicalReferences;
00076       element.IncludeSubtypes = true;
00077       element.TargetName = name;
00078 
00079       OpcUa::RelativePath path;
00080       path.Elements.push_back(element);
00081       return GetVariable(path);
00082     }
00083 
00084     Variable Object::GetVariable(const RelativePath& relativePath) const
00085     {
00086       OpcUa::BrowsePath browsePath;
00087       browsePath.StartingNode = GetId();
00088       browsePath.Path = relativePath;
00089       OpcUa::TranslateBrowsePathsParameters params;
00090       params.BrowsePaths.push_back(browsePath);
00091       const std::vector<OpcUa::BrowsePathResult>& result = GetServices()->Views()->TranslateBrowsePathsToNodeIds(params);
00092       if (result.size() != 1)
00093         throw std::runtime_error("object_model| Server returned more than one browse paths on TranslateBrowsePathsToNodeIds request.");
00094 
00095       const OpcUa::BrowsePathResult& resultPath = result.back();
00096       OpcUa::CheckStatusCode(resultPath.Status);
00097       if (resultPath.Targets.size() != 1)
00098         throw std::runtime_error("object_model| Server returned too many target elements on TranslateBrowsePathsToNodeIds request.");
00099 
00100       return Variable(resultPath.Targets.back().Node, GetServices());
00101     }
00102 
00103 
00104     std::vector<Object> Object::GetObjects() const
00105     {
00106       return Browse<Object>(GetId(), NodeClass::Object, GetServices());
00107     }
00108 
00109     Object Object::GetObject(const QualifiedName& name) const
00110     {
00111       return Object(ObjectId::Null, GetServices());
00112     }
00113 
00114     Object Object::GetObject(const RelativePath& name) const
00115     {
00116       return Object(ObjectId::Null, GetServices());
00117     }
00118 
00119     Object Object::CreateObject(const ObjectType& type, const QualifiedName& browseName)
00120     {
00121       return CreateObject(NodeId(), type, browseName);
00122     }
00123 
00124     Object Object::CreateObject(const NodeId& newNodeId, const ObjectType& nodeType, const QualifiedName& browseName)
00125     {
00126       return CreateObject(newNodeId, GetId(), nodeType.GetId(), browseName, browseName.Name);
00127     }
00128 
00129     Object Object::CreateObject(const ObjectType& type, const QualifiedName& browseName, const std::string& displayName)
00130     {
00131       return CreateObject(NodeId(), GetId(), type.GetId(), browseName, displayName);
00132     }
00133 
00134     Object Object::CreateObject(const NodeId& newNodeId, const NodeId& parentNode, const NodeId& typeId, const QualifiedName& browseName, const std::string& displayName)
00135     {
00136       Object object(GetServices());
00137       object.Id = InstantiateType(newNodeId, parentNode, typeId, NodeClass::Object, browseName, displayName);
00138       object.BrowseName = browseName;
00139       object.DisplayName = LocalizedText(displayName);
00140       return object;
00141 
00142     }
00143 
00144     NodeId Object::InstantiateType(const NodeId& newNodeId, const NodeId& parentNode, const NodeId& typeId, NodeClass nodeClass, const QualifiedName& browseName, const std::string& displayName)
00145     {
00146       // Creating new node for object
00147       AddNodesItem newNodeRequest;
00148       newNodeRequest.BrowseName = browseName;
00149       newNodeRequest.RequestedNewNodeId = newNodeId;
00150       newNodeRequest.Class = nodeClass;
00151       newNodeRequest.ParentNodeId = parentNode;
00152       newNodeRequest.ReferenceTypeId = nodeClass == NodeClass::Object ? ObjectId::HasComponent : ObjectId::HasProperty;
00153       newNodeRequest.TypeDefinition = typeId;
00154       ObjectAttributes attrs;
00155       attrs.Description = LocalizedText(displayName);
00156       attrs.DisplayName = LocalizedText(displayName);
00157       newNodeRequest.Attributes = attrs;
00158 
00159       NodeManagementServices::SharedPtr nodes = GetServices()->NodeManagement();
00160       std::vector<AddNodesResult> newObjectNode = nodes->AddNodes({newNodeRequest});
00161       if (newObjectNode.size() != 1)
00162       {
00163         throw std::runtime_error("opcua_model| Server returned wrong number new nodes results.");
00164       }
00165 
00166       OpcUa::CheckStatusCode(newObjectNode[0].Status);
00167 
00168       std::map<NodeId, std::vector<ReferenceDescription>> nextRefs;
00169       nextRefs.insert({newObjectNode[0].AddedNodeId, BrowseObjectsAndVariables(typeId)});
00170       while(!nextRefs.empty())
00171       {
00172         std::map<NodeId, std::vector<ReferenceDescription>> newRefs;
00173         for (auto idRefs : nextRefs)
00174         {
00175           std::map<NodeId, std::vector<ReferenceDescription>> tmpRefs = CopyObjectsAndVariables(idRefs.first, idRefs.second);
00176           newRefs.insert(tmpRefs.begin(), tmpRefs.end());
00177         }
00178         nextRefs = std::move(newRefs);
00179       }
00180       return newObjectNode[0].AddedNodeId;
00181     }
00182 
00183     std::vector<ReferenceDescription> Object::BrowseObjectsAndVariables(const NodeId& id)
00184     {
00185       // Id of the new node.
00186       BrowseDescription desc;
00187       desc.Direction = BrowseDirection::Forward;
00188       desc.IncludeSubtypes = true;
00189       desc.NodeClasses =   NodeClass::Object | NodeClass::Variable | NodeClass::Method;
00190       desc.ReferenceTypeId = ObjectId::HierarchicalReferences;
00191       desc.NodeToBrowse = id;
00192       desc.ResultMask = BrowseResultMask::NodeClass | BrowseResultMask::TypeDefinition | BrowseResultMask::BrowseName | BrowseResultMask::DisplayName;
00193 
00194       // browse sub objects and variables.
00195       NodesQuery query;
00196       query.NodesToBrowse.push_back(desc);
00197       ViewServices::SharedPtr views = GetServices()->Views();
00198       return views->Browse(query)[0].Referencies; //FIME: this method should return BrowseResults
00199     }
00200 
00201     std::map<NodeId, std::vector<ReferenceDescription>> Object::CopyObjectsAndVariables(const NodeId& targetNode, const std::vector<ReferenceDescription>& refs)
00202     {
00203       std::map<NodeId, std::vector<ReferenceDescription>> nextCopyData;
00204       for (const ReferenceDescription& ref : refs)
00205       {
00206         std::vector<AddNodesResult> result;
00207         std::vector<AddNodesItem> newNodeRequest;
00208         switch (ref.TargetNodeClass)
00209         {
00210           case NodeClass::Object:
00211           {
00212             if (ref.TargetNodeTypeDefinition !=ObjectId::Null)
00213             {
00214               InstantiateType(NodeId(), targetNode, ref.TargetNodeTypeDefinition, NodeClass::Object, ref.BrowseName, ref.DisplayName.Text);
00215             }
00216             else
00217             {
00218               newNodeRequest = {CreateObjectCopy(targetNode, ref)};
00219             }
00220             break;
00221           }
00222           case NodeClass::Variable:
00223           {
00224             newNodeRequest = {CreateVariableCopy(targetNode, ref)};
00225             break;
00226           }
00227           default:
00228           {
00229             continue;
00230           }
00231         }
00232         if (newNodeRequest.empty())
00233         {
00234           continue;
00235         }
00236         result = GetServices()->NodeManagement()->AddNodes(newNodeRequest);
00237         std::vector<ReferenceDescription> newRefs = BrowseObjectsAndVariables(ref.TargetNodeId);
00238         nextCopyData.insert({result[0].AddedNodeId, newRefs});
00239       }
00240       return nextCopyData;
00241     }
00242 
00243     Variable Object::CreateVariable(const QualifiedName& browseName, const Variant& value)
00244     {
00245       return CreateVariable(NodeId(), browseName, value);
00246     }
00247 
00248     Variable Object::CreateVariable(const NodeId& newVariableId, const QualifiedName& browseName, const Variant& value)
00249     {
00250       // Creating new node for object
00251       AddNodesItem newNodeRequest;
00252       newNodeRequest.BrowseName = browseName;
00253       newNodeRequest.RequestedNewNodeId = newVariableId;
00254       newNodeRequest.Class = NodeClass::Variable;
00255       newNodeRequest.ParentNodeId = GetId();
00256       newNodeRequest.ReferenceTypeId = ObjectId::HasProperty;
00257       newNodeRequest.TypeDefinition = NodeId();
00258       VariableAttributes attrs;
00259       attrs.Description = LocalizedText(browseName.Name);
00260       attrs.DisplayName = LocalizedText(browseName.Name);
00261       attrs.Value = value;
00262       attrs.Type = OpcUa::VariantTypeToDataType(value.Type());
00263       newNodeRequest.Attributes = attrs;
00264 
00265       NodeManagementServices::SharedPtr nodes = GetServices()->NodeManagement();
00266       std::vector<AddNodesResult> newNode = nodes->AddNodes({newNodeRequest});
00267       if (newNode.size() != 1)
00268       {
00269         throw std::runtime_error("opcua_model| Server returned wrong number new nodes results.");
00270       }
00271 
00272       OpcUa::CheckStatusCode(newNode[0].Status);
00273       Variable newVariable(GetServices());
00274       newVariable.Id = newNode[0].AddedNodeId;
00275       newVariable.BrowseName = browseName;
00276       newVariable.DisplayName = attrs.Description;
00277       newVariable.DataType = value.Type();
00278       newVariable.TypeId = newNodeRequest.TypeDefinition;
00279       return newVariable;
00280     }
00281 
00282     Variable Object::CreateVariable(const QualifiedName& browseName, const VariableType& type)
00283     {
00284       return Variable(GetServices());
00285     }
00286 
00287     Variable Object::CreateVariable(const NodeId& newVariableId, const QualifiedName& browseName, const VariableType& type)
00288     {
00289       return Variable(GetServices());
00290     }
00291 
00292     AddNodesItem Object::CreateVariableCopy(const NodeId& parentId, const ReferenceDescription& ref)
00293     {
00294       const NodeId& nodeId = ref.TargetNodeId;
00295 
00296       ReadParameters readParams;
00297       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::DisplayName));
00298       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Description));
00299       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Value));
00300       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::DataType));
00301       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::ValueRank));
00302       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::ArrayDimensions));
00303       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::AccessLevel));
00304       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::UserAccessLevel));
00305       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::MinimumSamplingInterval));
00306       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Historizing));
00307       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::WriteMask));
00308       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::UserWriteMask));
00309       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::BrowseName));
00310       std::vector<DataValue> values = GetServices()->Attributes()->Read(readParams);
00311 
00312       VariableAttributes attrs;
00313       attrs.DisplayName = values[0].Value.As<LocalizedText>();
00314       attrs.Description = values[1].Value.As<LocalizedText>();
00315       attrs.Value = values[2].Value;
00316       attrs.Type = values[3].Value.As<NodeId>();
00317       attrs.Rank = values[4].Value.As<int32_t>();
00318       attrs.Dimensions = values[5].Value.As<std::vector<uint32_t>>();
00319       attrs.AccessLevel = static_cast<VariableAccessLevel>(values[6].Value.As<uint8_t>());
00320       attrs.UserAccessLevel = static_cast<VariableAccessLevel>(values[7].Value.As<uint8_t>());
00321       attrs.MinimumSamplingInterval = values[8].Value.As<Duration>();
00322       attrs.Historizing = values[9].Value.As<bool>();
00323       attrs.WriteMask = values[10].Value.As<uint32_t>();
00324       attrs.UserWriteMask = values[11].Value.As<uint32_t>();
00325 
00326       AddNodesItem newNode;
00327       newNode.BrowseName = values[12].Value.As<QualifiedName>();
00328       newNode.Class = NodeClass::Variable;
00329       newNode.ParentNodeId = parentId;
00330       newNode.ReferenceTypeId = ref.ReferenceTypeId;
00331       newNode.TypeDefinition = ref.TargetNodeTypeDefinition;
00332       newNode.Attributes = attrs;
00333       return newNode;
00334     }
00335 
00336     AddNodesItem Object::CreateObjectCopy(const NodeId& parentId, const ReferenceDescription& ref)
00337     {
00338       const NodeId& nodeId = ref.TargetNodeId;
00339 
00340       ReadParameters readParams;
00341       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::DisplayName));
00342       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::Description));
00343       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::WriteMask));
00344       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::UserWriteMask));
00345       readParams.AttributesToRead.push_back(ToReadValueId(nodeId, AttributeId::BrowseName));
00346       std::vector<DataValue> values = GetServices()->Attributes()->Read(readParams);
00347 
00348       ObjectAttributes attrs;
00349       attrs.DisplayName = values[0].Value.As<LocalizedText>();
00350       attrs.Description = values[1].Value.As<LocalizedText>();
00351       attrs.WriteMask = values[2].Value.As<uint32_t>();
00352       attrs.UserWriteMask = values[3].Value.As<uint32_t>();
00353 
00354       AddNodesItem newNode;
00355       newNode.BrowseName = values[4].Value.As<QualifiedName>();
00356       newNode.Class = NodeClass::Object;
00357       newNode.ParentNodeId = parentId;
00358       newNode.ReferenceTypeId = ref.ReferenceTypeId;
00359       newNode.TypeDefinition = ref.TargetNodeTypeDefinition;
00360       newNode.Attributes = attrs;
00361       return newNode;
00362     }
00363 
00364   } // namespace Model
00365 } // namespace OpcUa


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