FreeOpcUa / python-opcua

LGPL Pure Python OPC-UA Client and Server
http://freeopcua.github.io/
GNU Lesser General Public License v3.0
1.36k stars 658 forks source link

Right way to implement a node with ns index #575

Open mar-ar opened 6 years ago

mar-ar commented 6 years ago

Hi,

I want to implement my own address space with my own namespace. My problem ist that I cant find a way to give a node a namespace. First i thought i can just do it with "ns=" but with the code below my BrowsName is still "0:BaseInterface" and thereby in the standard address space.

`node = ua.AddNodesItem()

node.RequestedNewNodeId = ua.NodeId.from_string("ns=2;i=3")

node.BrowseName = ua.QualifiedName.from_string("BaseInterface") `

I already found a workaround, but I dont think that this is the best way. node.BrowseName = ua.QualifiedName.from_string("2:BaseInterface")

If someone knows a better way to include the namespace to a node please let me know.

best regards

zerox1212 commented 6 years ago

Do you really need to work directly with the UA objects? Can you use the high level interface?

mar-ar commented 6 years ago

No but I thought its the best way to implement a lot of objects, variables and references, like it is used for the standard adressspace. How would you do this?

oroulet commented 6 years ago

What do you want to do? before using the low level api you need to understand the basic opcua concepts. Then you decide if you want to create your nodes using xml or low level api or whatever

mar-ar commented 6 years ago

I hope that I already have understood the basic opc ua concepts. I just want to implement my own addresspace with a set of objects, variables and references. And I just saw how it is made with the standard addresspace so I just wanted to make it the same way.

zerox1212 commented 6 years ago

How many objects do you have? It seems like a lot of work to build nodes with the low level API just to save some startup time.

If you really need to use the low level I can't help you. I haven't found a reason yet to use anything but the nice high level API or XML.

mar-ar commented 6 years ago

I have somthing around 100 objects.

What do you mean with the high level API? XML would be also possible for me.

zerox1212 commented 6 years ago

100 objects or 100 nodes? 100 nodes is nothing...

I mean use the high level API to create your UA nodes:

# get Objects node, this is where we should put our nodes
    objects = server.get_objects_node()

    # populating our address space
    myobj = objects.add_object(idx, "MyObject")

You can call add_object(idx, "name") 100 times and all your nodes will be created. You don't need to mess around with building all the low level UA objects.

Perhaps if you had to add 100,000 nodes on startup I would look for a way to optimize it, but in the end large address space is almost always best handled with an XML for organization reasons.

mar-ar commented 6 years ago

Okey thank you for your response.

I started with the high level API but I thought its faster to implement everything in the node class. But then I will propably change.

Thank you

zerox1212 commented 6 years ago

I prefer to use modeler to build an address space design in XML and just import it. For me it's the best organization because then the python code focuses on populating the nodes with data instead of address space design.

mar-ar commented 6 years ago

My problem thereby is that my addressspace changes while the runtime.

oroulet commented 6 years ago

I do not think address space is supposed to change at runtime. You have a design error and will get into trouble

mar-ar commented 6 years ago

I dont think so. I already saw a few examples where the address space changed while the runtime. Its an advantage of opc ua and the events therefor are defined like GeneralModelcChangeEvent.

oroulet commented 6 years ago

I am quite sure this is made for very low frequency changes. By the way the model change event is not implement but this should be easy to implement or send it manually

mar-ar commented 6 years ago

I think the use case that the information model changes while the runtime is very common. So there has to be a good way to implement this. And my solution until now was to do it like this.

oroulet commented 6 years ago

You can do whatever you want. Even implement an ua server in Photoshop, possible but quite broken by design

mar-ar commented 6 years ago

I havent found a better way to handle this. When I start the server I dont know all elements which I want to transfer. One exaple therefor is that I create an error object for each error which occures while the runtime. If more error occure more error objects are created.

oroulet commented 6 years ago

I do not know your project but you should consider custom events and/or custom structures.

mar-ar commented 6 years ago

Its to complex to explain briefly.

What do you mean with custom structures?

zerox1212 commented 6 years ago

If you don't mind, I'm interested in your use case. What kind of machine or OPC UA application would be changing it's address space on the fly?

The only thing I can think of would be an HMI development app built on top of OPC UA. I think atvise HMI might be built this way. http://www.atvise.com/en/

mar-ar commented 6 years ago

I am implementing an opc ua server for a machine which provides all necessary information about this machine. One exaple is like I already mention if the PLC of the machine gets an error I want to read this error (or more) via ua. An other example is that I provide information about each tool in this machine but the amout of tools changes during time. Or information about a specific workpiece and so on...

oroulet commented 6 years ago

I have seens two cases:

If you want to expose tools you have two obvious choices.

for error the normal solution is to use events. Send error events. People interested in history can read event history. And maybe update the machine state with current error if this is something important

mar-ar commented 6 years ago

Hmm thats a good idea. Thanks I have to think about that.

zerox1212 commented 6 years ago

Don't change the address space for errors by using nodes. Use events and alarms. That way you can enable historizing and clients can read event history. This library already supports basic value and event history.

mar-ar commented 6 years ago

Yeah sure thanks.

I dont know how to implement a list of objects with properties and components. I know how to realize a variable with an array. Can you explain it please.