Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
Set node values from client to server
July 20, 2022
12:21, EEST
Avatar
Sabari
Member
Members
Forum Posts: 46
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Hello,
I have two applications, one is an opc ua client and the other an opc ua server. Both use the same information model.
In this information model, I have a Machine type. I create the machine information in the client application. My wish is to use the opc ua client to connect and update the corresponding machine node in the opc ua server.
Is there any way to do this with the SDK?

Thanks

July 20, 2022
15:23, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 946
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

Well, yes there should be a way, although I didn’t quite understand what you expect to happen.

You can use the information model to generate code for both client and server side development. This will help you working with complete Java objects that represent the Machines.

But, there is no automatic way to create a new Machine object in the client and make it appear in the server. Or if you change the attributes of the client side object, they are not automatically copied to the server.

You will need to use the UaCliient.write (writeAttributes, etc) to modify attribute values to the server objects. And if you wish to add or remove objects, you need to

#1 enable node management

server.getAddressSpace().setNodeManagementEnabled(true);

#2 call addNode/addNodes or deleteNode/deleteNodes from the client to add the objects to the server, one node at a time.

client.getAddressSpace().addNode(…);

Does this answer your question?

July 20, 2022
17:16, EEST
Avatar
Sabari
Member
Members
Forum Posts: 46
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Hello,
Thanks for your response.
Should i implement on my server an IOManager ?

July 20, 2022
18:13, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 946
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

The IOManager is responsible of responding to read and write requests. If you use the NodeManagerUaNode, it uses the default IoManagerUaNode that copies values directly to the nodes.

So, only if you have a custom NodeManager, should you need a custom IoManagaer as well.

You can still plug an IoManagerListener to the default IoManager to validate client requests, if you need to do so.

July 22, 2022
13:45, EEST
Avatar
Sabari
Member
Members
Forum Posts: 46
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Hello,
Thanks for your response.
So if i want to add a node in folder from client, how can i
do that with :

client.getAddressSpace().addNode(…);
July 22, 2022
16:01, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 946
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

OK, you can test it like this.

Add the following Action to the SampleConsoleServer (beginning of the class), if you don’t have a server that supports NodeManagement yet:

ENABLE_NODE_MANAGEMENT(‘N’, "enable/disable node management services") {
@Override
ActionResult performAction(SampleConsoleServer s) {
boolean value = !s.getServer().getAddressSpace().getNodeManagementEnabled();
s.getServer().getAddressSpace().setNodeManagementEnabled(value);
println("NodeManagement " + (value ? "enabled" : "disabled"));
return ActionResult.NOTHING;
}
},

This adds a toggle ‘N’ that you can use to enable Node Management in the server.

then you can add the following method to SampleConsoleClient – or your own client without the ‘println’ and ‘prompt’ calls:

protected void addNode(NodeId parentNodeId) throws ServiceException, EncodingException, StatusException {
println("Adding a new node to the current node");
println("Name:");
String name = readInput(false);
NodeId typeDefinitionId = Identifiers.BaseObjectType;
NodeId referenceTypeId = Identifiers.HasComponent;

int ns = parentNodeId.getNamespaceIndex();
NodeId newNodeId = new NodeId(ns, parentNodeId.getValue().toString() + "/" + name);
QualifiedName browseName = new QualifiedName(ns, name);
LocalizedText displayName = new LocalizedText(name);
UnsignedInteger attributesMask = NodeAttributesMask.getMask(NodeAttributesMask.DisplayName);
ObjectAttributes nodeAttributes = new ObjectAttributes(attributesMask, displayName, null, null, null, null);
client.getAddressSpace().addNode(parentNodeId, referenceTypeId, newNodeId, browseName, NodeClass.Object,
nodeAttributes, typeDefinitionId);
}

‘prompt’ is actually a new method as well

This adds just a node of BaseObjectType to the server, but you can modify it to your needs.

Note that even when you have enabled Node Management, the server requires that you connect with a non-Anonymous UserIdentity. SampleConsoleClient takes the username (-u) and password (-p) from the command line, for example.

Also, you cannot add nodes to nodes that are in the standard Namespace, so you have to browse to MyObjects, for example, before it works.

So, this should help you to get started.

July 22, 2022
17:23, EEST
Avatar
Sabari
Member
Members
Forum Posts: 46
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Thank you for your help.
Now, using the sample code you post, i can add new node of BaseObjectType on my server from client.
So have another question, to create a node with my custom type MachineType, how can i do that ?
In my client a have generated the informaion model and i have MachineType and MachineTypeImpl

Thanks you in advance

July 25, 2022
11:31, EEST
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 836
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Hi,

Based on the above my assumption is that you are also using our SDK in the server side.

Assuming the information model is loaded in the server side, you basically change the typeDefinitionId in the code above to be the MachineType TypeDefinition node (the in the Types part, I’m assuming it is an ObjectType node).

Assuming NodeManagerUaNode is the manager handling the namespace on the server side, it will do the same thing as a (NodeManagerUaNode).createInstance(…) call would (see SampleConsoleServer + MyNodeManager for creating e.g. the alarm node), i.e. create all Mandatory nodes below that type. Any Optionals you would need to create yourself however, unless configured in the manager (basically the server would have then to be made to expect AddNodes to be done like this, see also the alarm creation in the MyNodeManager sample)

However, also note that this doesn’t “automatically” persist these changes in the server, unless the server reacts to it i.e. on a restart it would lose the changes.

