OPC server create model information from existing nodeset file - opc-ua

I have a task that is create an opc server and instantaneously read data from an injection molding cnc machine with opc client. I have read a lot of documentation and came to a conclusion which I need a model information xml file and create c# classes with a compiler according to the model information file.
I have come across with OPCFoundation/UA-Nodeset repository which has Node Id's that plastic rubber devices shares.(I assume that) There is also a Opc.Ua.PlasticsRubber.IMM2MES.NodeSet2.xml file which is the final ingredient that model compiler produces.
Also I assume when I point my opc server address to the molding cnc device, I will read or machine push data with those spesific nodeIds.(I might be awfully wrong here)
Now the confusion begins here; In the Opc.Ua.PlasticsRubber.IMM2MES.NodeSet2.xml, there are some nodeIds presented. Is the data presented by the molding device published with that nodeIds or those id's are just a unique key for model file? Also when I try to create model information file, nodeId's are different. Is nodeIds should match with the nodeset2.xml?
In the end, I want to read lets say machine status data which nodeId is 5006, should match the model information file which I created in order to get data?
Thank you.

The nodeset in the Companion Specification usually contains only Types (such as ObjectTypes, VariableTypes, etc.) and sometimes an object that serves as an entry point (e.g. DeviceSet of DI). To use these types, you need to create an instance of an object in the address space of your OPC UA server. For example, in your case, the instance might be of the IMM_MES_InterfaceType. The nodes of your instance will have different nodeIds than the types.
As an OPC UA client, you should use the BrowsePath (and the browse service) to locate the correct node in the address space. Once you have the nodeId, you can read or write data from it. In the first step, you can use a generic OPC UA client such as UaExpert for browsing, but it is recommended to implement browsing in your own application. This will allow you to connect to other machines with the same interface.
In think your BrowsePath for the MachineStatus should something like this:
Objects.DeviceSet.IMM_<Manufacturer>_<SerialNumber>.MachineStatus
An example of an plastic rubber devices should be here

Related

OPC UA TranslateBrowsePathsToNodeIds: How stable/volatile are resolved NodeIDs

there is a OPC UA service TranslateBrowsePathsToNodeIds.
How volatile or stable are the NodeIDs results returned by the service ---
Is it possible that NodeIDs resolved by the service alter while server runtime?
In our Case we are running our client against a server, which enumerates NodeIDs differently on every server restart. So we decide to resolve IDs by BrowsePath once after each (re)connect to the server. So far so good. But now there is a Problem when the server is restartet and after the first client reconnect no paths can't resolved.. it seems the server is not ready for the job (...).
I am wondering how often I have to update the resolved Node IDs (all or just the onces which was not resolved correctly?).
We are reading data by polling in this case.
I don't know your server, but it seems, you do address an OPC UA Server with a very dynamic behaviour, But I think, it's within the OPC UA spec.
It depends on the OPC UA objects, this server offers and what a client should or wants do with them.
Is it possible that NodeIDs resolved by the service alter while server runtime?
Yes!
Many servers do offer a static node set from the device configuration. In this case, the client will always get the same node ids from TranslateBrowsePathsToNodeIds, the client may use the node ids directly without translation (but has always to resolve the namespace index after connecting to the server). But obviously it's not your kind of server.
Another use case are dynamic objects, with a restricted lifetime, coming and going on any time they want to come an go. Imagine a warehouse in which goods are received and delivered. So a good will be representent with an individual OPC UA object instance, created on receive and removed on delivery. As long the good exists in the warehouse, you may browse to the object, translate its browse pathes to node ids and use them (reading, writing, monitoring). Of course, when the good delivers, the UA object will no longer be needed and could be removed by the server. The node ids removed now could be used later in an other context for another object instance.
Alternatively, the server could offer an interface to create or remove objects with a client.
The question is, how the server deals with the creation or removal of it's objects, how does it announce the changes? There should be a kind of configuration change event you want to monitor with your client. When your client receives an event, it may decide which actions to do, e.g. rebrowse the object and translate the browse pathes. Read the manual!
By the way: TranslateBrowsPathsToNodeIds is widly used to adress subnodes of object instances with a known object type. Once you know the node id for the entire object, you easily get the node ids for the subnodes with their browse pathes.

Retrieving a node solely based on its Tag

