Variable Object::CreateVariable(const NodeId& newVariableId, const QualifiedName& browseName, const Variant& value) { // Creating new node for object AddNodesItem newNodeRequest; newNodeRequest.BrowseName = browseName; newNodeRequest.RequestedNewNodeId = newVariableId; newNodeRequest.Class = NodeClass::Variable; newNodeRequest.ParentNodeId = GetId(); newNodeRequest.ReferenceTypeId = ObjectId::HasProperty; newNodeRequest.TypeDefinition = NodeId(); VariableAttributes attrs; attrs.Description = LocalizedText(browseName.Name); attrs.DisplayName = LocalizedText(browseName.Name); attrs.Value = value; attrs.Type = OpcUa::VariantTypeToDataType(value.Type()); newNodeRequest.Attributes = attrs; NodeManagementServices::SharedPtr nodes = GetServices()->NodeManagement(); std::vector<AddNodesResult> newNode = nodes->AddNodes({newNodeRequest}); if (newNode.size() != 1) { throw std::runtime_error("opcua_model| Server returned wrong number new nodes results."); } OpcUa::CheckStatusCode(newNode[0].Status); Variable newVariable(GetServices()); newVariable.Id = newNode[0].AddedNodeId; newVariable.BrowseName = browseName; newVariable.DisplayName = attrs.Description; newVariable.DataType = value.Type(); newVariable.TypeId = newNodeRequest.TypeDefinition; return newVariable; }
static void create_11507(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=11507"); node.BrowseName = ToQualifiedName("DeltaBounds"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the difference between the StartBound and EndBound value in the interval."); attrs.DisplayName = LocalizedText("DeltaBounds"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_11506(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=11506"); node.BrowseName = ToQualifiedName("EndBound"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the value at the end of the interval using Simple Bounding Values."); attrs.DisplayName = LocalizedText("EndBound"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_2355(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=2355"); node.BrowseName = ToQualifiedName("NumberOfTransitions"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the number of changes between zero and non-zero that a Boolean or Numeric value experienced in the interval."); attrs.DisplayName = LocalizedText("NumberOfTransitions"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_11308(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=11308"); node.BrowseName = ToQualifiedName("DurationInStateNonZero"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the time a Boolean or numeric was in a non-zero state using Simple Bounding Values."); attrs.DisplayName = LocalizedText("DurationInStateNonZero"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_2352(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=2352"); node.BrowseName = ToQualifiedName("Count"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the number of raw values over the interval."); attrs.DisplayName = LocalizedText("Count"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_11306(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=11306"); node.BrowseName = ToQualifiedName("MaximumActualTime2"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the maximum value with the actual timestamp including the Simple Bounding Values."); attrs.DisplayName = LocalizedText("MaximumActualTime2"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_2349(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=2349"); node.BrowseName = ToQualifiedName("MaximumActualTime"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the maximum value in the interval and the Timestamp of the maximum value."); attrs.DisplayName = LocalizedText("MaximumActualTime"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_2344(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=2344"); node.BrowseName = ToQualifiedName("Total"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the total (time integral) of the data over the interval using Interpolated Bounding Values."); attrs.DisplayName = LocalizedText("Total"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_2361(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=2361"); node.BrowseName = ToQualifiedName("DurationBad"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the total duration of time in the interval during which the data is bad."); attrs.DisplayName = LocalizedText("DurationBad"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_2363(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=2363"); node.BrowseName = ToQualifiedName("PercentBad"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the percent of data (0 to 100) in the interval which has a bad StatusCode."); attrs.DisplayName = LocalizedText("PercentBad"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_11429(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=11429"); node.BrowseName = ToQualifiedName("VariancePopulation"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the variance for the interval as calculated by the StandardDeviationPopulation which includes Simple Bounding Values."); attrs.DisplayName = LocalizedText("VariancePopulation"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_2341(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=2341"); node.BrowseName = ToQualifiedName("Interpolative"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("At the beginning of each interval, retrieve the calculated value from the data points on either side of the requested timestamp."); attrs.DisplayName = LocalizedText("Interpolative"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_11426(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=11426"); node.BrowseName = ToQualifiedName("StandardDeviationSample"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the standard deviation for the interval for a sample of the population (n-1)."); attrs.DisplayName = LocalizedText("StandardDeviationSample"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
static void create_11292(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=11292"); node.BrowseName = ToQualifiedName("WorstQuality2"); node.Class = NodeClass::Object; node.TypeDefinition = ToNodeId("i=2340"); ObjectAttributes attrs; attrs.Description = LocalizedText("Retrieve the worst StatusCode of data in the interval including the Simple Bounding Values."); attrs.DisplayName = LocalizedText("WorstQuality2"); attrs.EventNotifier = 0; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); }
void UaServer::Start() { ApplicationDescription appDesc; appDesc.ApplicationName = LocalizedText(Name); appDesc.ApplicationUri = ServerUri; appDesc.ApplicationType = ApplicationType::Server; appDesc.ProductUri = ProductUri; OpcUa::Server::Parameters params; params.Debug = Debug; params.Endpoint.Server = appDesc; params.Endpoint.EndpointUrl = Endpoint; params.Endpoint.SecurityMode = SecurityMode; params.Endpoint.SecurityPolicyUri = "http://opcfoundation.org/UA/SecurityPolicy#None"; params.Endpoint.TransportProfileUri = "http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary"; //setting up policy is required for some client, this should be in a constructor UserTokenPolicy policy; policy.TokenType = UserTokenType::Anonymous; params.Endpoint.UserIdentityTokens.push_back(policy); Addons = Common::CreateAddonsManager(); Server::RegisterCommonAddons(params, *Addons); Addons->Start(); Registry = Addons->GetAddon<Server::ServicesRegistry>(Server::ServicesRegistryAddonId); SubscriptionService = Addons->GetAddon<Server::SubscriptionService>(Server::SubscriptionServiceAddonId); Node ServerArray = GetNode(OpcUa::ObjectId::Server_ServerArray); ServerArray.SetValue(std::vector<std::string>({Endpoint})); EnableEventNotification(); //Enabling event notification, it probably does hurt anyway and users will forgot to set it up }
static void create_11188(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=11188"); node.BrowseName = ToQualifiedName("TreatUncertainAsBad"); node.Class = NodeClass::Variable; node.ParentNodeId = ToNodeId("i=11187"); node.ReferenceTypeId = ReferenceId::HasProperty; node.TypeDefinition = ToNodeId("i=68"); VariableAttributes attrs; attrs.DisplayName = LocalizedText("TreatUncertainAsBad"); attrs.Type = ObjectId::Boolean; attrs.Rank = -1; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); std::vector<AddReferencesItem> refs; { AddReferencesItem ref; ref.IsForward = true; ref.ReferenceTypeId = ReferenceId::HasModellingRule; ref.SourceNodeId = ToNodeId("i=11188"); ref.TargetNodeClass = NodeClass::DataType; ref.TargetNodeId = ToNodeId("i=78"); refs.push_back(ref); } registry.AddReferences(refs); }
Object Object::CreateObject(const NodeId& newNodeId, const NodeId& parentNode, const NodeId& typeId, const QualifiedName& browseName, const std::string& displayName) { Object object(GetServices()); object.Id = InstantiateType(newNodeId, parentNode, typeId, NodeClass::Object, browseName, displayName); object.BrowseName = browseName; object.DisplayName = LocalizedText(displayName); return object; }
static void create_11187(OpcUa::NodeManagementServices & registry) { AddNodesItem node; node.RequestedNewNodeId = ToNodeId("i=11187"); node.BrowseName = ToQualifiedName("AggregateConfigurationType"); node.Class = NodeClass::ObjectType; node.ParentNodeId = ToNodeId("i=58"); node.ReferenceTypeId = ReferenceId::HasSubtype; ObjectTypeAttributes attrs; attrs.DisplayName = LocalizedText("AggregateConfigurationType"); attrs.IsAbstract = false; node.Attributes = attrs; registry.AddNodes(std::vector<AddNodesItem> {node}); std::vector<AddReferencesItem> refs; { AddReferencesItem ref; ref.IsForward = true; ref.ReferenceTypeId = ReferenceId::HasProperty; ref.SourceNodeId = ToNodeId("i=11187"); ref.TargetNodeClass = NodeClass::DataType; ref.TargetNodeId = ToNodeId("i=11188"); refs.push_back(ref); } { AddReferencesItem ref; ref.IsForward = true; ref.ReferenceTypeId = ReferenceId::HasProperty; ref.SourceNodeId = ToNodeId("i=11187"); ref.TargetNodeClass = NodeClass::DataType; ref.TargetNodeId = ToNodeId("i=11189"); refs.push_back(ref); } { AddReferencesItem ref; ref.IsForward = true; ref.ReferenceTypeId = ReferenceId::HasProperty; ref.SourceNodeId = ToNodeId("i=11187"); ref.TargetNodeClass = NodeClass::DataType; ref.TargetNodeId = ToNodeId("i=11190"); refs.push_back(ref); } { AddReferencesItem ref; ref.IsForward = true; ref.ReferenceTypeId = ReferenceId::HasProperty; ref.SourceNodeId = ToNodeId("i=11187"); ref.TargetNodeClass = NodeClass::DataType; ref.TargetNodeId = ToNodeId("i=11191"); refs.push_back(ref); } registry.AddReferences(refs); }
NodeId Object::InstantiateType(const NodeId& newNodeId, const NodeId& parentNode, const NodeId& typeId, NodeClass nodeClass, const QualifiedName& browseName, const std::string& displayName) { // Creating new node for object AddNodesItem newNodeRequest; newNodeRequest.BrowseName = browseName; newNodeRequest.RequestedNewNodeId = newNodeId; newNodeRequest.Class = nodeClass; newNodeRequest.ParentNodeId = parentNode; newNodeRequest.ReferenceTypeId = nodeClass == NodeClass::Object ? ObjectId::HasComponent : ObjectId::HasProperty; newNodeRequest.TypeDefinition = typeId; ObjectAttributes attrs; attrs.Description = LocalizedText(displayName); attrs.DisplayName = LocalizedText(displayName); newNodeRequest.Attributes = attrs; NodeManagementServices::SharedPtr nodes = GetServices()->NodeManagement(); std::vector<AddNodesResult> newObjectNode = nodes->AddNodes({newNodeRequest}); if (newObjectNode.size() != 1) { throw std::runtime_error("opcua_model| Server returned wrong number new nodes results."); } OpcUa::CheckStatusCode(newObjectNode[0].Status); std::map<NodeId, std::vector<ReferenceDescription>> nextRefs; nextRefs.insert({newObjectNode[0].AddedNodeId, BrowseObjectsAndVariables(typeId)}); while(!nextRefs.empty()) { std::map<NodeId, std::vector<ReferenceDescription>> newRefs; for (auto idRefs : nextRefs) { std::map<NodeId, std::vector<ReferenceDescription>> tmpRefs = CopyObjectsAndVariables(idRefs.first, idRefs.second); newRefs.insert(tmpRefs.begin(), tmpRefs.end()); } nextRefs = std::move(newRefs); } return newObjectNode[0].AddedNodeId; }
StatusCode AddressSpaceInMemory::AddReference(const AddReferencesItem& item) { NodesMap::iterator node_it = Nodes.find(item.SourceNodeId); if ( node_it == Nodes.end() ) { return StatusCode::BadSourceNodeIdInvalid; } NodesMap::iterator targetnode_it = Nodes.find(item.TargetNodeId); if ( targetnode_it == Nodes.end() ) { return StatusCode::BadTargetNodeIdInvalid; } ReferenceDescription desc; desc.ReferenceTypeId = item.ReferenceTypeId; desc.IsForward = item.IsForward; desc.TargetNodeId = item.TargetNodeId; desc.TargetNodeClass = item.TargetNodeClass; DataValue dv = GetValue(item.TargetNodeId, AttributeId::BrowseName); if (dv.Status == StatusCode::Good) { desc.BrowseName = dv.Value.As<QualifiedName>(); } else { desc.BrowseName = QualifiedName("NONAME", 0); } dv = GetValue(item.TargetNodeId, AttributeId::DisplayName); if (dv.Status == StatusCode::Good) { desc.DisplayName = dv.Value.As<LocalizedText>(); } else { desc.DisplayName = LocalizedText(desc.BrowseName.Name); } node_it->second.References.push_back(desc); return StatusCode::Good; }
AddNodesResult AddressSpaceInMemory::AddNode( const AddNodesItem& item ) { AddNodesResult result; if (Debug) std::cout << "AddressSpaceInternal | address_space| Adding new node id='" << item.RequestedNewNodeId << "' name=" << item.BrowseName.Name << std::endl; if (!Nodes.empty() && item.RequestedNewNodeId != ObjectId::Null && Nodes.find(item.RequestedNewNodeId) != Nodes.end()) { std::cerr << "AddressSpaceInternal | Error: NodeId '"<< item.RequestedNewNodeId << "' allready exist: " << std::endl; result.Status = StatusCode::BadNodeIdExists; return result; } NodesMap::iterator parent_node_it = Nodes.end(); if (item.ParentNodeId != NodeId()) { parent_node_it = Nodes.find(item.ParentNodeId); if ( parent_node_it == Nodes.end() ) { if (Debug) std::cout << "AddressSpaceInternal | Error: Parent node '"<< item.ParentNodeId << "'does not exist" << std::endl; result.Status = StatusCode::BadParentNodeIdInvalid; return result; } } const NodeId resultId = GetNewNodeId(item.RequestedNewNodeId); NodeStruct nodestruct; //Add Common attributes nodestruct.Attributes[AttributeId::NodeId].Value = resultId; nodestruct.Attributes[AttributeId::BrowseName].Value = item.BrowseName; nodestruct.Attributes[AttributeId::NodeClass].Value = static_cast<int32_t>(item.Class); // Add requested attributes for (const auto& attr: item.Attributes.Attributes) { AttributeValue attval; attval.Value = attr.second; nodestruct.Attributes.insert(std::make_pair(attr.first, attval)); } Nodes.insert(std::make_pair(resultId, nodestruct)); if (parent_node_it != Nodes.end()) { // Link to parent ReferenceDescription desc; desc.ReferenceTypeId = item.ReferenceTypeId; desc.TargetNodeId = resultId; desc.TargetNodeClass = item.Class; desc.BrowseName = item.BrowseName; desc.DisplayName = LocalizedText(item.BrowseName.Name); desc.TargetNodeTypeDefinition = item.TypeDefinition; desc.IsForward = true; // should this be in constructor? parent_node_it->second.References.push_back(desc); } if (item.TypeDefinition != ObjectId::Null) { // Link to parent AddReferencesItem typeRef; typeRef.SourceNodeId = resultId; typeRef.IsForward = true; typeRef.ReferenceTypeId = ObjectId::HasTypeDefinition; typeRef.TargetNodeId = item.TypeDefinition; typeRef.TargetNodeClass = NodeClass::DataType; AddReference(typeRef); } result.Status = StatusCode::Good; result.AddedNodeId = resultId; if (Debug) std::cout << "AddressSpaceInternal | node added." << std::endl; return result; }