PHP Classes

File: doc/16-node-management.md

Recommend this page to a friend!
  Packages of Gianfrancesco Aurecchia   OPC UA Client   doc/16-node-management.md   Download  
File: doc/16-node-management.md
Role: Auxiliary data
Content type: text/markdown
Description: Auxiliary data
Class: OPC UA Client
Control devices that support the OPC UA protocol
Author: By
Last change:
Date: 4 days ago
Size: 7,440 bytes
 

Contents

Class file image Download

Node Management

OPC UA servers that support dynamic address space modification allow clients to add and remove nodes and references at runtime. This library provides four methods for these operations.

> Note: Not all OPC UA servers support node management. Notably, the UA-.NETStandard reference implementation does not implement NodeManagement ? the library's integration coverage runs against an open62541 container provided by php-opcua/extra-test-suite (see doc/13-testing.md). > > NodeManagementModule ships in ClientBuilder::defaultModules() ? no opt-in required. The client does not probe the server at connect time, so there is zero overhead for users who never call these methods. If the server does not implement the service set, the first call to addNodes() / deleteNodes() / addReferences() / deleteReferences() raises Exception\ServiceUnsupportedException ? a subclass of ServiceException carrying ServiceResult = 0x800B0000 (BadServiceUnsupported). Subsequent calls behave identically (there is no runtime capability cache; if you want to avoid the re-throw, check once and guard at the call site). > > `php > use PhpOpcua\Client\Exception\ServiceUnsupportedException; > > try { > $client->addNodes([...]); > } catch (ServiceUnsupportedException $e) { > // server doesn't implement NodeManagement ? fall back or skip > } > `

Adding Nodes

use PhpOpcua\Client\Types\AddNodesResult;
use PhpOpcua\Client\Types\NodeClass;
use PhpOpcua\Client\Types\NodeId;
use PhpOpcua\Client\Types\QualifiedName;
use PhpOpcua\Client\Types\StatusCode;

// Add a Variable node under the Objects folder
$results = $client->addNodes([
    [
        'parentNodeId'       => 'i=85',                          // Objects folder
        'referenceTypeId'    => 'i=35',                          // Organizes
        'requestedNewNodeId' => 'ns=2;s=MyVariable',             // desired NodeId
        'browseName'         => new QualifiedName(2, 'MyVariable'),
        'nodeClass'          => NodeClass::Variable,
        'typeDefinition'     => 'i=63',                          // BaseDataVariableType
        'dataType'           => NodeId::numeric(0, 6),           // Int32
        'accessLevel'        => 3,                               // CurrentRead | CurrentWrite
    ],
]);

foreach ($results as $result) {
    if (StatusCode::isGood($result->statusCode)) {
        echo "Created: {$result->addedNodeId}\n";
    }
}

Each item in the array produces one AddNodesResult with a statusCode and the server-assigned addedNodeId.

Supported Node Classes

All 8 OPC UA node classes are supported. The library encodes class-specific attributes automatically:

| Node Class | Extra Fields | |---|---| | Object | eventNotifier | | Variable | dataType, valueRank, arrayDimensions, accessLevel, userAccessLevel, minimumSamplingInterval, historizing, value | | Method | executable, userExecutable | | ObjectType | isAbstract | | VariableType | dataType, valueRank, arrayDimensions, isAbstract, value | | ReferenceType | isAbstract, symmetric, inverseName | | DataType | isAbstract | | View | containsNoLoops, eventNotifier |

Common fields for all classes: displayName, description, writeMask, userWriteMask. If displayName is omitted, the browse name is used.

Adding an Object Node

$results = $client->addNodes([
    [
        'parentNodeId'       => 'i=85',
        'referenceTypeId'    => 'i=35',
        'requestedNewNodeId' => 'ns=2;s=MyFolder',
        'browseName'         => new QualifiedName(2, 'MyFolder'),
        'nodeClass'          => NodeClass::Object,
        'typeDefinition'     => 'i=61',  // FolderType
    ],
]);

Adding Multiple Nodes

$results = $client->addNodes([
    [
        'parentNodeId'       => 'i=85',
        'referenceTypeId'    => 'i=35',
        'requestedNewNodeId' => 'ns=2;s=Node1',
        'browseName'         => new QualifiedName(2, 'Node1'),
        'nodeClass'          => NodeClass::Variable,
        'typeDefinition'     => 'i=63',
    ],
    [
        'parentNodeId'       => 'i=85',
        'referenceTypeId'    => 'i=35',
        'requestedNewNodeId' => 'ns=2;s=Node2',
        'browseName'         => new QualifiedName(2, 'Node2'),
        'nodeClass'          => NodeClass::Variable,
        'typeDefinition'     => 'i=63',
    ],
]);

// $results[0] corresponds to Node1, $results[1] to Node2

Deleting Nodes

$statusCodes = $client->deleteNodes([
    ['nodeId' => 'ns=2;s=MyVariable', 'deleteTargetReferences' => true],
    ['nodeId' => 'ns=2;s=MyFolder'],  // deleteTargetReferences defaults to true
]);

foreach ($statusCodes as $code) {
    echo StatusCode::isGood($code) ? "Deleted\n" : "Failed: " . StatusCode::getName($code) . "\n";
}

Adding References

$statusCodes = $client->addReferences([
    [
        'sourceNodeId'    => 'ns=2;s=MyFolder',
        'referenceTypeId' => NodeId::numeric(0, 35),  // Organizes
        'isForward'       => true,
        'targetNodeId'    => 'ns=2;s=MyVariable',
        'targetNodeClass' => NodeClass::Variable,
    ],
]);

Deleting References

$statusCodes = $client->deleteReferences([
    [
        'sourceNodeId'       => 'ns=2;s=MyFolder',
        'referenceTypeId'    => NodeId::numeric(0, 35),
        'isForward'          => true,
        'targetNodeId'       => 'ns=2;s=MyVariable',
        'deleteBidirectional' => true,  // also remove the inverse reference
    ],
]);

Full Example: Create, Use, and Clean Up

use PhpOpcua\Client\Types\BuiltinType;

// 1. Create a folder and a variable
$results = $client->addNodes([
    [
        'parentNodeId'       => 'i=85',
        'referenceTypeId'    => 'i=35',
        'requestedNewNodeId' => 'ns=2;s=TempFolder',
        'browseName'         => new QualifiedName(2, 'TempFolder'),
        'nodeClass'          => NodeClass::Object,
        'typeDefinition'     => 'i=61',
    ],
    [
        'parentNodeId'       => 'ns=2;s=TempFolder',
        'referenceTypeId'    => 'i=47',  // HasComponent
        'requestedNewNodeId' => 'ns=2;s=TempValue',
        'browseName'         => new QualifiedName(2, 'TempValue'),
        'nodeClass'          => NodeClass::Variable,
        'typeDefinition'     => 'i=63',
        'dataType'           => NodeId::numeric(0, 11),  // Double
        'accessLevel'        => 3,
    ],
]);

// 2. Write and read
$client->write('ns=2;s=TempValue', 23.5, BuiltinType::Double);
$dv = $client->read('ns=2;s=TempValue');
echo $dv->getValue(); // 23.5

// 3. Clean up
$client->deleteNodes([
    ['nodeId' => 'ns=2;s=TempValue'],
    ['nodeId' => 'ns=2;s=TempFolder'],
]);

Error Handling

Common status codes returned by node management operations:

| Status Code | Meaning | |---|---| | 0x00000000 (Good) | Operation succeeded | | 0x800B0000 (BadServiceUnsupported) | Server does not support this service | | 0x80340000 (BadNodeIdUnknown) | Node does not exist (delete) | | 0x80330000 (BadNodeIdExists) | Requested NodeId already exists (add) | | 0x80480000 (BadParentNodeIdInvalid) | Parent node not found or invalid | | 0x80620000 (BadReferenceNotAllowed) | Reference type not valid for the target |