A customer has implemented an OPC-UA server and has provided some documentation for us to access it. The only information we have is the endpoint to contact the server at and the tags that the data points are linked to.
I have to implement a client without having access to the server to test it with. Is this enough information to go by? I imagine we would at least need some namespace uri. From what I understand, in order to use a function such as translateBrowsePathsToNodeIds I would also need to know some namespace ID's.
For instance, in python-opcua it would be something like:
mynode = client.uaclient.translate_browsepaths_to_nodeids(ua.QualifiedName("StaticData", 3)) (which somehow is not working but that's another question)
It doesn't help that the client examples I find somehow all use hardcoded namespace ID's.
TranslateBrowsePathToNodeIds is generally used when programming against type definitions where you know what the path of BrowseNames will be because they are defined by the type definition of each node in the path.
If this doesn't sound like your situation then you should push back for the documentation to include the NodeIds of all the Nodes you need to access.

Livetime / uniqueness of NodeId (How to manage NodeIds for dynamic nodes)

The Specification (Part 3: Address Space Model) of OPC UA says
5.2.2 NodeId
... A Server shall persist the NodeId of a Node, that is, it shall not
generate new NodeIds when rebooting.
but how can this be?
NodeId is a combination from a NamespceIndex and Identifier. NamespceIndex can be changed when the Server is restarting. see:
http://documentation.unified-automation.com/uasdkhp/1.0.0/html/_l2_ua_node_ids.html
For this reason, a Client should not persist the namespace index without storing the namespace URI as well, because a namespace URI represented by index “2” during one session could be represented by index “5” during the next session
Also the use of FolderType with e.g. "Files" as Items speak again this, or should the server store the NodeId it uses for File-X to assign it right again after restart?
What for is "GenericModelChangeEventType" if no NodeId can be created?
Client: I thought useing BrowsePath-Path (e.g. "Objects.Server.ServerStatus.CurrentTime" (* ) ) for addressing NodeIds and then using the NodeId while the clinet session to access the nodes is a good approach. Also because Companion Specifications defines the browsename so I might by save. Is this a good idea? ( *need attention on collisions caused by different namespaces)
Server: How should the Server behave when it needs to generate/create new NodeIds. Need the NodeIds to be unambiguous all the time or just for the Server runtime. I know some Servers are using NodeIds with String-Typed Identifiers and this String-Identifiers are made from the BrowsePath e.g. "ns=1;s=Server.ServerStatus.CurrentTime". But I don't like this...
What the OPC UA spec means when it says " A Server shall persist the NodeId of a Node, that is, it shall not generate new NodeIds when rebooting." is as follows: The NodeIds, when seen as a combination of namespace URI and identifier, must not change. The server may or may not reassign namespace indices after reboot - but the resulting namespaceURI/Identifier must not change. So, if on the first run I had a node with Identifier 1234 and namespace index 7, and that namespace index corresponded to "http://mynamespace.mycompany.com" in the namespace table, on the second run the same node may have Identifier 1234, but the namespace index 8, as long as in the new NamespaceTable index 8 now corresponds to "http://mynamespace.mycompany.com".
I think the Unified Automation SDK technically violates the spec in this regard. The recommendation it suggests is good practice for client implementations either way, but as you pointed out, shouldn't strictly be necessary.
Also the use of FolderType with e.g. "Files" as Items speak again this, or should the server store the NodeId it uses for File-X to assign it right again after restart?
I'm not sure what you're asking here.
What for is "GenericModelChangeEventType" if no NodeId can be created?
That's not what is being said here. Nodes can be created and deleted and the structure of objects and variables can change. All the spec is saying is that given Node "Foo" with NodeId "ns=1;s=Foo" it should have the same NodeId if the server reboots.
I thought useing BrowsePath-Path (e.g. "Objects.Server.ServerStatus.CurrentTime" (* ) ) for addressing NodeIds and then using the NodeId while the clinet session to access the nodes is a good approach.
Browse paths are for programming against types. The approach suggested by the Unified Automation SDK docs is the safe one for persisting NodeIds in your client.
How should the Server behave when it needs to generate/create new NodeIds. Need the NodeIds to be unambiguous all the time or just for the Server runtime. I know some Servers are using NodeIds with String-Typed Identifiers and this String-Identifiers are made from the BrowsePath e.g. "ns=1;s=Server.ServerStatus.CurrentTime". But I don't like this...
Create them however you like in the Namespaces you control, it's up to you. Using string-based NodeIds allows you to easily "derive" the NodeId from certain other sources, though, e.g. from the address of a variable in a PLC or something similar.

OPC UA - Client - Milo - Best Practice - Subscription to Data Change

I started a OPC UA project using the Milo project to create a OPC UA Client. I am still very new to OPC UA. Right now I am stuck looking for the best practice to read values from several Nodes after a data change of one specific node.
The information model looks like this:
RfidSensorType
On my server i will have several objects of this RfidSensorType. The client creates a subscription on the CurrentAtTag Node to listen for data changes.
My Question:
When the value of CurrentAtTag is changed a callback function will be called in my client which contains the UaMonitoredItem and the DataValue of the CurrentAtTag.
In my application i need to process (at the same time) also the values of Station, IOLPort and CurrentValue which are changed at that moment too.
How can i access those values within the callback from CurrentAtTag?
My only solution is: Using a synchronous read request within that callback
-> Is that an legit approach?
My Research:
1) TriggeringService
I've seen that a TriggerigService exists, which monitors items will send reports only if one specific node changes it values.
Problem: This will call several callsbacks and noz just one..i need all the informations at the same time to further process them..
2) Event Monitoring
In event monitoring one can select "Event fields" which will be returned for each Event notificaiton. I am not sure if i could select the CurrentAtTag, Station, IOLPort and CurrentValue...
Just like you can subscribe to the server's ServerStatus (nodeid "i=2256"), you should be able to subscribe to the nodeid corresponding to 'RfidSensor_Station1'. The server will send PublishResponse with data of type 'RfidSensorType' encoded as an ExtensionObject. The trick is decoding the ExtensionObject.
As Kevin corrected, because 'RfidSensor_Station1' is not node class 'Variable' then it doesn't have a value attribute and you can not monitor the node for data changes. If you are using a PLC, I might combine all properties of the sensor into a string, or byte array. Then I monitor the new variable, and parse the string in the client.
Or you could make ReadRequest as you describe. That will work just fine.

