Commit 10a9064b authored by oroulet's avatar oroulet Committed by oroulet

change command line so that it generestes static code for structures from a server, not only xml

This is necessary since xml does not contain typeid
parent b698bc87
......@@ -40,6 +40,7 @@ class Struct(object):
self.name = name
self.fields = []
self.code = ""
self.typeid = None
def get_code(self):
if not self.fields:
......@@ -177,7 +178,7 @@ class StructGenerator(object):
def _make_registration(self):
code = "\n\n"
for struct in self.model:
code += "\nsetattr(ua, '{name}', {name})\n".format(name=struct.name)
code += "ua.register_extension_object('{name}', ua.NodeId.from_string('{nodeid}'), {name})\n".format(name=struct.name, nodeid=struct.typeid)
return code
def get_python_classes(self, env=None):
......@@ -232,13 +233,17 @@ import uuid
from opcua import ua
""")
def set_typeid(self, name, typeid):
for struct in self.model:
if struct.name == name:
struct.typeid = typeid
return
def load_type_definitions(server, nodes=None):
"""
Download xml from given variable node defining custom structures.
If no no node is given, attemps to import variables from all nodes under
If no node is given, attemps to import variables from all nodes under
"0:OPC Binary"
the code is generated and imported on the fly. If you know the structures
are not going to be modified it might be interresting to copy the generated files
......@@ -251,10 +256,12 @@ def load_type_definitions(server, nodes=None):
nodes.append(server.get_node(desc.NodeId))
structs_dict = {}
generators = []
for node in nodes:
xml = node.get_value()
xml = xml.decode("utf-8")
generator = StructGenerator()
generators.append(generator)
generator.make_model_from_string(xml)
# generate and execute new code on the fly
generator.get_python_classes(structs_dict)
......@@ -277,6 +284,9 @@ def load_type_definitions(server, nodes=None):
continue
nodeid = ref_desc_list[0].NodeId
ua.register_extension_object(name, nodeid, structs_dict[name])
# save the typeid if user want to create static file for type definitnion
generator.set_typeid(name, nodeid.to_string())
return generators, structs_dict
def _clean_name(name):
......
import os
import logging
import sys
import argparse
......@@ -19,7 +18,6 @@ from opcua import Client
from opcua import Server
from opcua import Node
from opcua import uamethod
from opcua.common.structures_generator import StructGenerator
def add_minimum_args(parser):
......@@ -41,12 +39,13 @@ def add_minimum_args(parser):
help="Set socket timeout (NOT the diverse UA timeouts)")
def add_common_args(parser, default_node='i=84'):
def add_common_args(parser, default_node='i=84', require_node=False):
add_minimum_args(parser)
parser.add_argument("-n",
"--nodeid",
help="Fully-qualified node ID (for example: i=85). Default: root node",
default=default_node,
required=require_node,
metavar="NODE")
parser.add_argument("-p",
"--path",
......@@ -729,12 +728,7 @@ def uacall():
def uageneratestructs():
parser = argparse.ArgumentParser(description="Generate a Python module from the xml structure definition (.bsd)")
parser.add_argument("-i",
"--input",
dest="input_path",
required=True,
help="The xml file definning the custom OPC UA structures.",
)
add_common_args(parser, require_node=True)
parser.add_argument("-o",
"--output",
dest="output_path",
......@@ -743,15 +737,15 @@ def uageneratestructs():
default=None,
help="The python file to be generated.",
)
args = parse_args(parser, requirenodeid=True)
args = parser.parse_args()
if not os.path.isfile(args.output_path):
parser.print_usage()
return 1
generator = StructGenerator()
generator.make_model_from_file(args.input_path)
generator.save_to_file(args.output_path, True)
client = Client(args.url, timeout=args.timeout)
client.set_security_string(args.security)
client.connect()
try:
node = get_node(client, args)
generators, _ = client.load_type_definitions([node])
generators[0].save_to_file(args.output_path, True)
finally:
client.disconnect()
sys.exit(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