Commit f17f79ee authored by maljac's avatar maljac Committed by ORD

[Server] Allow Methods to be imported via XML (#257)

* Allow the import of methods in xml imports

* Adds unittest for testing method importing
parent b9b1be18
...@@ -95,20 +95,7 @@ class XmlImporter(object): ...@@ -95,20 +95,7 @@ class XmlImporter(object):
attrs.DataType = self.to_nodeid(obj.datatype) attrs.DataType = self.to_nodeid(obj.datatype)
# if obj.value and len(obj.value) == 1: # if obj.value and len(obj.value) == 1:
if obj.value is not None: if obj.value is not None:
#TODO: If non variant based types grow move it to a seperate function attrs.Value = self._add_variable_value(obj, )
if obj.valuetype == 'ListOfLocalizedText':
attrs.Value = ua.Variant([ua.LocalizedText(txt) for txt in obj.value], None)
elif obj.valuetype == 'EnumValueType':
values = []
for ev in obj.value:
enum_value = ua.EnumValueType()
enum_value.DisplayName = ua.LocalizedText(ev['DisplayName'])
enum_value.Description = ua.LocalizedText(ev['Description'])
enum_value.Value = int(ev['Value'])
values.append(enum_value)
attrs.Value = values
else:
attrs.Value = ua.Variant(obj.value, getattr(ua.VariantType, obj.valuetype))
if obj.rank: if obj.rank:
attrs.ValueRank = obj.rank attrs.ValueRank = obj.rank
if obj.accesslevel: if obj.accesslevel:
...@@ -123,6 +110,36 @@ class XmlImporter(object): ...@@ -123,6 +110,36 @@ class XmlImporter(object):
self.server.add_nodes([node]) self.server.add_nodes([node])
self._add_refs(obj) self._add_refs(obj)
def _add_variable_value(self, obj):
"""
Returns the value for a Variable based on the objects valuetype.
"""
if obj.valuetype == 'ListOfLocalizedText':
return ua.Variant([ua.LocalizedText(txt) for txt in obj.value], None)
elif obj.valuetype == 'EnumValueType':
values = []
for ev in obj.value:
enum_value = ua.EnumValueType()
enum_value.DisplayName = ua.LocalizedText(ev['DisplayName'])
enum_value.Description = ua.LocalizedText(ev['Description'])
enum_value.Value = int(ev['Value'])
values.append(enum_value)
return values
elif obj.valuetype == 'Argument':
values = []
for arg in obj.value:
argument = ua.Argument()
argument.Name = arg['Name']
argument.Description = ua.LocalizedText(arg['Description'])
argument.DataType = self.to_nodeid(arg['DataType'])
argument.ValueRank = int(arg['ValueRank'])
argument.ArrayDimensions = arg['ArrayDimensions']
values.append(argument)
return values
return ua.Variant(obj.value, getattr(ua.VariantType, obj.valuetype))
def add_variable_type(self, obj): def add_variable_type(self, obj):
node = self._get_node(obj) node = self._get_node(obj)
attrs = ua.VariableTypeAttributes() attrs = ua.VariableTypeAttributes()
......
...@@ -957,6 +957,7 @@ class EnumValueType(FrozenClass): ...@@ -957,6 +957,7 @@ class EnumValueType(FrozenClass):
:ivar Description: :ivar Description:
:vartype Description: LocalizedText :vartype Description: LocalizedText
''' '''
def __init__(self, binary=None): def __init__(self, binary=None):
if binary is not None: if binary is not None:
self._binary_init(binary) self._binary_init(binary)
......
...@@ -175,6 +175,80 @@ ...@@ -175,6 +175,80 @@
</uax:ExtensionObject> </uax:ExtensionObject>
</uax:ListOfExtensionObject> </uax:ListOfExtensionObject>
</Value> </Value>
</UAVariable>
<!-- test data Object with Method and MethodArguments -->
<UAObjectType NodeId="ns=1;i=1050" BrowseName="1:MyObjectType">
<DisplayName>MyObjectType</DisplayName>
<References>
<Reference ReferenceType="HasComponent">ns=1;i=7050</Reference>
<Reference ReferenceType="HasSubtype" IsForward="false">i=58</Reference>
</References>
</UAObjectType>
<UAMethod ParentNodeId="ns=1;i=1050" NodeId="ns=1;i=7050" BrowseName="1:MyMethod">
<DisplayName>MyMethod</DisplayName>
<References>
<Reference ReferenceType="HasProperty">ns=1;i=6050</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=1050</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=6051</Reference>
</References>
</UAMethod>
<UAVariable DataType="Argument" ParentNodeId="ns=1;i=7050" ValueRank="1" NodeId="ns=1;i=6050" ArrayDimensions="1" BrowseName="InputArguments">
<DisplayName>InputArguments</DisplayName>
<References>
<Reference ReferenceType="HasProperty" IsForward="false">ns=1;i=7050</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
<Value>
<uax:ListOfExtensionObject>
<uax:ExtensionObject>
<uax:TypeId>
<uax:Identifier>i=297</uax:Identifier>
</uax:TypeId>
<uax:Body>
<uax:Argument>
<uax:Name>Context</uax:Name>
<uax:DataType>
<uax:Identifier>i=12</uax:Identifier>
</uax:DataType>
<uax:ValueRank>-1</uax:ValueRank>
<uax:ArrayDimensions/>
<uax:Description/>
</uax:Argument>
</uax:Body>
</uax:ExtensionObject>
</uax:ListOfExtensionObject>
</Value>
</UAVariable>
<UAVariable DataType="Argument" ParentNodeId="ns=1;i=7050" ValueRank="1" NodeId="ns=1;i=6051" ArrayDimensions="1" BrowseName="OutputArguments">
<DisplayName>OutputArguments</DisplayName>
<References>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
<Reference ReferenceType="HasProperty" IsForward="false">ns=1;i=7050</Reference>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
<Value>
<uax:ListOfExtensionObject>
<uax:ExtensionObject>
<uax:TypeId>
<uax:Identifier>i=297</uax:Identifier>
</uax:TypeId>
<uax:Body>
<uax:Argument>
<uax:Name>Status</uax:Name>
<uax:DataType>
<uax:Identifier>i=6</uax:Identifier>
</uax:DataType>
<uax:ValueRank>-1</uax:ValueRank>
<uax:ArrayDimensions/>
<uax:Description/>
</uax:Argument>
</uax:Body>
</uax:ExtensionObject>
</uax:ListOfExtensionObject>
</Value>
</UAVariable> </UAVariable>
</UANodeSet> </UANodeSet>
...@@ -143,9 +143,24 @@ class TestServer(unittest.TestCase, CommonTests, SubscriptionTests): ...@@ -143,9 +143,24 @@ class TestServer(unittest.TestCase, CommonTests, SubscriptionTests):
val = v.get_value() val = v.get_value()
self.assertEqual(val, "StringValue") self.assertEqual(val, "StringValue")
o = self.opc.get_root_node().get_child(["Types", "DataTypes", "BaseDataType", "Enumeration", "1:MyEnum", "0:EnumStrings"]) node_path = ["Types", "DataTypes", "BaseDataType", "Enumeration",
"1:MyEnum", "0:EnumStrings"]
o = self.opc.get_root_node().get_child(node_path)
self.assertEqual(len(o.get_value()), 3) self.assertEqual(len(o.get_value()), 3)
# Check if method is imported
node_path = ["Types", "ObjectTypes", "BaseObjectType",
"1:MyObjectType", "1:MyMethod"]
o = self.opc.get_root_node().get_child(node_path)
self.assertEqual(len(o.get_referenced_nodes()), 4)
# Check if InputArgs are imported and can be read
node_path = ["Types", "ObjectTypes", "BaseObjectType",
"1:MyObjectType", "1:MyMethod", "InputArguments"]
o = self.opc.get_root_node().get_child(node_path)
input_arg = o.get_data_value().Value.Value[0]
self.assertEqual(input_arg.Name, 'Context')
def test_historize_variable(self): def test_historize_variable(self):
o = self.opc.get_objects_node() o = self.opc.get_objects_node()
var = o.add_variable(3, "test_hist", 1.0) var = o.add_variable(3, "test_hist", 1.0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment