In our OPC UA server we have automatically generated code (using UaModeler) from a rather large information model. When server starts up the information model is loaded and all mandatory nodes are created in a tree of nodes. Then, when external devices sends new data to the server, the server uses its mapping of data to the relevant nodes in the node tree, which are then updated with fresh data, which OPC UA clients can read. All this works really good :-)
Now comes the next use case: some of the data in the information model is not only readable but also writeable, and an OPC UA client may want to write some of that data. How shall the server detect client writes in order to handle the new OPC UA client data?
This use case sure must be common so I thought I could easily find information how to do this, but to my surprise the documentation does not give a clear answer (to me) and I have therefore no idea what should be done on the server side. I was expecting to find some kind of virtual method/callback newClientData(Session, NodeId, Data) maybe in one of the Server/Session classes, but have not found it - yet...
Advise is very much appreciated!
Regards,
/Tommy
How to handle OPC UA Client writes in our OPC UA Server...
Moderator: uasdkcpp
-
- Sr. Member
- Posts: 15
- Joined: 03 Oct 2023, 16:42
- Support Team
- Hero Member
- Posts: 3078
- Joined: 18 Mar 2011, 15:09
Re: How to handle OPC UA Client writes in our OPC UA Server...
Hi,
there is an extensive example in the documentation regarding readValues and writeValues when having external source:
https://documentation.unified-automation.com/uasdkcpp/1.8.3/html/L3GettingStartedLesson03.html
Whenever a client writes a value you will always enter the writeValues method and you can do the magic (accessing the underlying target).
For other use case (e.g. having in memory copy of nodes) you may want to lok into the "beforeSetAttributeValue" and the "afterSetAttributeValue" as being described here:
https://documentation.unified-automation.com/uasdkcpp/1.8.3/html/classIOManagerUaNode.html#aaad421a7d9f7a6d8b78e7124cd45b546
and
https://documentation.unified-automation.com/uasdkcpp/1.8.3/html/classIOManagerUaNode.html#acd75cc99df0a6e8b1b88965adeac4fa0
This will give you oportunity to do the magic (e.g. check/reject/manipulate) before the value attribute hits the target.
there is an extensive example in the documentation regarding readValues and writeValues when having external source:
https://documentation.unified-automation.com/uasdkcpp/1.8.3/html/L3GettingStartedLesson03.html
Whenever a client writes a value you will always enter the writeValues method and you can do the magic (accessing the underlying target).
For other use case (e.g. having in memory copy of nodes) you may want to lok into the "beforeSetAttributeValue" and the "afterSetAttributeValue" as being described here:
https://documentation.unified-automation.com/uasdkcpp/1.8.3/html/classIOManagerUaNode.html#aaad421a7d9f7a6d8b78e7124cd45b546
and
https://documentation.unified-automation.com/uasdkcpp/1.8.3/html/classIOManagerUaNode.html#acd75cc99df0a6e8b1b88965adeac4fa0
This will give you oportunity to do the magic (e.g. check/reject/manipulate) before the value attribute hits the target.
Best regards
Unified Automation Support Team
Unified Automation Support Team
-
- Sr. Member
- Posts: 15
- Joined: 03 Oct 2023, 16:42
Re: How to handle OPC UA Client writes in our OPC UA Server...
The before/afterSetAttributeValue is probably what I was looking for, thanks! I understand that I need to subclass the automatically generated NodeManager for our information model and then just override these two methods, pretty straightforward :-)
The example in lesson3 seems to rely on having all writable data derive from UserDataBase, which is not possible I guess, since we use automatically generated code from an information model that says nothing about a UserDataBase type. Maybe one can instruct UaModeler to generate code that derives from UserDataBase if the variable type is writable? But I do not see how this approach would be better than using before/afterSetAttributeValue for our case so I'll go with that approach.
Regards,
/Tommy
The example in lesson3 seems to rely on having all writable data derive from UserDataBase, which is not possible I guess, since we use automatically generated code from an information model that says nothing about a UserDataBase type. Maybe one can instruct UaModeler to generate code that derives from UserDataBase if the variable type is writable? But I do not see how this approach would be better than using before/afterSetAttributeValue for our case so I'll go with that approach.
Regards,
/Tommy