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
f08c39b8
Commit
f08c39b8
authored
Jul 27, 2020
by
oroulet
Committed by
oroulet
Jul 30, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
import substructures from xml
parent
736373dc
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
53 additions
and
33 deletions
+53
-33
asyncua/common/structures104.py
asyncua/common/structures104.py
+4
-1
asyncua/common/xmlimporter.py
asyncua/common/xmlimporter.py
+49
-32
No files found.
asyncua/common/structures104.py
View file @
f08c39b8
...
...
@@ -86,7 +86,9 @@ class {name}:
elif field.DataType in ua.enums_by_datatype:
uatype = ua.enums_by_datatype[field.DataType].__name__
else:
raise RuntimeError(f"Unknown datatype for field: {field} in structure:{name}")
#FIXME: we are probably missing many custom tyes here based on builtin types
#maybe we can use ua_utils.get_base_data_type()
raise RuntimeError(f"Unknown datatype for field: {field} in structure:{name}, please report")
if field.ValueRank >= 1 and uatype == '
Char
':
uatype = '
String
'
uatypes.append((field, uatype))
...
...
@@ -177,6 +179,7 @@ async def load_data_type_definitions(server, base_node=None):
base_node = server.nodes.base_structure_type
dtypes = []
await _recursive_parse(server, base_node, dtypes)
dtypes.sort()
for dts in dtypes:
try:
env = await _generate_object(dts.name, dts.sdef)
...
...
asyncua/common/xmlimporter.py
View file @
f08c39b8
...
...
@@ -12,13 +12,15 @@ from .xmlparser import XMLParser, ua_type_to_python
from
..ua.uaerrors
import
UaError
_logger
=
logging
.
getLogger
(
__name__
)
class
XmlImporter
:
def
__init__
(
self
,
server
):
self
.
logger
=
logging
.
getLogger
(
__name__
)
self
.
parser
=
None
self
.
server
=
server
self
.
namespaces
:
Dict
[
int
,
int
]
=
{}
self
.
namespaces
:
Dict
[
int
,
int
]
=
{}
#Dict[IndexInXml, IndexInServer]
self
.
aliases
:
Dict
[
str
,
ua
.
NodeId
]
=
{}
self
.
refs
=
None
...
...
@@ -39,14 +41,14 @@ class XmlImporter:
"""
aliases_mapped
=
{}
for
alias
,
node_id
in
aliases
.
items
():
aliases_mapped
[
alias
]
=
self
.
to
_nodeid
(
node_id
)
aliases_mapped
[
alias
]
=
self
.
_to_migrated
_nodeid
(
node_id
)
return
aliases_mapped
async
def
import_xml
(
self
,
xmlpath
=
None
,
xmlstring
=
None
):
"""
import xml and return added nodes
"""
self
.
logger
.
info
(
"Importing XML file %s"
,
xmlpath
)
_
logger
.
info
(
"Importing XML file %s"
,
xmlpath
)
self
.
parser
=
XMLParser
()
await
self
.
parser
.
parse
(
xmlpath
,
xmlstring
)
self
.
namespaces
=
await
self
.
_map_namespaces
(
self
.
parser
.
get_used_namespaces
())
...
...
@@ -60,13 +62,13 @@ class XmlImporter:
try
:
node
=
await
self
.
_add_node_data
(
nodedata
)
except
Exception
:
self
.
logger
.
warning
(
"failure adding node %s"
,
nodedata
)
_
logger
.
warning
(
"failure adding node %s"
,
nodedata
)
raise
nodes
.
append
(
node
)
self
.
refs
,
remaining_refs
=
[],
self
.
refs
await
self
.
_add_references
(
remaining_refs
)
if
len
(
self
.
refs
):
self
.
logger
.
warning
(
"The following references could not be imported and are probably broken: %s"
,
self
.
refs
)
_
logger
.
warning
(
"The following references could not be imported and are probably broken: %s"
,
self
.
refs
)
return
nodes
async
def
_add_node_data
(
self
,
nodedata
)
->
"Node"
:
...
...
@@ -104,15 +106,23 @@ class XmlImporter:
def
make_objects
(
self
,
node_data
):
new_nodes
=
[]
for
node_datum
in
node_data
:
node_datum
.
nodeid
=
ua
.
NodeId
.
from_string
(
node_datum
.
nodeid
)
node_datum
.
nodeid
=
self
.
_to_migrated_nodeid
(
node_datum
.
nodeid
)
node_datum
.
browsename
=
ua
.
QualifiedName
.
from_string
(
node_datum
.
browsename
)
if
node_datum
.
parent
:
node_datum
.
parent
=
ua
.
NodeId
.
from_string
(
node_datum
.
parent
)
node_datum
.
parent
=
self
.
_to_migrated_nodeid
(
node_datum
.
parent
)
if
node_datum
.
parentlink
:
node_datum
.
parentlink
=
self
.
_to_nodeid
(
node_datum
.
parentlink
)
node_datum
.
parentlink
=
self
.
_to_
migrated_
nodeid
(
node_datum
.
parentlink
)
if
node_datum
.
typedef
:
node_datum
.
typedef
=
self
.
_to_nodeid
(
node_datum
.
typedef
)
node_datum
.
typedef
=
self
.
_to_migrated_nodeid
(
node_datum
.
typedef
)
if
node_datum
.
datatype
:
node_datum
.
datatype
=
self
.
_to_migrated_nodeid
(
node_datum
.
datatype
)
new_nodes
.
append
(
node_datum
)
for
ref
in
node_datum
.
refs
:
ref
.
reftype
=
self
.
_to_migrated_nodeid
(
ref
.
reftype
)
ref
.
target
=
self
.
_to_migrated_nodeid
(
ref
.
target
)
for
field
in
node_datum
.
definitions
:
if
field
.
datatype
:
field
.
datatype
=
self
.
_to_migrated_nodeid
(
field
.
datatype
)
return
new_nodes
def
_migrate_ns
(
self
,
nodeid
:
ua
.
NodeId
)
->
ua
.
NodeId
:
...
...
@@ -132,7 +142,7 @@ class XmlImporter:
node
=
ua
.
AddNodesItem
()
node
.
RequestedNewNodeId
=
self
.
_migrate_ns
(
obj
.
nodeid
)
node
.
BrowseName
=
self
.
_migrate_ns
(
obj
.
browsename
)
self
.
logger
.
info
(
"Importing xml node (%s, %s) as (%s %s)"
,
obj
.
browsename
,
_
logger
.
info
(
"Importing xml node (%s, %s) as (%s %s)"
,
obj
.
browsename
,
obj
.
nodeid
,
node
.
BrowseName
,
node
.
RequestedNewNodeId
)
node
.
NodeClass
=
getattr
(
ua
.
NodeClass
,
obj
.
nodetype
[
2
:])
if
obj
.
parent
and
obj
.
parentlink
:
...
...
@@ -142,6 +152,10 @@ class XmlImporter:
node
.
TypeDefinition
=
self
.
_migrate_ns
(
obj
.
typedef
)
return
node
def
_to_migrated_nodeid
(
self
,
nodeid
:
Union
[
ua
.
NodeId
,
None
,
str
])
->
ua
.
NodeId
:
nodeid
=
self
.
_to_nodeid
(
nodeid
)
return
self
.
_migrate_ns
(
nodeid
)
def
_to_nodeid
(
self
,
nodeid
:
Union
[
ua
.
NodeId
,
None
,
str
])
->
ua
.
NodeId
:
if
isinstance
(
nodeid
,
ua
.
NodeId
):
return
nodeid
...
...
@@ -157,9 +171,6 @@ class XmlImporter:
else
:
return
ua
.
NodeId
(
getattr
(
ua
.
ObjectIds
,
nodeid
))
def
to_nodeid
(
self
,
nodeid
:
Union
[
ua
.
NodeId
,
None
,
str
])
->
ua
.
NodeId
:
return
self
.
_migrate_ns
(
self
.
_to_nodeid
(
nodeid
))
async
def
add_object
(
self
,
obj
):
node
=
self
.
_get_node
(
obj
)
attrs
=
ua
.
ObjectAttributes
()
...
...
@@ -192,7 +203,7 @@ class XmlImporter:
if
obj
.
desc
:
attrs
.
Description
=
ua
.
LocalizedText
(
obj
.
desc
)
attrs
.
DisplayName
=
ua
.
LocalizedText
(
obj
.
displayname
)
attrs
.
DataType
=
self
.
to_nodeid
(
obj
.
datatype
)
attrs
.
DataType
=
obj
.
datatype
if
obj
.
value
is
not
None
:
attrs
.
Value
=
self
.
_add_variable_value
(
obj
,)
if
obj
.
rank
:
...
...
@@ -274,7 +285,7 @@ class XmlImporter:
"""
Returns the value for a Variable based on the objects value type.
"""
self
.
logger
.
debug
(
"Setting value with type %s and value %s"
,
obj
.
valuetype
,
obj
.
value
)
_
logger
.
debug
(
"Setting value with type %s and value %s"
,
obj
.
valuetype
,
obj
.
value
)
if
obj
.
valuetype
==
'ListOfExtensionObject'
:
values
=
[]
for
ext
in
obj
.
value
:
...
...
@@ -306,7 +317,7 @@ class XmlImporter:
elif
name
==
"Locale"
:
ltext
.
Locale
=
val
else
:
self
.
logger
.
warning
(
"While parsing localizedText value, unkown element: %s with val: %s"
,
name
,
val
)
_
logger
.
warning
(
"While parsing localizedText value, unkown element: %s with val: %s"
,
name
,
val
)
return
ua
.
Variant
(
ltext
,
ua
.
VariantType
.
LocalizedText
)
elif
obj
.
valuetype
==
'NodeId'
:
return
ua
.
Variant
(
ua
.
NodeId
.
from_string
(
obj
.
value
))
...
...
@@ -319,7 +330,7 @@ class XmlImporter:
if
obj
.
desc
:
attrs
.
Description
=
ua
.
LocalizedText
(
obj
.
desc
)
attrs
.
DisplayName
=
ua
.
LocalizedText
(
obj
.
displayname
)
attrs
.
DataType
=
self
.
to_nodeid
(
obj
.
datatype
)
attrs
.
DataType
=
obj
.
datatype
if
obj
.
value
and
len
(
obj
.
value
)
==
1
:
attrs
.
Value
=
obj
.
value
[
0
]
if
obj
.
rank
:
...
...
@@ -380,14 +391,20 @@ class XmlImporter:
attrs
.
DisplayName
=
ua
.
LocalizedText
(
obj
.
displayname
)
if
obj
.
abstract
:
attrs
.
IsAbstract
=
obj
.
abstract
if
obj
.
definitions
and
obj
.
parent
==
ua
.
NodeId
(
29
):
attrs
.
DataTypeDefinition
=
self
.
_get_edef
(
node
,
obj
)
pass
elif
obj
.
definitions
and
obj
.
parent
==
ua
.
NodeId
(
22
):
#FIXME need better check for subclasses!!
attrs
.
DataTypeDefinition
=
self
.
_get_sdef
(
node
,
obj
)
else
:
if
not
obj
.
definitions
:
print
(
"NOT DEFINITON"
,
obj
.
parent
,
obj
)
else
:
if
obj
.
parent
==
self
.
server
.
nodes
.
enum_data_type
:
attrs
.
DataTypeDefinition
=
self
.
_get_edef
(
node
,
obj
)
elif
obj
.
parent
==
self
.
server
.
nodes
.
base_structure_type
:
attrs
.
DataTypeDefinition
=
self
.
_get_sdef
(
node
,
obj
)
else
:
parent_node
=
self
.
server
.
get_node
(
obj
.
parent
)
path
=
await
parent_node
.
get_path
()
if
self
.
server
.
nodes
.
base_structure_type
in
path
:
attrs
.
DataTypeDefinition
=
self
.
_get_sdef
(
node
,
obj
)
else
:
_logger
.
warning
(
"%s has datatypedefinition and path %s but we could not find out if this is a struct"
,
obj
,
path
)
node
.
NodeAttributes
=
attrs
res
=
await
self
.
_get_server
().
add_nodes
([
node
])
res
[
0
].
StatusCode
.
check
()
...
...
@@ -401,9 +418,9 @@ class XmlImporter:
for
data
in
obj
.
refs
:
ref
=
ua
.
AddReferencesItem
()
ref
.
IsForward
=
data
.
forward
ref
.
ReferenceTypeId
=
self
.
to_nodeid
(
data
.
reftype
)
ref
.
SourceNodeId
=
self
.
_migrate_ns
(
obj
.
nodeid
)
ref
.
TargetNodeId
=
self
.
to_nodeid
(
data
.
target
)
ref
.
ReferenceTypeId
=
data
.
reftype
ref
.
SourceNodeId
=
obj
.
nodeid
ref
.
TargetNodeId
=
data
.
target
refs
.
append
(
ref
)
await
self
.
_add_references
(
refs
)
...
...
@@ -430,17 +447,17 @@ class XmlImporter:
return
None
sdef
=
ua
.
StructureDefinition
()
if
obj
.
parent
:
sdef
.
BaseDataType
=
self
.
to_nodeid
(
obj
.
parent
)
sdef
.
BaseDataType
=
obj
.
parent
for
data
in
obj
.
refs
:
if
data
.
reftype
==
"HasEncoding"
:
# looks likebinary encodingisthe firt one...can someone confirm?
sdef
.
DefaultEncodingId
=
self
.
to_nodeid
(
data
.
target
)
sdef
.
DefaultEncodingId
=
data
.
target
break
optional
=
False
for
field
in
obj
.
definitions
:
f
=
ua
.
StructureField
()
f
.
Name
=
field
.
name
f
.
DataType
=
self
.
to_nodeid
(
field
.
datatype
)
f
.
DataType
=
field
.
datatype
f
.
ValueRank
=
field
.
valuerank
f
.
IsOptional
=
field
.
optional
if
f
.
IsOptional
:
...
...
@@ -468,7 +485,7 @@ class XmlImporter:
all_node_ids
=
[
data
.
nodeid
for
data
in
ndatas
]
while
ndatas
:
for
ndata
in
ndatas
[:]:
if
ndata
.
nodeid
.
NamespaceIndex
not
in
self
.
namespaces
or
\
if
ndata
.
nodeid
.
NamespaceIndex
not
in
self
.
namespaces
.
values
()
or
\
ndata
.
parent
is
None
or
\
ndata
.
parent
not
in
all_node_ids
:
sorted_ndatas
.
append
(
ndata
)
...
...
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