OPC UA unique ID

I'm trying to build a OPC UA client application.
I'd like to be able to identify a UA node uniquely in the OPC tree.
I know that in OPC DA, a standard node id is a string with a '.' as a delimeter that I can use in order to identify a node.
In OPC UA, the node ID doesn't have to be a string, but I'd still like to be able to build a unique string that maps to a particular node.
I'm thinking about basing it on the the nodes names. e.g.: Demo.MyNode.MyValue.
but I'm afraid that the node name can contain characters such as "." and this will make my IDs not unique.
Is there a character I can use as a delimeter?
Is there a better way to represent the node ID as a string (including its path)?
OPC-UA offers the concept of a unique "BrowsePath" for each and every node, and a client could opt to store BrowsePaths instead of NodeIds, and then upon startup call the TranslateBrowsePathsToNodeIds service.
In fact, I believe this may be the intended behavior, as there's no requirement that a server use the same NodeId for any given Node after restarting, even if in practice that's how it's done.
I was wrong about NodeId being allowed to change. The spec says: "A Server shall persist the NodeId of a Node, that is, it shall not generate new NodeIds when rebooting."
I now believe its best to store NodeIds and only use BrowsePaths to aid in programming against type definitions.
One of the features of OPC UA is that the server can offer different menu trees to different users. It may not matter for your client, since any given user will only see the one tree, and the BrowsePath will be unique for that user.
In v1.03 of Part 3 of the OPC UA spec, "OPC UA Part 3 - Address Space Model 1.03 Specification.pdf", section 5.2.2 says a server should not change a node's NodeId when it reboots. (The spec is available from the OPC Foundation at https://opcfoundation.org. You can register and download it for free.)
Of course, some UA servers might not maintain their NodeIDs across a reboot. Which is another reason to use Kevin's suggestion to use the BrowsePath to make a unique string for each node. The string can make it clearer to the user which node they're accessing. Good idea!
The OPC Foundation announced their “OPC UA Open Shared Source” Strategy (04/14/2015).
The stack for .NET including lots of samples for DA, Historie... clients and servers can freely be downloaded here OPCFoundation/UA-.NET on GitHub.
Also Build OPC UA .NET applications using C#, VB.NET
You can take a look at the samples in the "SampleApplications" directory and see how they do things...