Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
opcua-asyncio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nikola Balog
opcua-asyncio
Commits
441f33e2
Commit
441f33e2
authored
Jan 06, 2021
by
oroulet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bugfix xml 2
parent
ab146464
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
70 additions
and
28 deletions
+70
-28
asyncua/common/manage_nodes.py
asyncua/common/manage_nodes.py
+1
-0
asyncua/common/structures104.py
asyncua/common/structures104.py
+3
-4
asyncua/common/xmlexporter.py
asyncua/common/xmlexporter.py
+9
-11
asyncua/common/xmlimporter.py
asyncua/common/xmlimporter.py
+0
-3
asyncua/common/xmlparser.py
asyncua/common/xmlparser.py
+1
-1
asyncua/server/server.py
asyncua/server/server.py
+1
-8
asyncua/sync.py
asyncua/sync.py
+4
-0
tests/custom_enum.xml
tests/custom_enum.xml
+21
-0
tests/custom_struct.xml
tests/custom_struct.xml
+29
-0
tests/test_sync.py
tests/test_sync.py
+1
-1
No files found.
asyncua/common/manage_nodes.py
View file @
441f33e2
...
...
@@ -352,6 +352,7 @@ async def create_encoding(parent, nodeid, bname):
or namespace index, name
"""
nodeid
,
qname
=
_parse_nodeid_qname
(
nodeid
,
bname
)
qname
.
NamespaceIndex
=
0
# encoding bname idx must be 0
return
make_node
(
parent
.
server
,
await
_create_encoding
(
parent
.
server
,
parent
.
nodeid
,
nodeid
,
qname
))
...
...
asyncua/common/structures104.py
View file @
441f33e2
...
...
@@ -30,7 +30,7 @@ def new_struct_field(name, dtype, array=False, optional=False, description=""):
elif
isinstance
(
dtype
,
Node
):
field
.
DataType
=
dtype
.
nodeid
else
:
raise
ValueError
(
f"Data
t
ype of a field must be a NodeId, not
{
dtype
}
of type
{
type
(
dtype
)
}
"
)
raise
ValueError
(
f"Data
T
ype of a field must be a NodeId, not
{
dtype
}
of type
{
type
(
dtype
)
}
"
)
if
array
:
field
.
ValueRank
=
ua
.
ValueRank
.
OneOrMoreDimensions
field
.
ArrayDimensions
=
[
1
]
...
...
@@ -56,7 +56,7 @@ async def new_struct(server, idx, name, fields):
sdef
.
StructureType
=
ua
.
StructureType
.
StructureWithOptionalFields
break
sdef
.
Fields
=
fields
sdef
.
BaseData
t
ype
=
server
.
nodes
.
base_data_type
.
nodeid
sdef
.
BaseData
T
ype
=
server
.
nodes
.
base_data_type
.
nodeid
sdef
.
DefaultEncodingId
=
enc
.
nodeid
await
dtype
.
write_data_type_definition
(
sdef
)
...
...
@@ -65,7 +65,6 @@ async def new_struct(server, idx, name, fields):
async
def
new_enum
(
server
,
idx
,
name
,
values
):
edef
=
ua
.
EnumDefinition
()
edef
.
Name
=
name
counter
=
0
for
val_name
in
values
:
field
=
ua
.
EnumField
()
...
...
@@ -272,7 +271,7 @@ async def load_data_type_definitions(server, base_node=None):
async def _read_data_type_definition(server, desc):
if desc.BrowseName.Name == "FilterOperand":
#FIXME: find out why that one is not in ua namespace...
#
FIXME: find out why that one is not in ua namespace...
return None
# FIXME: this is fishy, we may have same name in different Namespaces
if hasattr(ua, desc.BrowseName.Name):
...
...
asyncua/common/xmlexporter.py
View file @
441f33e2
...
...
@@ -44,30 +44,28 @@ class XmlExporter:
self
.
etree
=
Et
.
ElementTree
(
Et
.
Element
(
'UANodeSet'
,
node_write_attributes
))
async
def
build_etree
(
self
,
node_list
,
uris
=
None
):
async
def
build_etree
(
self
,
node_list
):
"""
Create an XML etree object from a list of nodes;
custom namespace uris are optional
Create an XML etree object from a list of nodes;
Namespaces used by nodes are always exported for consistency.
Args:
node_list: list of Node objects for export
uris: list of namespace uri strings
Returns:
"""
self
.
logger
.
info
(
'Building XML etree'
)
await
self
.
_add_namespaces
(
node_list
,
uris
)
await
self
.
_add_namespaces
(
node_list
)
# add all nodes in the list to the XML etree
for
node
in
node_list
:
await
self
.
node_to_etree
(
node
)
# add aliases to the XML etree
self
.
_add_alias_els
()
async
def
_add_namespaces
(
self
,
nodes
,
uris
):
idxs
=
await
self
.
_get_ns_idxs_of_nodes
(
nodes
)
async
def
_add_namespaces
(
self
,
nodes
):
ns_array
=
await
self
.
server
.
get_namespace_array
()
# now add index of provided uris if necessary
if
uris
:
self
.
_add_idxs_from_uris
(
idxs
,
uris
,
ns_array
)
idxs
=
await
self
.
_get_ns_idxs_of_nodes
(
nodes
)
# now create a dict of idx_in_address_space to idx_in_exported_file
self
.
_addr_idx_to_xml_idx
=
self
.
_make_idx_dict
(
idxs
,
ns_array
)
ns_to_export
=
[
ns_array
[
i
]
for
i
in
sorted
(
list
(
self
.
_addr_idx_to_xml_idx
.
keys
()))
if
i
!=
0
]
...
...
@@ -308,14 +306,14 @@ class XmlExporter:
elif
isinstance
(
sdef
,
ua
.
EnumDefinition
):
self
.
_enum_fields_to_etree
(
bname
,
sdef_el
,
sdef
)
else
:
self
.
logger
.
warning
(
"Unknown Data
t
ypeSpecification elemnt: %s"
,
sdef
)
self
.
logger
.
warning
(
"Unknown Data
T
ypeSpecification elemnt: %s"
,
sdef
)
await
self
.
_add_ref_els
(
obj_el
,
obj
)
def
_structure_fields_to_etree
(
self
,
bname
,
sdef_el
,
sdef
):
for
field
in
sdef
.
Fields
:
field_el
=
Et
.
SubElement
(
sdef_el
,
'Field'
)
field_el
.
attrib
[
'Name'
]
=
field
.
Name
field_el
.
attrib
[
'Data
t
ype'
]
=
field
.
DataType
.
to_string
()
field_el
.
attrib
[
'Data
T
ype'
]
=
field
.
DataType
.
to_string
()
if
field
.
ValueRank
!=
-
1
:
field_el
.
attrib
[
'ValueRank'
]
=
str
(
int
(
field
.
ValueRank
))
if
field
.
ArrayDimensions
:
...
...
asyncua/common/xmlimporter.py
View file @
441f33e2
...
...
@@ -494,8 +494,6 @@ class XmlImporter:
if
not
obj
.
definitions
:
return
None
edef
=
ua
.
EnumDefinition
()
if
obj
.
parent
:
edef
.
BaseDataType
=
obj
.
parent
for
field
in
obj
.
definitions
:
f
=
ua
.
EnumField
()
f
.
Name
=
field
.
name
...
...
@@ -521,7 +519,6 @@ class XmlImporter:
break
optional
=
False
for
field
in
obj
.
definitions
:
print
(
"IMPORT FIEL"
,
field
.
name
,
field
.
datatype
)
f
=
ua
.
StructureField
()
f
.
Name
=
field
.
name
f
.
DataType
=
field
.
datatype
...
...
asyncua/common/xmlparser.py
View file @
441f33e2
...
...
@@ -69,7 +69,7 @@ class NodeData:
class
Field
:
def
__init__
(
self
,
data
):
self
.
datatype
=
data
.
get
(
"Data
t
ype"
,
""
)
self
.
datatype
=
data
.
get
(
"Data
T
ype"
,
""
)
self
.
name
=
data
.
get
(
"Name"
)
self
.
dname
=
data
.
get
(
"DisplayName"
,
""
)
self
.
optional
=
bool
(
data
.
get
(
"IsOptional"
,
False
))
...
...
asyncua/server/server.py
View file @
441f33e2
...
...
@@ -546,15 +546,8 @@ class Server:
"""
Export defined nodes to xml
"""
uris
=
await
self
.
get_namespace_array
()
uris_to_export
=
{}
for
node
in
nodes
:
idx
=
node
.
nodeid
.
NamespaceIndex
if
idx
not
in
uris_to_export
and
idx
<
len
(
uris
):
uris_to_export
[
idx
]
=
uris
[
idx
]
exp
=
XmlExporter
(
self
)
await
exp
.
build_etree
(
nodes
,
uris_to_export
)
await
exp
.
build_etree
(
nodes
)
await
exp
.
write_xml
(
path
)
async
def
export_xml_by_ns
(
self
,
path
:
str
,
namespaces
:
list
=
None
):
...
...
asyncua/sync.py
View file @
441f33e2
...
...
@@ -374,6 +374,10 @@ class SyncNode:
def
read_attribute
(
self
,
attr
):
pass
@
syncmethod
def
write_attribute
(
self
,
attributeid
,
datavalue
,
indexrange
=
None
):
pass
@
syncmethod
def
read_browse_name
(
self
):
pass
...
...
tests/custom_enum.xml
0 → 100644
View file @
441f33e2
<?xml version='1.0' encoding='utf-8'?>
<UANodeSet
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:uax=
"http://opcfoundation.org/UA/2008/02/Types.xsd"
xmlns:xsd=
"http://www.w3.org/2001/XMLSchema"
xmlns=
"http://opcfoundation.org/UA/2011/03/UANodeSet.xsd"
>
<NamespaceUris>
<Uri>
http://toto.freeopcua.github.io/
</Uri>
</NamespaceUris>
<Aliases>
<Alias
Alias=
"HasSubtype"
>
i=45
</Alias>
</Aliases>
<UADataType
NodeId=
"ns=1;i=5101"
BrowseName=
"4:MyCrazyEnum"
>
<DisplayName>
MyCrazyEnum
</DisplayName>
<Description>
MyCrazyEnum
</Description>
<Definition
Name=
"MyCrazyEnum"
>
<Field
Name=
"titi"
Value=
"0"
/>
<Field
Name=
"toto"
Value=
"1"
/>
<Field
Name=
"tutu"
Value=
"2"
/>
</Definition>
<References>
<Reference
ReferenceType=
"HasSubtype"
IsForward=
"false"
>
i=29
</Reference>
</References>
</UADataType>
</UANodeSet>
tests/custom_struct.xml
0 → 100644
View file @
441f33e2
<?xml version='1.0' encoding='utf-8'?>
<UANodeSet
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:uax=
"http://opcfoundation.org/UA/2008/02/Types.xsd"
xmlns:xsd=
"http://www.w3.org/2001/XMLSchema"
xmlns=
"http://opcfoundation.org/UA/2011/03/UANodeSet.xsd"
>
<NamespaceUris>
<Uri>
http://toto.freeopcua.github.io/
</Uri>
</NamespaceUris>
<Aliases>
<Alias
Alias=
"HasEncoding"
>
i=38
</Alias>
<Alias
Alias=
"HasSubtype"
>
i=45
</Alias>
</Aliases>
<UADataType
NodeId=
"ns=1;i=6101"
BrowseName=
"4:MyCrazyStruct"
>
<DisplayName>
MyCrazyStruct
</DisplayName>
<Description>
My Description
</Description>
<Definition
Name=
"MyCrazyStruct"
>
<Field
Name=
"MyBool"
DataType=
"i=1"
/>
<Field
Name=
"MyUInt32"
DataType=
"i=7"
ValueRank=
"0"
ArrayDimensions=
"1"
/>
</Definition>
<References>
<Reference
ReferenceType=
"HasSubtype"
IsForward=
"false"
>
i=22
</Reference>
<Reference
ReferenceType=
"HasEncoding"
>
ns=1;i=6102
</Reference>
</References>
</UADataType>
<UAObjectType
NodeId=
"ns=1;i=6102"
BrowseName=
"0:Default Binary"
>
<DisplayName>
Default Binary
</DisplayName>
<Description>
Default Binary
</Description>
<References>
<Reference
ReferenceType=
"HasEncoding"
IsForward=
"false"
>
ns=1;i=6101
</Reference>
</References>
</UAObjectType>
</UANodeSet>
tests/test_sync.py
View file @
441f33e2
...
...
@@ -130,5 +130,5 @@ def test_sync_call_meth(client, idx):
def
test_sync_xml_export
(
server
):
exp
=
XmlExporter
(
server
)
exp
.
build_etree
([
server
.
nodes
.
objects
]
,
uris
=
[]
)
exp
.
build_etree
([
server
.
nodes
.
objects
])
exp
.
write_xml
(
"toto_test_export.xml"
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment