23 from __future__
import print_function
24 from ua_namespace
import *
27 from open62541_XMLPreprocessor
import open62541_XMLPreprocessor
29 logger = logging.getLogger(__name__)
31 parser = argparse.ArgumentParser(
32 description=
"""Parse OPC UA NamespaceXML file(s) and create C code for generating nodes in open62541
34 generate_open62541CCode.py will first read all XML files passed on the command line, then link and check the namespace. All nodes that fulfill the basic requirements will then be printed as C-Code intended to be included in the open62541 OPC UA Server that will initialize the corresponding namespace.""",
35 formatter_class=argparse.RawDescriptionHelpFormatter)
36 parser.add_argument(
'infiles',
37 metavar=
"<namespaceXML>",
39 type=argparse.FileType(
'r'),
40 help=
'Namespace XML file(s). Note that the last definition of a node encountered will be used and all prior definitions are discarded.')
41 parser.add_argument(
'outputFile',
42 metavar=
'<outputFile>',
44 help=
'The basename for the <output file>.c and <output file>.h files to be generated. This will also be the function name used in the header and c-file.')
45 parser.add_argument(
'-i',
'--ignore',
46 metavar=
"<ignoreFile>",
47 type=argparse.FileType(
'r'),
51 help=
'Loads a list of NodeIDs stored in ignoreFile (one NodeID per line). The compiler will assume that these nodes have been created externally and not generate any code for them. They will however be linked to from other nodes.')
52 parser.add_argument(
'-b',
'--blacklist',
53 metavar=
"<blacklistFile>",
54 type=argparse.FileType(
'r'),
56 dest=
"blacklistFiles",
58 help=
'Loads a list of NodeIDs stored in blacklistFile (one NodeID per line). Any of the nodeIds encountered in this file will be removed from the namespace prior to compilation. Any references to these nodes will also be removed')
59 parser.add_argument(
'-s',
'--suppress',
60 metavar=
"<attribute>",
62 dest=
"suppressedAttributes",
63 choices=[
'description',
'browseName',
'displayName',
'writeMask',
'userWriteMask',
'nodeid'],
65 help=
"Suppresses the generation of some node attributes. Currently supported options are 'description', 'browseName', 'displayName', 'writeMask', 'userWriteMask' and 'nodeid'.")
67 parser.add_argument(
'-v',
'--verbose', action=
'count', help=
'Make the script more verbose. Can be applied up to 4 times')
69 args = parser.parse_args()
71 level = logging.CRITICAL
74 verbosity = int(args.verbose)
78 level = logging.WARNING
84 logging.basicConfig(level=level)
85 logger.setLevel(logging.INFO)
95 outfileh = open(args.outputFile+
".h",
r"w+")
96 outfilec = open(args.outputFile+
".c",
r"w+")
103 for xmlfile
in args.infiles:
104 logger.info(
"Preprocessing " +
str(xmlfile.name))
105 preProc.addDocument(xmlfile.name)
106 preProc.preprocessAll()
109 for xmlfile
in preProc.getPreProcessedFiles():
110 logger.info(
"Parsing " +
str(xmlfile))
114 namespaceArrayNames = preProc.getUsedNamespaceArrayNames()
115 for key
in namespaceArrayNames:
116 ns.addNamespace(key, namespaceArrayNames[key])
119 preProc.removePreprocessedFiles()
124 for blacklist
in args.blacklistFiles:
125 for line
in blacklist.readlines():
126 line = line.replace(
" ",
"")
127 id = line.replace(
"\n",
"")
128 if ns.getNodeByIDString(id) ==
None:
129 logger.info(
"Can't blacklist node, namespace does currently not contain a node with id " +
str(id))
131 ns.removeNodeById(line)
135 logger.info(
"Linking namespace nodes and references")
136 ns.linkOpenPointers()
147 logger.info(
"Building datatype encoding rules")
148 ns.buildEncodingRules()
152 logger.info(
"Allocating variables")
153 ns.allocateVariables()
160 for ignore
in args.ignoreFiles:
161 for line
in ignore.readlines():
162 line = line.replace(
" ",
"")
163 id = line.replace(
"\n",
"")
164 if ns.getNodeByIDString(id) ==
None:
165 logger.warn(
"Can't ignore node, Namespace does currently not contain a node with id " +
str(id))
167 ignoreNodes.append(ns.getNodeByIDString(id))
171 logger.info(
"Generating Header")
173 from os.path
import basename
174 generatedCode = ns.printOpen62541Header(ignoreNodes, args.suppressedAttributes, outfilename=basename(args.outputFile))
175 for line
in generatedCode[0]:
176 outfileh.write(line+
"\n")
177 for line
in generatedCode[1]:
178 outfilec.write(line+
"\n")
183 logger.info(
"Namespace generation code successfully printed")