123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- from __future__ import print_function
- from ua_namespace import *
- import logging
- import argparse
- from open62541_XMLPreprocessor import open62541_XMLPreprocessor
- logger = logging.getLogger(__name__)
- parser = argparse.ArgumentParser(
- description="""Parse OPC UA NamespaceXML file(s) and create C code for generating nodes in open62541
- 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.""",
- formatter_class=argparse.RawDescriptionHelpFormatter)
- parser.add_argument('infiles',
- metavar="<namespaceXML>",
- nargs='+',
- type=argparse.FileType('r'),
- help='Namespace XML file(s). Note that the last definition of a node encountered will be used and all prior definitions are discarded.')
- parser.add_argument('outputFile',
- metavar='<outputFile>',
-
- 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.')
- parser.add_argument('-i','--ignore',
- metavar="<ignoreFile>",
- type=argparse.FileType('r'),
- action='append',
- dest="ignoreFiles",
- default=[],
- 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.')
- parser.add_argument('-b','--blacklist',
- metavar="<blacklistFile>",
- type=argparse.FileType('r'),
- action='append',
- dest="blacklistFiles",
- default=[],
- 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')
- parser.add_argument('-s','--suppress',
- metavar="<attribute>",
- action='append',
- dest="suppressedAttributes",
- choices=['description', 'browseName', 'displayName', 'writeMask', 'userWriteMask','nodeid'],
- default=[],
- help="Suppresses the generation of some node attributes. Currently supported options are 'description', 'browseName', 'displayName', 'writeMask', 'userWriteMask' and 'nodeid'.")
- parser.add_argument('-v','--verbose', action='count', help='Make the script more verbose. Can be applied up to 4 times')
- args = parser.parse_args()
- level = logging.CRITICAL
- verbosity = 0
- if args.verbose:
- verbosity = int(args.verbose)
- if (verbosity==1):
- level = logging.ERROR
- elif (verbosity==2):
- level = logging.WARNING
- elif (verbosity==3):
- level = logging.INFO
- elif (verbosity>=4):
- level = logging.DEBUG
- logging.basicConfig(level=level)
- logger.setLevel(logging.INFO)
- outfileh = open(args.outputFile+".h", r"w+")
- outfilec = open(args.outputFile+".c", r"w+")
- ns = opcua_namespace("open62541")
- preProc = open62541_XMLPreprocessor()
- for xmlfile in args.infiles:
- logger.info("Preprocessing " + str(xmlfile.name))
- preProc.addDocument(xmlfile.name)
- preProc.preprocessAll()
- for xmlfile in preProc.getPreProcessedFiles():
- logger.info("Parsing " + str(xmlfile))
- ns.parseXML(xmlfile)
- namespaceArrayNames = preProc.getUsedNamespaceArrayNames()
- for key in namespaceArrayNames:
- ns.addNamespace(key, namespaceArrayNames[key])
- preProc.removePreprocessedFiles()
- for blacklist in args.blacklistFiles:
- for line in blacklist.readlines():
- line = line.replace(" ","")
- id = line.replace("\n","")
- if ns.getNodeByIDString(id) == None:
- logger.info("Can't blacklist node, namespace does currently not contain a node with id " + str(id))
- else:
- ns.removeNodeById(line)
- blacklist.close()
- logger.info("Linking namespace nodes and references")
- ns.linkOpenPointers()
- ns.sanitize()
- logger.info("Building datatype encoding rules")
- ns.buildEncodingRules()
- logger.info("Allocating variables")
- ns.allocateVariables()
- ignoreNodes = []
- for ignore in args.ignoreFiles:
- for line in ignore.readlines():
- line = line.replace(" ","")
- id = line.replace("\n","")
- if ns.getNodeByIDString(id) == None:
- logger.warn("Can't ignore node, Namespace does currently not contain a node with id " + str(id))
- else:
- ignoreNodes.append(ns.getNodeByIDString(id))
- ignore.close()
- logger.info("Generating Header")
- from os.path import basename
- generatedCode = ns.printOpen62541Header(ignoreNodes, args.suppressedAttributes, outfilename=basename(args.outputFile))
- for line in generatedCode[0]:
- outfileh.write(line+"\n")
- for line in generatedCode[1]:
- outfilec.write(line+"\n")
- outfilec.close()
- outfileh.close()
- logger.info("Namespace generation code successfully printed")
|