You can note the AddNodes happening via a NodeManagerListener.onAddNode (or onAfterAddNode). The logic of making the node happens in ‘protected UaNode createNodeForAddNodesRequest(NodeId nodeId, QualifiedName browseName, NodeClass nodeClass, ExpandedNodeId typeDefinitionId, LocalizedText displayName)’, which can be overridden if needed. There is ‘createNodeForNodeSet2’ also when the nodes are loaded from a NodeSet2 file. Do note the difference is that when loading a NodeSet, it must contain all the nodes, but when the client calls AddNodes, the server shall make all Mandatory nodes below the type given (BaseObjectType has none, thus only that node was created). And also this behaviour was clarified at some point in the spec, i.e. some older servers might incorrectly just do the “top-lvl” node in types.

IF the server doesn’t even have the TypeDefinition, you can create that node-by-node via AddNodes (NodeClasses ObjectType+VariableType and for the structure other ones as well), and then use the NodeId of the Type later (the instantiation doesn’t need Codegen, just for the types to exist, and in the presense of Codegen classes those more-specific-uanode implementations would be used).

P.S. IMPORTANT
Also consider adding user validation via the NodeManagerListener to all NodeManagers, as otherwise any client that can make sessions on the server can e.g. delete the ‘Server’ node. Thus you should check that and throw a StatusException if the operation is not allowed (this is why the nodemanagement is by default disabled). If you trust and know all clients then this might not be needed.

July 25, 2022
11:57, EEST
Avatar
Sabari
Member
Members
Forum Posts: 46
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Hi,
Thank you for the explanations.
My question is how to change the TypeDefinition in the code below

NodeId typeDefinitionId = Identifiers.BaseObjectType;

to be the MachineType TypeDefinition ?

July 25, 2022
16:29, EEST
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 836
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Put the NodeId of the MachineType “type node” there. This is assuming my assumption was correct that the information model is loaded on the server side. If not you would need to load them first to the server.

Anyway, assuming the model is loaded in the Server, look with a graphical client such as our https://www.prosysopc.com/products/opc-ua-browser/ in the Types part of the server.

Alternatively, since you have generated the model in the client side, there is a XXXIds class, where XXX is the “prefix” in the configuration when generating. If no prefix was used the class is just ‘Ids’. IMPORTANT, the SDK already also includes an ‘Ids’ class internally, for the base namespace, thus be careful which class you import if this is the case (the prefix is preferred).

And technically com.prosysopc.ua.AnnotationUtils.readTypeDefinitionId(MachineType.class) would also give it, though the Ids-way would be the expected way instead of this.

Also for the first approach, we would recommend storing the NodeId as an ExpandedNodeId with the NamespaceUri instead of the NamespaceIndex (the number X in the NodeId ns=X;…) (the index points to Objects/Server/NamespaceArray the string at that index in the value is the NamespaceUri of that namespace), and then transforming it to NodeId in the context of (UaClient)client.getNamespaceTable(). This is also what you would do with the Ids output (since the generator cannot know which index it would be they are ExpandedNodeIds with the uri).

July 27, 2022
12:39, EEST
Avatar
Sabari
Member
Members
Forum Posts: 46
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Hi,
Thanks, these explanations help me to create a MachineType node in my server.
To write values from my client, i used uaClient.writeValues(nodeIds, values).

Now I want to insert in database with my server application, the information of the written node.
I want this insertion in the database to happen only when the writing of the node opc ua has been successful.
My question is there a way to know that the writing of the node has been successful? Can I manage this behavior with an IOManagerListner?

July 27, 2022
16:16, EEST
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 836
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Well, in general I would say you would want to do it the other way around: only set the value to the node once you have successfully written it to the DB. Otherwise the client would see the value, but if e.g. the server machine crashed just there before it was written to the DB on a restart that value would be lost. If done database-first it would not be.

Basically at the point when the IoManagerListener onXXX are being called, the accesslevel and datatype have been checked, so basically unless you prevent it in the listener it will be successful. Thus you could write it to the DB within the listener method.

July 28, 2022
15:51, EEST
Avatar
Sabari
Member
Members
Forum Posts: 46
Member Since:
June 21, 2021
sp_UserOfflineSmall Offline

Hi,
thanks, it’s works !

Forum Timezone: Europe/Helsinki

Most Users Ever Online: 267

Currently Online:
11 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

hbrackel: 122

pramanj: 86

ibrahim: 74

rocket science: 65

kapsl: 57

gjevremovic: 49

Sabari: 46

Xavier: 42

fred: 41

TimK: 41

Member Stats:

Guest Posters: 0

Members: 3344

Moderators: 17

Admins: 1

Forum Stats:

Groups: 3

Forums: 15

Topics: 1300

Posts: 5561

Newest Members:

UPtato42, fblvicky6629601, elliebloomer44, Manuelagibe, justinafavenc54, sarlaman9, nancymcneal1, elztaim591797, JeffreyAidet, sameisenhower7

Moderators: Jouni Aro: 946, Otso Palonen: 32, Tuomas Hiltunen: 5, janimakela: 0, Pyry: 1, Terho: 0, Petri: 0, Bjarne Boström: 836, Heikki Tahvanainen: 402, Jukka Asikainen: 1, moldzh08: 0, Jimmy Ni: 25, Teppo Uimonen: 21, Markus Johansson: 41, Niklas Nurminen: 0, Matti Siponen: 221, Lusetti: 0

Administrators: admin: 1