Commit 7b2b130f authored by Christoph Ziebuhr's avatar Christoph Ziebuhr Committed by oroulet

Fix interpretation of IncludeSubtypes

parent 2be7ce80
......@@ -219,7 +219,7 @@ async def select_event_attributes_from_type_node(node: "Node", attributeSelector
if curr_node.nodeid.Identifier == ua.ObjectIds.BaseEventType:
break
parents = await curr_node.get_referenced_nodes(
refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse, includesubtypes=True
refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse
)
if len(parents) != 1: # Something went wrong
return None
......@@ -278,9 +278,7 @@ async def get_event_obj_from_type_node(node):
# Add the sub-properties of the VariableType
for prop in await var.get_properties():
await self._add_new_property(prop, var)
parents = await curr_node.get_referenced_nodes(refs=ua.ObjectIds.HasSubtype,
direction=ua.BrowseDirection.Inverse,
includesubtypes=True)
parents = await curr_node.get_referenced_nodes(refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse)
if len(parents) != 1: # Something went wrong
raise UaError("Parent of event type could not be found")
curr_node = parents[0]
......@@ -295,9 +293,7 @@ async def get_event_obj_from_type_node(node):
async def _find_parent_eventtype(node):
"""
"""
parents = await node.get_referenced_nodes(refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse,
includesubtypes=True)
parents = await node.get_referenced_nodes(refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse)
if len(parents) != 1: # Something went wrong
raise UaError("Parent of event type could not be found")
if parents[0].nodeid.NamespaceIndex == 0:
......
......@@ -97,7 +97,7 @@ async def _instantiate_node(server,
parents = await get_node_supertypes(node_type, includeitself=True)
node = make_node(server, res.AddedNodeId)
for parent in parents:
descs = await parent.get_children_descriptions(includesubtypes=False)
descs = await parent.get_children_descriptions()
for c_rdesc in descs:
# skip items that already exists, prefer the 'lowest' one in object hierarchy
if not await is_child_present(node, c_rdesc.BrowseName):
......
......@@ -204,7 +204,7 @@ async def get_node_supertype(node):
return node supertype or None
"""
supertypes = await node.get_referenced_nodes(
refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse, includesubtypes=True
refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse
)
if supertypes:
return supertypes[0]
......
......@@ -12,7 +12,7 @@ from functools import partial
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Callable, Dict, List, Union, Tuple
from typing import Callable, Dict, List, Union, Tuple, Generator
from asyncua.ua.uaprotocol_auto import (
ObjectAttributes, DataTypeAttributes, ReferenceTypeAttributes,
VariableTypeAttributes, VariableAttributes, ObjectTypeAttributes
......@@ -152,24 +152,19 @@ class ViewService(object):
# If ReferenceTypeId is not specified in the BrowseDescription,
# all References are returned and includeSubtypes is ignored.
return True
if not subtypes and ref2.Identifier == ua.ObjectIds.HasSubtype:
return False
if ref1.Identifier == ref2.Identifier:
if ref1 == ref2:
return True
if subtypes and ref2 in self._get_sub_ref(ref1):
return True
oktypes = self._get_sub_ref(ref1)
if not subtypes and ua.NodeId(ua.ObjectIds.HasSubtype) in oktypes:
oktypes.remove(ua.NodeId(ua.ObjectIds.HasSubtype))
return ref2 in oktypes
def _get_sub_ref(self, ref: ua.NodeId) -> List[ua.NodeId]:
res: List[ua.NodeId] = []
nodedata = self._aspace[ref]
return False
def _get_sub_ref(self, ref: ua.NodeId) -> Generator[ua.NodeId, None, None]:
nodedata = self._aspace.get(ref)
if nodedata is not None:
for ref_desc in nodedata.references:
if ref_desc.ReferenceTypeId.Identifier == ua.ObjectIds.HasSubtype and ref_desc.IsForward:
res.append(ref_desc.NodeId)
res += self._get_sub_ref(ref_desc.NodeId)
return res
if ref_desc.ReferenceTypeId == ua.NodeId(ua.ObjectIds.HasSubtype) and ref_desc.IsForward:
yield ref_desc.NodeId
yield from self._get_sub_ref(ref_desc.NodeId)
def _suitable_direction(self, direction: ua.BrowseDirection, isforward: bool) -> bool:
if direction == ua.BrowseDirection.Both:
......@@ -231,11 +226,8 @@ class ViewService(object):
continue
if ref.IsForward == el.IsInverse:
continue
if not el.IncludeSubtypes and ref.ReferenceTypeId != el.ReferenceTypeId:
if not self._suitable_reftype(el.ReferenceTypeId, ref.ReferenceTypeId, el.IncludeSubtypes):
continue
elif el.IncludeSubtypes and ref.ReferenceTypeId != el.ReferenceTypeId:
if ref.ReferenceTypeId not in self._get_sub_ref(el.ReferenceTypeId):
continue
nodeids.append(ref.NodeId)
return nodeids
......
......@@ -357,9 +357,15 @@ async def test_browse_references(opc):
assert objects in parents
parents = await folder.get_referenced_nodes(
refs=ua.ObjectIds.HierarchicalReferences, direction=ua.BrowseDirection.Inverse, includesubtypes=False
refs=ua.ObjectIds.HierarchicalReferences, direction=ua.BrowseDirection.Inverse, includesubtypes=True
)
assert objects in parents
parents = await folder.get_referenced_nodes(
refs=ua.ObjectIds.HierarchicalReferences, direction=ua.BrowseDirection.Inverse, includesubtypes=False
)
assert objects not in parents
assert await folder.get_parent() == objects
......@@ -928,7 +934,7 @@ async def test_copy_node(opc):
ctrl_t = await dev_t.add_object(0, "controller")
prop_t = await ctrl_t.add_property(0, "state", "Running")
# Create device sutype
devd_t = await dev_t.add_object_type(0, "MyDeviceDervived")
devd_t = await dev_t.add_object_type(0, "MyDeviceDerived")
_ = await devd_t.add_variable(0, "childparam", 1.0)
_ = await devd_t.add_property(0, "sensorx_id", "0340")
nodes = await copy_node(opc.opc.nodes.objects, dev_t)
......@@ -959,7 +965,7 @@ async def test_instantiate_1(opc):
await prop_t.set_modelling_rule(True)
# Create device sutype
devd_t = await dev_t.add_object_type(0, "MyDeviceDervived")
devd_t = await dev_t.add_object_type(0, "MyDeviceDerived")
v_t = await devd_t.add_variable(0, "childparam", 1.0)
await v_t.set_modelling_rule(True)
p_t = await devd_t.add_property(0, "sensorx_id", "0340")
......@@ -973,10 +979,11 @@ async def test_instantiate_1(opc):
assert dev_t.nodeid == await mydevice.read_type_definition()
_ = await mydevice.get_child(["0:controller"])
prop = await mydevice.get_child(["0:controller", "0:state"])
with pytest.raises(ua.UaError):
await mydevice.get_child(["0:controller", "0:vendor"])
with pytest.raises(ua.UaError):
await mydevice.get_child(["0:controller", "0:model"])
_ = await mydevice.get_child(["0:vendor"])
with pytest.raises(ua.uaerrors.BadNoMatch):
await mydevice.get_child(["0:model"])
with pytest.raises(ua.uaerrors.BadNoMatch):
await mydevice.get_child(["0:MyDeviceDerived"])
assert ua.ObjectIds.PropertyType == (await prop.read_type_definition()).Identifier
assert "Running" == await prop.read_value()
......
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