Open ruimmaraujo opened 4 years ago
def set_modelling_rule(self, mandatory):
"""
Add a modelling rule reference to Node.
When creating a new object type, its variable and child nodes will not
be instanciated if they do not have modelling rule
if mandatory is None, the modelling rule is removed
"""
# remove all existing modelling rule
rules = self.get_references(ua.ObjectIds.HasModellingRule)
self.server.delete_references(list(map(self._fill_delete_reference_item, rules)))
# add new modelling rule as requested
if mandatory is not None:
rule = ua.ObjectIds.ModellingRule_Mandatory if mandatory else ua.ObjectIds.ModellingRule_Optional
self.add_reference(rule, ua.ObjectIds.HasModellingRule, True, False)
can be: set_modelling_rule(None) set_modelling_rule(False) set_modelling_rule(True)
guess you need to "add_reference()" instead!
def add_reference(self, target, reftype, forward=True, bidirectional=True):
"""
Add reference to node
"""
aitem = ua.AddReferencesItem()
aitem.SourceNodeId = self.nodeid
aitem.TargetNodeId = _to_nodeid(target)
aitem.ReferenceTypeId = _to_nodeid(reftype)
aitem.IsForward = forward
params = [aitem]
if bidirectional:
aitem2 = ua.AddReferencesItem()
aitem2.SourceNodeId = aitem.TargetNodeId
aitem2.TargetNodeId = aitem.SourceNodeId
aitem2.ReferenceTypeId = aitem.ReferenceTypeId
aitem2.IsForward = not forward
params.append(aitem2)
results = self.server.add_references(params)
for r in results:
r.check()
maybe:
dev.add_reference(ua.ObjectIds.ModellingRule_ExposesItsArray, ua.ObjectIds.HasModellingRule, True, False)
thank you @AndreasHeine for the feedback. I haven't considered the add reference. I gave it a try but seems without success
In the image below the sensor values of the array are include in the sensor1 variable but as expected as individual nodes :S
https://reference.opcfoundation.org/v104/Core/docs/Part3/6.4.4/#6.4.4.5#6.4.4.5.4
6.4.4.5.4 ExposesItsArray ToC
The ExposesItsArray ModellingRule exposes a special semantic on VariableTypes having a single- or multidimensional array as the data type. It indicates that each value of the array will also be exposed as a Variable in the AddressSpace.
The ExposesItsArray ModellingRule can only be applied on InstanceDeclarations of NodeClass Variable that are part of a VariableType having a single- or multidimensional array as its data type.
The Variable A having this ModellingRule shall be referenced by a forward hierarchical Reference from a VariableType B. B shall have a ValueRank value that is equal to or larger than zero. A should have a data type that reflects at least parts of the data that is managed in the array of B. Each instance of B shall reference one instance of A for each of its array elements. The used Reference shall be of the same type as the hierarchical Reference that connects B with A or a subtype of it. If there are more than one forward hierarchical References between A and B, then all instances based on B shall be referenced with all those References.
Figure 21 gives an example. A is an instance of Type_A having two entries in its value array. Therefore it references two instances of the same type as the InstanceDeclaration ArrayExpose. The BrowseNames of those instances are not defined by the ModellingRule. In general, it is not possible to get a Variable representing a specific entry in the array (e.g. the second). Clients will typically either get the array or access the Variables directly, so there is no need to provide that information.
@AndreasHeine thank you once again for the feedback. I actually had a look at that document.
and even this one https://readthedocs.org/projects/python-opcua/downloads/pdf/stable/ but it is not very clear how it is implemented :/
I initially thought by set a modelling rule 83 as an argument it would expose the array.. .but no clue how to activate this...
This is for sure not implement. I am also not sure we should implement that kind of strange things. The protocol and code is complicated enough with the features that make sense
Hi @oroulet thank for clearfying. It is actually useful for the client to read as a node in a position of the array e.g. sensor1[0] ,sensor [1] ... instead all packed in one variable. I will see how this could be implemented ... again thank you for feedback 👍
There is nothing bad or difficult in making every sensor available individually. Then also as an array. It does not need to be part of protocol
But contributions are welcome anyway
it's one of those convenience functions ;)
do you know a stack which has implemented this functionality just to test what happens if we add the reference in our server variable?
Unified Automation has implemented this in their stack. In the image bekow is an example of how it woukd be done. All variables of the array has its own node.
I don't understand this feature. What is the problem with just getting the entire array and dealing with the sensor you want? Are you trying to reduce communication overhead or something? Or is it just for convenience that you don't want to deal with entire array (in which case why did they design it as an array in the first place?)
Seems like this just programmers solving a problem that doesn't exist lol.
@zerox1212 some parts of spec. make sense if you have a companion spec. in mind (especialy modeling rules and naming rules) so you could auto generate a number of variables with just a modelimg rule reference!
device internaly its an array for some reason so you simply write it in once but as a interface it is in some cases better to seperate them to maybe read only a few of them
edit: its not one of the features most devs need, thats for sure 😜
@oroulet maybe we can implement a method in node.py similar to "set_modelling_rule" for "expose its array" which simply add_variables for each array-element
edit: updating them if the parent got written would be something for @JoeyFaulkner callback topic 😉
@AndreasHeine thanks for the feedback. I would be glad to contribute to this. in the automation world it is quite used the ExposesItsArray
I did some experiments to see how it would be possible something like can work. In no shape or form I am saying we should :)
"for i in testarray:" would be faster and more pythonic, range method generates a list but you already have one 😉
edit: in python there is only the for each like loop
My issue is that if we do it inside opcua we need to register somewhere that these are the same values and that updating one exposed node must also update that value inside array... This is some code that make things more complicated and slower
updating one exposed node must also update that value inside array...
i try a quick prove of concept with an serverside subscription!
edit: just like a optional utility not a core feature!
read or write only works but not together... without callbacks not realy practical to be honest -_-°
I am trying to deploy the modeling rule ExposesItsArray but it seems it is not working by exposing the variable of the array are exposed as a individual Variable in the AddressSpace
By checking the document https://readthedocs.org/projects/python-opcua/downloads/pdf/stable/ it seems that ModellingRule_ExposesItsArray is 83 and I have tried the following line but seems it is not working: dev.add_variable(idx, "sensor1", [6.7, 7.9]).set_modelling_rule(83)
How can enable this rule?