Browse Source

Use standard python libraries for logging and argparsing in namespace compiler (#669)

Markus Graube 8 years ago
parent
commit
09dcc4644d

+ 0 - 2
CMakeLists.txt

@@ -296,7 +296,6 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_namespaceinit_g
                                                 ${PROJECT_BINARY_DIR}/src_generated/ua_namespaceinit_generated
                                                 ${PROJECT_BINARY_DIR}/src_generated/ua_namespaceinit_generated
                    DEPENDS ${PROJECT_SOURCE_DIR}/tools/schema/namespace0/${GENERATE_NAMESPACE0_FILE}
                    DEPENDS ${PROJECT_SOURCE_DIR}/tools/schema/namespace0/${GENERATE_NAMESPACE0_FILE}
                            ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/generate_open62541CCode.py
                            ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/generate_open62541CCode.py
-                           ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/logger.py
                            ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/open62541_MacroHelper.py
                            ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/open62541_MacroHelper.py
                            ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/ua_builtin_types.py
                            ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/ua_builtin_types.py
                            ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/ua_constants.py
                            ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/ua_constants.py
@@ -470,7 +469,6 @@ if(UA_BUILD_EXAMPLES)
                                                     ${PROJECT_SOURCE_DIR}/examples/server_nodeset.xml
                                                     ${PROJECT_SOURCE_DIR}/examples/server_nodeset.xml
                                                     ${PROJECT_BINARY_DIR}/src_generated/nodeset
                                                     ${PROJECT_BINARY_DIR}/src_generated/nodeset
                       DEPENDS ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/generate_open62541CCode.py
                       DEPENDS ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/generate_open62541CCode.py
-                              ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/logger.py
                               ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/open62541_MacroHelper.py
                               ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/open62541_MacroHelper.py
                               ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/ua_builtin_types.py
                               ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/ua_builtin_types.py
                               ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/ua_constants.py
                               ${PROJECT_SOURCE_DIR}/tools/pyUANamespace/ua_constants.py

+ 83 - 104
tools/pyUANamespace/generate_open62541CCode.py

@@ -3,7 +3,7 @@
 
 
 ###
 ###
 ### Author:  Chris Iatrou (ichrispa@core-vector.net)
 ### Author:  Chris Iatrou (ichrispa@core-vector.net)
-### Version: rev 13
+### Version: rev 14
 ###
 ###
 ### This program was created for educational purposes and has been
 ### This program was created for educational purposes and has been
 ### contributed to the open62541 project by the author. All licensing
 ### contributed to the open62541 project by the author. All licensing
@@ -17,87 +17,67 @@
 ###
 ###
 
 
 from __future__ import print_function
 from __future__ import print_function
-from sys import argv, exit
-from os import path
 from ua_namespace import *
 from ua_namespace import *
-from logger import *
+import logging
+import argparse
 from open62541_XMLPreprocessor import open62541_XMLPreprocessor
 from open62541_XMLPreprocessor import open62541_XMLPreprocessor
 
 
-def usage():
-  print("Script usage:")
-  print("generate_open62541CCode [-i <ignorefile> | -b <blacklistfile>] <namespace XML> [namespace.xml[ namespace.xml[...]]] <output file>\n")
-  print("generate_open62541CCode will first read all XML files passed on the command line, then ")
-  print("link and check the namespace. All nodes that fullfill the basic requirements will then be")
-  print("printed as C-Code intended to be included in the open62541 OPC-UA Server that will")
-  print("initialize the corresponding name space.\n")
-  print("Manditory Arguments:")
-  print("<namespace XML>    At least one Namespace XML file must be passed.")
-  print("<output file>      The basename for the <output file>.c and <output file>.h files to be generated.")
-  print("                   This will also be the function name used in the header and c-file.\n\n")
-  print("Additional Arguments:")
-  print("""   -i <ignoreFile>     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.""")
-  print("""   -b <blacklistFile>  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""")
-  print("""   -s <attribute>  Suppresses the generation of some node attributes. Currently supported
-                       options are 'description', 'browseName', 'displayName', 'writeMask', 'userWriteMask'
-                       and 'nodeid'.""")
-  print("""   namespaceXML Any number of namespace descriptions in XML format. Note that the
-                       last description of a node encountered will be used and all prior definitions
-                       are discarded.""")
+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>',
+                    #type=argparse.FileType('w', 0),
+                    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 creathed 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')
+
+
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
-  # Check if the parameters given correspond to actual files
-  infiles = []
-  ouffile = ""
-  ignoreFiles = []
-  blacklistFiles = []
-  supressGenerationOfAttribute=[]
-
-  GLOBAL_LOG_LEVEL = LOG_LEVEL_DEBUG
-  
-  arg_isIgnore    = False
-  arg_isBlacklist = False
-  arg_isSupress   = False
-  if len(argv) < 2:
-    usage()
-    exit(1)
-  for filename in argv[1:-1]:
-    if arg_isIgnore:
-      arg_isIgnore = False
-      if path.exists(filename):
-        ignoreFiles.append(filename)
-      else:
-        log(None, "File " + str(filename) + " does not exist.", LOG_LEVEL_ERROR)
-        usage()
-        exit(1)
-    elif arg_isBlacklist:
-      arg_isBlacklist = False
-      if path.exists(filename):
-        blacklistFiles.append(filename)
-      else:
-        log(None, "File " + str(filename) + " does not exist.", LOG_LEVEL_ERROR)
-        usage()
-        exit(1)
-    elif arg_isSupress:
-      arg_isSupress = False
-      supressGenerationOfAttribute.append(filename.lower())
-    else:
-      if path.exists(filename):
-        infiles.append(filename)
-      elif filename.lower() == "-i" or filename.lower() == "--ignore" :
-        arg_isIgnore = True
-      elif filename.lower() == "-b" or filename.lower() == "--blacklist" :
-        arg_isBlacklist = True
-      elif filename.lower() == "-s" or filename.lower() == "--suppress" :
-        arg_isSupress = True
-      else:
-        log(None, "File " + str(filename) + " does not exist.", LOG_LEVEL_ERROR)
-        usage()
-        exit(1)
+  args = parser.parse_args()
+
+  level= logging.CRITICAL
+  if (args.verbose==1):
+    level = logging.ERROR
+  elif (args.verbose==2):
+    level = logging.WARNING
+  elif (args.verbose==3):
+    level = logging.INFO
+  elif (args.verbose>=4):
+    level = logging.DEBUG
+  logging.basicConfig(level=level)
+  logger.setLevel(logging.INFO)
 
 
   # Creating the header is tendious. We can skip the entire process if
   # Creating the header is tendious. We can skip the entire process if
   # the header exists.
   # the header exists.
@@ -107,8 +87,8 @@ if __name__ == '__main__':
   #  exit(0)
   #  exit(0)
 
 
   # Open the output file
   # Open the output file
-  outfileh = open(argv[-1]+".h", r"w+")
-  outfilec = open(argv[-1]+".c", r"w+")
+  outfileh = open(args.outputFile+".h", r"w+")
+  outfilec = open(args.outputFile+".c", r"w+")
 
 
   # Create a new namespace
   # Create a new namespace
   # Note that the name is actually completely symbolic, it has no other
   # Note that the name is actually completely symbolic, it has no other
@@ -119,40 +99,39 @@ if __name__ == '__main__':
 
 
   # Clean up the XML files by removing duplicate namespaces and unwanted prefixes
   # Clean up the XML files by removing duplicate namespaces and unwanted prefixes
   preProc = open62541_XMLPreprocessor()
   preProc = open62541_XMLPreprocessor()
-  for xmlfile in infiles:
-    log(None, "Preprocessing " + str(xmlfile), LOG_LEVEL_INFO)
-    preProc.addDocument(xmlfile)
+  for xmlfile in args.infiles:
+    logger.info("Preprocessing " + str(xmlfile.name))
+    preProc.addDocument(xmlfile.name)
   preProc.preprocessAll()
   preProc.preprocessAll()
-  
+
   for xmlfile in preProc.getPreProcessedFiles():
   for xmlfile in preProc.getPreProcessedFiles():
-    log(None, "Parsing " + str(xmlfile), LOG_LEVEL_INFO)
+    logger.info("Parsing " + str(xmlfile))
     ns.parseXML(xmlfile)
     ns.parseXML(xmlfile)
-  
+
   # We need to notify the open62541 server of the namespaces used to be able to use i.e. ns=3
   # We need to notify the open62541 server of the namespaces used to be able to use i.e. ns=3
   namespaceArrayNames = preProc.getUsedNamespaceArrayNames()
   namespaceArrayNames = preProc.getUsedNamespaceArrayNames()
   for key in namespaceArrayNames:
   for key in namespaceArrayNames:
     ns.addNamespace(key, namespaceArrayNames[key])
     ns.addNamespace(key, namespaceArrayNames[key])
-    
+
   # Remove any temp files - they are not needed after the AST is created
   # Remove any temp files - they are not needed after the AST is created
   # Removed for debugging
   # Removed for debugging
   preProc.removePreprocessedFiles()
   preProc.removePreprocessedFiles()
-  
+
   # Remove blacklisted nodes from the namespace
   # Remove blacklisted nodes from the namespace
   # Doing this now ensures that unlinkable pointers will be cleanly removed
   # Doing this now ensures that unlinkable pointers will be cleanly removed
   # during sanitation.
   # during sanitation.
-  for blacklist in blacklistFiles:
-    bl = open(blacklist, "r")
-    for line in bl.readlines():
+  for blacklist in args.blacklistFiles:
+    for line in blacklist.readlines():
       line = line.replace(" ","")
       line = line.replace(" ","")
       id = line.replace("\n","")
       id = line.replace("\n","")
       if ns.getNodeByIDString(id) == None:
       if ns.getNodeByIDString(id) == None:
-        log(None, "Can't blacklist node, namespace does currently not contain a node with id " + str(id), LOG_LEVEL_WARN)
+        logger.info("Can't blacklist node, namespace does currently not contain a node with id " + str(id))
       else:
       else:
         ns.removeNodeById(line)
         ns.removeNodeById(line)
-    bl.close()
+    blacklist.close()
 
 
   # Link the references in the namespace
   # Link the references in the namespace
-  log(None, "Linking namespace nodes and references", LOG_LEVEL_INFO)
+  logger.info("Linking namespace nodes and references")
   ns.linkOpenPointers()
   ns.linkOpenPointers()
 
 
   # Remove nodes that are not printable or contain parsing errors, such as
   # Remove nodes that are not printable or contain parsing errors, such as
@@ -164,12 +143,12 @@ if __name__ == '__main__':
   # Ex. <rpm>123</rpm> is not encodable
   # Ex. <rpm>123</rpm> is not encodable
   #     only after parsing the datatypes, it is known that
   #     only after parsing the datatypes, it is known that
   #     rpm is encoded as a double
   #     rpm is encoded as a double
-  log(None, "Building datatype encoding rules", LOG_LEVEL_INFO)
+  logger.info("Building datatype encoding rules")
   ns.buildEncodingRules()
   ns.buildEncodingRules()
 
 
   # Allocate/Parse the data values. In order to do this, we must have run
   # Allocate/Parse the data values. In order to do this, we must have run
   # buidEncodingRules.
   # buidEncodingRules.
-  log(None, "Allocating variables", LOG_LEVEL_INFO)
+  logger.info("Allocating variables")
   ns.allocateVariables()
   ns.allocateVariables()
 
 
   # Users may have manually defined some nodes in their code already (such as serverStatus).
   # Users may have manually defined some nodes in their code already (such as serverStatus).
@@ -177,26 +156,26 @@ if __name__ == '__main__':
   # converted to C-Code. That way, they will still be reffered to by other nodes, but
   # converted to C-Code. That way, they will still be reffered to by other nodes, but
   # they will not be created themselves.
   # they will not be created themselves.
   ignoreNodes = []
   ignoreNodes = []
-  for ignore in ignoreFiles:
-    ig = open(ignore, "r")
-    for line in ig.readlines():
+  for ignore in args.ignoreFiles:
+    for line in ignore.readlines():
       line = line.replace(" ","")
       line = line.replace(" ","")
       id = line.replace("\n","")
       id = line.replace("\n","")
       if ns.getNodeByIDString(id) == None:
       if ns.getNodeByIDString(id) == None:
-        log(None, "Can't ignore node, Namespace does currently not contain a node with id " + str(id), LOG_LEVEL_WARN)
+        logger.warn("Can't ignore node, Namespace does currently not contain a node with id " + str(id))
       else:
       else:
         ignoreNodes.append(ns.getNodeByIDString(id))
         ignoreNodes.append(ns.getNodeByIDString(id))
-    ig.close()
-  
+    ignore.close()
+
   # Create the C Code
   # Create the C Code
-  log(None, "Generating Header", LOG_LEVEL_INFO)
+  logger.info("Generating Header")
   # Returns a tuple of (["Header","lines"],["Code","lines","generated"])
   # Returns a tuple of (["Header","lines"],["Code","lines","generated"])
-  generatedCode=ns.printOpen62541Header(ignoreNodes, supressGenerationOfAttribute, outfilename=path.basename(argv[-1]))
+  from os.path import basename
+  generatedCode=ns.printOpen62541Header(ignoreNodes, args.suppressedAttributes, outfilename=basename(args.outputFile))
   for line in generatedCode[0]:
   for line in generatedCode[0]:
     outfileh.write(line+"\n")
     outfileh.write(line+"\n")
   for line in generatedCode[1]:
   for line in generatedCode[1]:
     outfilec.write(line+"\n")
     outfilec.write(line+"\n")
- 
+
   outfilec.close()
   outfilec.close()
   outfileh.close()
   outfileh.close()
 
 

+ 0 - 46
tools/pyUANamespace/logger.py

@@ -1,46 +0,0 @@
-#!/usr/bin/env/python
-# -*- coding: utf-8 -*-
-
-###
-### Author:  Chris Iatrou (ichrispa@core-vector.net)
-### Version: rev 13
-###
-### This program was created for educational purposes and has been
-### contributed to the open62541 project by the author. All licensing
-### terms for this source is inherited by the terms and conditions
-### specified for by the open62541 project (see the projects readme
-### file for more information on the LGPL terms and restrictions).
-###
-### This program is not meant to be used in a production environment. The
-### author is not liable for any complications arising due to the use of
-### this program.
-###
-
-from __future__ import print_function
-import inspect
-
-###
-### Tidy logging helpers
-###
-
-LOG_LEVEL_DEBUG  = 4
-LOG_LEVEL_INFO   = 2
-LOG_LEVEL_WARN   = 1
-LOG_LEVEL_ERROR  = 0
-LOG_LEVEL_SILENT = -1
-
-# Change the following to filter logging output
-GLOBAL_LOG_LEVEL = LOG_LEVEL_SILENT
-
-def log(callee, logstr, level=LOG_LEVEL_DEBUG):
-  prefixes = { LOG_LEVEL_DEBUG : "DBG: ",
-               LOG_LEVEL_INFO  : "INF: ",
-               LOG_LEVEL_WARN  : "WRN: ",
-               LOG_LEVEL_ERROR : "ERR: ",
-               LOG_LEVEL_SILENT: ""
-            }
-  if level <= GLOBAL_LOG_LEVEL:
-    if prefixes.has_key(level):
-      print(str(prefixes[level]) + callee.__class__.__name__ + "." + inspect.stack()[1][3] +  "(): " + logstr)
-    else:
-      print(callee.__class__.__name__  + "." + inspect.stack()[1][3] + "(): " + logstr)

+ 21 - 18
tools/pyUANamespace/open62541_MacroHelper.py

@@ -16,10 +16,13 @@
 ### this program.
 ### this program.
 ###
 ###
 
 
-from logger import *
+import logging
 from ua_constants import *
 from ua_constants import *
 import string
 import string
 
 
+
+logger = logging.getLogger(__name__)
+
 __unique_item_id = 0
 __unique_item_id = 0
 
 
 defined_typealiases = []
 defined_typealiases = []
@@ -34,20 +37,20 @@ class open62541_MacroHelper():
     elif node.id().s != None:
     elif node.id().s != None:
       return "UA_EXPANDEDNODEID_STRING("  + str(node.id().ns) + ", " + node.id().s + ")"
       return "UA_EXPANDEDNODEID_STRING("  + str(node.id().ns) + ", " + node.id().s + ")"
     elif node.id().b != None:
     elif node.id().b != None:
-      log(self, "NodeID Generation macro for bytestrings has not been implemented.")
+      logger.debug("NodeID Generation macro for bytestrings has not been implemented.")
       return ""
       return ""
     elif node.id().g != None:
     elif node.id().g != None:
-      log(self, "NodeID Generation macro for guids has not been implemented.")
+      logger.debug("NodeID Generation macro for guids has not been implemented.")
       return ""
       return ""
     else:
     else:
       return ""
       return ""
 
 
   def substitutePunctuationCharacters(self, input):
   def substitutePunctuationCharacters(self, input):
     ''' substitutePunctuationCharacters
     ''' substitutePunctuationCharacters
-    
+
         Replace punctuation characters in input. Part of this class because it is used by
         Replace punctuation characters in input. Part of this class because it is used by
         ua_namespace on occasion.
         ua_namespace on occasion.
-        
+
         returns: C-printable string representation of input
         returns: C-printable string representation of input
     '''
     '''
     # No punctuation characters <>!$
     # No punctuation characters <>!$
@@ -62,7 +65,7 @@ class open62541_MacroHelper():
         substitution = substitution + '_'
         substitution = substitution + '_'
 
 
     return input.translate(string.maketrans(illegal, substitution), illegal)
     return input.translate(string.maketrans(illegal, substitution), illegal)
-  
+
   def getNodeIdDefineString(self, node):
   def getNodeIdDefineString(self, node):
     code = []
     code = []
     extrNs = node.browseName().split(":")
     extrNs = node.browseName().split(":")
@@ -75,18 +78,18 @@ class open62541_MacroHelper():
 
 
     symbolic_name = self.substitutePunctuationCharacters(nodename)
     symbolic_name = self.substitutePunctuationCharacters(nodename)
     if symbolic_name != nodename :
     if symbolic_name != nodename :
-        log(self, "Subsituted characters in browsename for nodeid " + str(node.id().i) + " while generating C-Code ", LOG_LEVEL_WARN)
-    
+        logger.warn("Subsituted characters in browsename for nodeid " + str(node.id().i) + " while generating C-Code ")
+
     if symbolic_name in defined_typealiases:
     if symbolic_name in defined_typealiases:
-      log(self, "Typealias definition of " + str(node.id().i) + " is non unique!", LOG_LEVEL_WARN)
+      logger.warn(self, "Typealias definition of " + str(node.id().i) + " is non unique!")
       extendedN = 1
       extendedN = 1
       while (symbolic_name+"_"+str(extendedN) in defined_typealiases):
       while (symbolic_name+"_"+str(extendedN) in defined_typealiases):
-        log(self, "Typealias definition of " + str(node.id().i) + " is non unique!", LOG_LEVEL_WARN)
+        logger.warn("Typealias definition of " + str(node.id().i) + " is non unique!")
         extendedN+=1
         extendedN+=1
-      symbolic_name = symbolic_name+"_"+str(extendedN) 
-      
+      symbolic_name = symbolic_name+"_"+str(extendedN)
+
     defined_typealiases.append(symbolic_name)
     defined_typealiases.append(symbolic_name)
-      
+
     code.append("#define UA_NS"  + str(node.id().ns) + "ID_" + symbolic_name.upper() + " " + str(node.id().i))
     code.append("#define UA_NS"  + str(node.id().ns) + "ID_" + symbolic_name.upper() + " " + str(node.id().i))
     return code
     return code
 
 
@@ -96,10 +99,10 @@ class open62541_MacroHelper():
     elif node.id().s != None:
     elif node.id().s != None:
       return "UA_NODEID_STRING("  + str(node.id().ns) + ", " + node.id().s + ")"
       return "UA_NODEID_STRING("  + str(node.id().ns) + ", " + node.id().s + ")"
     elif node.id().b != None:
     elif node.id().b != None:
-      log(self, "NodeID Generation macro for bytestrings has not been implemented.")
+      logger.debug("NodeID Generation macro for bytestrings has not been implemented.")
       return ""
       return ""
     elif node.id().g != None:
     elif node.id().g != None:
-      log(self, "NodeID Generation macro for guids has not been implemented.")
+      logger.debug("NodeID Generation macro for guids has not been implemented.")
       return ""
       return ""
     else:
     else:
       return ""
       return ""
@@ -284,20 +287,20 @@ class open62541_MacroHelper():
         code.append(node.getCodePrintableID() + "->nodeId.identifier.numeric = " + str(node.id().i) + ";")
         code.append(node.getCodePrintableID() + "->nodeId.identifier.numeric = " + str(node.id().i) + ";")
       elif node.id().b != None:
       elif node.id().b != None:
         code.append(node.getCodePrintableID() + "->nodeId.identifierType = UA_NODEIDTYPE_BYTESTRING;")
         code.append(node.getCodePrintableID() + "->nodeId.identifierType = UA_NODEIDTYPE_BYTESTRING;")
-        log(self, "ByteString IDs for nodes has not been implemented yet.", LOG_LEVEL_ERROR)
+        logger.error("ByteString IDs for nodes has not been implemented yet.")
         return []
         return []
       elif node.id().g != None:
       elif node.id().g != None:
         #<jpfr> the string is sth like { .length = 111, .data = <ptr> }
         #<jpfr> the string is sth like { .length = 111, .data = <ptr> }
         #<jpfr> there you _may_ alloc the <ptr> on the heap
         #<jpfr> there you _may_ alloc the <ptr> on the heap
         #<jpfr> for the guid, just set it to {.data1 = 111, .data2 = 2222, ....
         #<jpfr> for the guid, just set it to {.data1 = 111, .data2 = 2222, ....
         code.append(node.getCodePrintableID() + "->nodeId.identifierType = UA_NODEIDTYPE_GUID;")
         code.append(node.getCodePrintableID() + "->nodeId.identifierType = UA_NODEIDTYPE_GUID;")
-        log(self, "GUIDs for nodes has not been implemented yet.", LOG_LEVEL_ERROR)
+        logger.error(self, "GUIDs for nodes has not been implemented yet.")
         return []
         return []
       elif node.id().s != None:
       elif node.id().s != None:
         code.append(node.getCodePrintableID() + "->nodeId.identifierType = UA_NODEIDTYPE_STRING;")
         code.append(node.getCodePrintableID() + "->nodeId.identifierType = UA_NODEIDTYPE_STRING;")
         code.append(node.getCodePrintableID() + "->nodeId.identifier.numeric = UA_STRING_ALLOC(\"" + str(node.id().i) + "\");")
         code.append(node.getCodePrintableID() + "->nodeId.identifier.numeric = UA_STRING_ALLOC(\"" + str(node.id().i) + "\");")
       else:
       else:
-        log(self, "Node ID is not numeric, bytestring, guid or string. I do not know how to create c code for that...", LOG_LEVEL_ERROR)
+        logger.error("Node ID is not numeric, bytestring, guid or string. I do not know how to create c code for that...")
         return []
         return []
 
 
     return code
     return code

+ 82 - 82
tools/pyUANamespace/open62541_XMLPreprocessor.py

@@ -15,7 +15,7 @@
 ### this program.
 ### this program.
 ###
 ###
 
 
-from logger import *
+import logging
 from ua_constants import *
 from ua_constants import *
 import tempfile
 import tempfile
 import xml.dom.minidom as dom
 import xml.dom.minidom as dom
@@ -25,6 +25,9 @@ from collections import Counter
 
 
 from ua_namespace import opcua_node_id_t
 from ua_namespace import opcua_node_id_t
 
 
+
+logger = logging.getLogger(__name__)
+
 class preProcessDocument:
 class preProcessDocument:
   originXML = '' # Original XML passed to the preprocessor
   originXML = '' # Original XML passed to the preprocessor
   targetXML = () # tuple of (fileHandle, fileName)
   targetXML = () # tuple of (fileHandle, fileName)
@@ -35,7 +38,7 @@ class preProcessDocument:
   namespaceOrder  = [] # contains xmlns:sX attributed as tuples (int ns, string name)
   namespaceOrder  = [] # contains xmlns:sX attributed as tuples (int ns, string name)
   namespaceQualifiers = []      # contains all xmlns:XYZ qualifiers that might prefix value aliases (like "<uax:Int32>")
   namespaceQualifiers = []      # contains all xmlns:XYZ qualifiers that might prefix value aliases (like "<uax:Int32>")
   referencedNamesSpaceUris = [] # contains <NamespaceUris> URI elements
   referencedNamesSpaceUris = [] # contains <NamespaceUris> URI elements
-  
+
   def __init__(self, originXML):
   def __init__(self, originXML):
     self.originXML = originXML
     self.originXML = originXML
     self.targetXML = tempfile.mkstemp(prefix=os.path.basename(originXML)+"_preProcessed-" ,suffix=".xml")
     self.targetXML = tempfile.mkstemp(prefix=os.path.basename(originXML)+"_preProcessed-" ,suffix=".xml")
@@ -48,29 +51,29 @@ class preProcessDocument:
     try:
     try:
       self.nodeset = dom.parse(originXML)
       self.nodeset = dom.parse(originXML)
       if len(self.nodeset.getElementsByTagName("UANodeSet")) == 0 or len(self.nodeset.getElementsByTagName("UANodeSet")) > 1:
       if len(self.nodeset.getElementsByTagName("UANodeSet")) == 0 or len(self.nodeset.getElementsByTagName("UANodeSet")) > 1:
-        log(self, "Document " + self.targetXML[1] + " contains no or more then 1 nodeset", LOG_LEVEL_ERROR)
+        logger.error(self, "Document " + self.targetXML[1] + " contains no or more then 1 nodeset", LOG_LEVEL_ERROR)
         self.parseOK   = False
         self.parseOK   = False
     except:
     except:
       self.parseOK   = False
       self.parseOK   = False
-    log(self, "Adding new document to be preprocessed " + os.path.basename(originXML) + " as " + self.targetXML[1], LOG_LEVEL_DEBUG)
-  
+    logger.debug("Adding new document to be preprocessed " + os.path.basename(originXML) + " as " + self.targetXML[1])
+
   def clean(self):
   def clean(self):
     #os.close(self.targetXML[0]) Don't -> done to flush() after finalize()
     #os.close(self.targetXML[0]) Don't -> done to flush() after finalize()
     os.remove(self.targetXML[1])
     os.remove(self.targetXML[1])
-  
+
   def getTargetXMLName(self):
   def getTargetXMLName(self):
     if (self.parseOK):
     if (self.parseOK):
       return self.targetXML[1]
       return self.targetXML[1]
     return None
     return None
-  
+
   def extractNamespaceURIs(self):
   def extractNamespaceURIs(self):
     """ extractNamespaceURIs
     """ extractNamespaceURIs
-        
+
         minidom gobbles up <NamespaceUris></NamespaceUris> elements, without a decent
         minidom gobbles up <NamespaceUris></NamespaceUris> elements, without a decent
-        way to reliably access this dom2 <uri></uri> elements (only attribute xmlns= are 
-        accessible using minidom).  We need them for dereferencing though... This 
+        way to reliably access this dom2 <uri></uri> elements (only attribute xmlns= are
+        accessible using minidom).  We need them for dereferencing though... This
         function attempts to do just that.
         function attempts to do just that.
-        
+
         returns: Nothing
         returns: Nothing
     """
     """
     infile = open(self.originXML)
     infile = open(self.originXML)
@@ -86,37 +89,37 @@ class preProcessDocument:
         break
         break
       if foundURIs:
       if foundURIs:
         nsline = nsline + line
         nsline = nsline + line
-    
+
     if len(nsline) > 0:
     if len(nsline) > 0:
       ns = dom.parseString(nsline).getElementsByTagName("NamespaceUris")
       ns = dom.parseString(nsline).getElementsByTagName("NamespaceUris")
       for uri in ns[0].childNodes:
       for uri in ns[0].childNodes:
         if uri.nodeType != uri.ELEMENT_NODE:
         if uri.nodeType != uri.ELEMENT_NODE:
           continue
           continue
         self.referencedNamesSpaceUris.append(uri.firstChild.data)
         self.referencedNamesSpaceUris.append(uri.firstChild.data)
-      
+
     infile.close()
     infile.close()
-    
+
   def analyze(self):
   def analyze(self):
     """ analyze()
     """ analyze()
-    
+
         analyze will gather information about the nodes and references contained in a XML File
         analyze will gather information about the nodes and references contained in a XML File
         to facilitate later preprocessing stages that adresss XML dependency issues
         to facilitate later preprocessing stages that adresss XML dependency issues
-        
+
         returns: No return value
         returns: No return value
-    """ 
+    """
     nodeIds = []
     nodeIds = []
     ns = self.nodeset.getElementsByTagName("UANodeSet")
     ns = self.nodeset.getElementsByTagName("UANodeSet")
-    
+
     # We need to find out what the namespace calls itself and other referenced, as numeric id's are pretty
     # We need to find out what the namespace calls itself and other referenced, as numeric id's are pretty
     # useless sans linked nodes. There is two information sources...
     # useless sans linked nodes. There is two information sources...
     self.extractNamespaceURIs() # From <URI>...</URI> definitions
     self.extractNamespaceURIs() # From <URI>...</URI> definitions
-    
+
     for key in ns[0].attributes.keys(): # from xmlns:sX attributes
     for key in ns[0].attributes.keys(): # from xmlns:sX attributes
       if "xmlns:" in key:  # Any key: we will be removing these qualifiers from Values later
       if "xmlns:" in key:  # Any key: we will be removing these qualifiers from Values later
         self.namespaceQualifiers.append(key.replace("xmlns:",""))
         self.namespaceQualifiers.append(key.replace("xmlns:",""))
       if "xmlns:s" in key: # get a numeric nsId and modelname/uri
       if "xmlns:s" in key: # get a numeric nsId and modelname/uri
         self.namespaceOrder.append((int(key.replace("xmlns:s","")), ns[0].getAttribute(key)))
         self.namespaceOrder.append((int(key.replace("xmlns:s","")), ns[0].getAttribute(key)))
-    
+
     # Get all nodeIds contained in this XML
     # Get all nodeIds contained in this XML
     for nd in ns[0].childNodes:
     for nd in ns[0].childNodes:
       if nd.nodeType != nd.ELEMENT_NODE:
       if nd.nodeType != nd.ELEMENT_NODE:
@@ -127,39 +130,39 @@ class preProcessDocument:
         for ref in refs.childNodes:
         for ref in refs.childNodes:
           if ref.nodeType == ref.ELEMENT_NODE:
           if ref.nodeType == ref.ELEMENT_NODE:
             self.referencedNodes.append( (opcua_node_id_t(ref.firstChild.data), ref) )
             self.referencedNodes.append( (opcua_node_id_t(ref.firstChild.data), ref) )
-    
-    log(self, "Nodes: " + str(len(self.containedNodes)) + " References: " + str(len(self.referencedNodes)), LOG_LEVEL_DEBUG)
-  
+
+    logger.debug("Nodes: " + str(len(self.containedNodes)) + " References: " + str(len(self.referencedNodes)))
+
   def getNamespaceId(self):
   def getNamespaceId(self):
     """ namespaceId()
     """ namespaceId()
-        
+
         Counts the namespace IDs in all nodes of this XML and picks the most used
         Counts the namespace IDs in all nodes of this XML and picks the most used
         namespace as the numeric identifier of this data model.
         namespace as the numeric identifier of this data model.
-        
+
         returns: Integer ID of the most propable/most used namespace in this XML
         returns: Integer ID of the most propable/most used namespace in this XML
     """
     """
     max = 0;
     max = 0;
     namespaceIdGuessed = 0;
     namespaceIdGuessed = 0;
     idDict = {}
     idDict = {}
-    
+
     for ndid in self.containedNodes:
     for ndid in self.containedNodes:
       if not idDict.has_key(ndid[0].ns):
       if not idDict.has_key(ndid[0].ns):
         idDict[ndid[0].ns] = 1
         idDict[ndid[0].ns] = 1
       else:
       else:
         idDict[ndid[0].ns] = idDict[ndid[0].ns] + 1
         idDict[ndid[0].ns] = idDict[ndid[0].ns] + 1
-    
+
     for entry in idDict:
     for entry in idDict:
       if idDict[entry] > max:
       if idDict[entry] > max:
         max = idDict[entry]
         max = idDict[entry]
         namespaceIdGuessed = entry
         namespaceIdGuessed = entry
-    log(self, "XML Contents are propably in namespace " + str(entry) + " (used by " + str(idDict[entry]) + " Nodes)", LOG_LEVEL_DEBUG)
+    logger.debug("XML Contents are propably in namespace " + str(entry) + " (used by " + str(idDict[entry]) + " Nodes)")
     return namespaceIdGuessed
     return namespaceIdGuessed
-  
+
   def getReferencedNamespaceUri(self, nsId):
   def getReferencedNamespaceUri(self, nsId):
     """ getReferencedNamespaceUri
     """ getReferencedNamespaceUri
-    
+
         returns an URL that hopefully corresponds to the nsId that was used to reference this model
         returns an URL that hopefully corresponds to the nsId that was used to reference this model
-        
+
         return: URI string corresponding to nsId
         return: URI string corresponding to nsId
     """
     """
     # Might be the more reliable method: Get the URI from the xmlns attributes (they have numers)
     # Might be the more reliable method: Get the URI from the xmlns attributes (they have numers)
@@ -167,22 +170,22 @@ class preProcessDocument:
       for el in self.namespaceOrder:
       for el in self.namespaceOrder:
         if el[0] == nsId:
         if el[0] == nsId:
           return el[1]
           return el[1]
-    
-    # Fallback: 
+
+    # Fallback:
     #  Some models do not have xmlns:sX attributes, but still <URI>s (usually when they only reference NS0)
     #  Some models do not have xmlns:sX attributes, but still <URI>s (usually when they only reference NS0)
     if len(self.referencedNamesSpaceUris) > 0  and len(self.referencedNamesSpaceUris) >= nsId-1:
     if len(self.referencedNamesSpaceUris) > 0  and len(self.referencedNamesSpaceUris) >= nsId-1:
       return self.referencedNamesSpaceUris[nsId-1]
       return self.referencedNamesSpaceUris[nsId-1]
-    
+
     #Nope, not found.
     #Nope, not found.
     return ""
     return ""
-  
+
   def getNamespaceDependencies(self):
   def getNamespaceDependencies(self):
     deps = []
     deps = []
     for ndid in self.referencedNodes:
     for ndid in self.referencedNodes:
       if not ndid[0].ns in deps:
       if not ndid[0].ns in deps:
         deps.append(ndid[0].ns)
         deps.append(ndid[0].ns)
     return deps
     return deps
-    
+
   def finalize(self):
   def finalize(self):
     outfile = self.targetXML[0]
     outfile = self.targetXML[0]
     outline = self.nodeset.toxml()
     outline = self.nodeset.toxml()
@@ -191,29 +194,29 @@ class preProcessDocument:
       outline = outline.replace(rq.decode('UTF-8'), "")
       outline = outline.replace(rq.decode('UTF-8'), "")
     os.write(outfile, outline.encode('UTF-8'))
     os.write(outfile, outline.encode('UTF-8'))
     os.close(outfile)
     os.close(outfile)
-    
+
   def reassignReferencedNamespaceId(self, currentNsId, newNsId):
   def reassignReferencedNamespaceId(self, currentNsId, newNsId):
     """ reassignReferencedNamespaceId
     """ reassignReferencedNamespaceId
-        
+
         Iterates over all references in this document, find references to currentNsId and changes them to newNsId.
         Iterates over all references in this document, find references to currentNsId and changes them to newNsId.
         NodeIds themselves are not altered.
         NodeIds themselves are not altered.
-        
+
         returns: nothing
         returns: nothing
-    """ 
+    """
     for refNd in self.referencedNodes:
     for refNd in self.referencedNodes:
       if refNd[0].ns == currentNsId:
       if refNd[0].ns == currentNsId:
         refNd[1].firstChild.data = refNd[1].firstChild.data.replace("ns="+str(currentNsId), "ns="+str(newNsId))
         refNd[1].firstChild.data = refNd[1].firstChild.data.replace("ns="+str(currentNsId), "ns="+str(newNsId))
         refNd[0].ns = newNsId
         refNd[0].ns = newNsId
         refNd[0].toString()
         refNd[0].toString()
-  
+
   def reassignNamespaceId(self, currentNsId, newNsId):
   def reassignNamespaceId(self, currentNsId, newNsId):
     """ reassignNamespaceId
     """ reassignNamespaceId
-        
+
         Iterates over all nodes in this document, find those in namespace currentNsId and changes them to newNsId.
         Iterates over all nodes in this document, find those in namespace currentNsId and changes them to newNsId.
-        
+
         returns: nothing
         returns: nothing
-    """ 
-    log(self, "Migrating nodes /w ns index " + str(currentNsId) + " to " + str(newNsId), LOG_LEVEL_DEBUG)
+    """
+    logger.debug("Migrating nodes /w ns index " + str(currentNsId) + " to " + str(newNsId))
     for nd in self.containedNodes:
     for nd in self.containedNodes:
       if nd[0].ns == currentNsId:
       if nd[0].ns == currentNsId:
         # In our own document, update any references to this node
         # In our own document, update any references to this node
@@ -225,33 +228,33 @@ class preProcessDocument:
         nd[1].setAttribute(u'NodeId', nd[1].getAttribute(u'NodeId').replace("ns="+str(currentNsId), "ns="+str(newNsId)))
         nd[1].setAttribute(u'NodeId', nd[1].getAttribute(u'NodeId').replace("ns="+str(currentNsId), "ns="+str(newNsId)))
         nd[0].ns = newNsId
         nd[0].ns = newNsId
         nd[0].toString()
         nd[0].toString()
-  
+
 class open62541_XMLPreprocessor:
 class open62541_XMLPreprocessor:
   preProcDocuments = []
   preProcDocuments = []
-  
+
   def __init__(self):
   def __init__(self):
       self.preProcDocuments = []
       self.preProcDocuments = []
-      
+
   def addDocument(self, documentPath):
   def addDocument(self, documentPath):
     self.preProcDocuments.append(preProcessDocument(documentPath))
     self.preProcDocuments.append(preProcessDocument(documentPath))
-    
+
   def removePreprocessedFiles(self):
   def removePreprocessedFiles(self):
     for doc in self.preProcDocuments:
     for doc in self.preProcDocuments:
       doc.clean()
       doc.clean()
-  
+
   def getPreProcessedFiles(self):
   def getPreProcessedFiles(self):
     files = []
     files = []
     for doc in self.preProcDocuments:
     for doc in self.preProcDocuments:
       if (doc.parseOK):
       if (doc.parseOK):
         files.append(doc.getTargetXMLName())
         files.append(doc.getTargetXMLName())
     return files
     return files
-  
+
   def testModelCongruencyAgainstReferences(self, doc, refs):
   def testModelCongruencyAgainstReferences(self, doc, refs):
     """ testModelCongruencyAgainstReferences
     """ testModelCongruencyAgainstReferences
-    
+
         Counts how many of the nodes referencef in refs can be found in the model
         Counts how many of the nodes referencef in refs can be found in the model
         doc.
         doc.
-        
+
         returns: double corresponding to the percentage of hits
         returns: double corresponding to the percentage of hits
     """
     """
     sspace = len(refs)
     sspace = len(refs)
@@ -265,7 +268,7 @@ class open62541_XMLPreprocessor:
           found = found + 1
           found = found + 1
           break
           break
     return float(found)/float(sspace)
     return float(found)/float(sspace)
-    
+
   def preprocess_assignUniqueNsIds(self):
   def preprocess_assignUniqueNsIds(self):
     nsdep  = []
     nsdep  = []
     docLst = []
     docLst = []
@@ -276,7 +279,7 @@ class open62541_XMLPreprocessor:
         docLst.append(doc)
         docLst.append(doc)
     for doc in docLst:
     for doc in docLst:
       self.preProcDocuments.remove(doc)
       self.preProcDocuments.remove(doc)
-    
+
     # Reassign namespace id's to be in ascending order
     # Reassign namespace id's to be in ascending order
     nsidx = 1 # next namespace id to assign on collision (first one will be "2")
     nsidx = 1 # next namespace id to assign on collision (first one will be "2")
     for doc in self.preProcDocuments:
     for doc in self.preProcDocuments:
@@ -284,14 +287,14 @@ class open62541_XMLPreprocessor:
       nsid = doc.getNamespaceId()
       nsid = doc.getNamespaceId()
       doc.reassignNamespaceId(nsid, nsidx)
       doc.reassignNamespaceId(nsid, nsidx)
       docLst.append(doc)
       docLst.append(doc)
-      log(self, "Document " + doc.originXML + " is now namespace " + str(nsidx), LOG_LEVEL_INFO)
+      logger.info("Document " + doc.originXML + " is now namespace " + str(nsidx))
     self.preProcDocuments = docLst
     self.preProcDocuments = docLst
-  
+
   def getUsedNamespaceArrayNames(self):
   def getUsedNamespaceArrayNames(self):
     """ getUsedNamespaceArrayNames
     """ getUsedNamespaceArrayNames
-    
+
         Returns the XML xmlns:s1 or <URI>[0] of each XML document (if contained/possible)
         Returns the XML xmlns:s1 or <URI>[0] of each XML document (if contained/possible)
-        
+
         returns: dict of int:nsId -> string:url
         returns: dict of int:nsId -> string:url
     """
     """
     nsName = {}
     nsName = {}
@@ -301,10 +304,10 @@ class open62541_XMLPreprocessor:
         uri = "http://modeluri.not/retrievable/from/xml"
         uri = "http://modeluri.not/retrievable/from/xml"
       nsName[doc.getNamespaceId()] = doc.getReferencedNamespaceUri(1)
       nsName[doc.getNamespaceId()] = doc.getReferencedNamespaceUri(1)
     return nsName
     return nsName
-      
-  def preprocess_linkDependantModels(self):    
+
+  def preprocess_linkDependantModels(self):
     revertToStochastic = [] # (doc, int id), where id was not resolvable using model URIs
     revertToStochastic = [] # (doc, int id), where id was not resolvable using model URIs
-    
+
     # Attemp to identify the model relations by using model URIs in xmlns:sX or <URI> contents
     # Attemp to identify the model relations by using model URIs in xmlns:sX or <URI> contents
     for doc in self.preProcDocuments:
     for doc in self.preProcDocuments:
       nsid = doc.getNamespaceId()
       nsid = doc.getNamespaceId()
@@ -313,10 +316,10 @@ class open62541_XMLPreprocessor:
         if d != nsid and d != 0:
         if d != nsid and d != 0:
           # Attempt to identify the namespace URI this d referes to...
           # Attempt to identify the namespace URI this d referes to...
           nsUri = doc.getReferencedNamespaceUri(d) # FIXME: This could actually fail and return ""!
           nsUri = doc.getReferencedNamespaceUri(d) # FIXME: This could actually fail and return ""!
-          log(self, "Need a namespace referenced as " + str(d) + ". Which hopefully is " + nsUri, LOG_LEVEL_INFO)
+          logger.info("Need a namespace referenced as " + str(d) + ". Which hopefully is " + nsUri)
           targetDoc = None
           targetDoc = None
           for tgt in self.preProcDocuments:
           for tgt in self.preProcDocuments:
-            # That model, whose URI is known but its current id is not, will 
+            # That model, whose URI is known but its current id is not, will
             #   refer have referred to itself as "1"
             #   refer have referred to itself as "1"
             if tgt.getReferencedNamespaceUri(1) == nsUri:
             if tgt.getReferencedNamespaceUri(1) == nsUri:
               targetDoc = tgt
               targetDoc = tgt
@@ -326,11 +329,11 @@ class open62541_XMLPreprocessor:
             doc.reassignReferencedNamespaceId(d, targetDoc.getNamespaceId())
             doc.reassignReferencedNamespaceId(d, targetDoc.getNamespaceId())
             continue
             continue
           else:
           else:
-            revertToStochastic.append((doc, d)) 
-            log(self, "Failed to reliably identify which XML/Model " + os.path.basename(doc.originXML) + " calls ns=" +str(d), LOG_LEVEL_WARN)
-    
+            revertToStochastic.append((doc, d))
+            logger.warn("Failed to reliably identify which XML/Model " + os.path.basename(doc.originXML) + " calls ns=" +str(d))
+
     for (doc, d) in revertToStochastic:
     for (doc, d) in revertToStochastic:
-      log(self, "Attempting to find stochastic match for target namespace ns=" + str(d) + " of " + os.path.basename(doc.originXML), LOG_LEVEL_WARN)
+      logger.warn("Attempting to find stochastic match for target namespace ns=" + str(d) + " of " + os.path.basename(doc.originXML))
       # Copy all references to the given namespace
       # Copy all references to the given namespace
       refs = []
       refs = []
       matches = [] # list of (match%, targetDoc) to pick from later
       matches = [] # list of (match%, targetDoc) to pick from later
@@ -354,37 +357,34 @@ class open62541_XMLPreprocessor:
         if m[0] > best[0]:
         if m[0] > best[0]:
           best = m
           best = m
       if best[1] != None:
       if best[1] != None:
-        log(self, "Best match (" + str(best[1]*100) + "%) for what " + os.path.basename(doc.originXML) + " refers to as ns="+str(d)+" was " + os.path.basename(best[1].originXML), LOG_LEVEL_WARN)
+        logger.warn("Best match (" + str(best[1]*100) + "%) for what " + os.path.basename(doc.originXML) + " refers to as ns="+str(d)+" was " + os.path.basename(best[1].originXML))
         doc.reassignReferencedNamespaceId(d, best[1].getNamespaceId())
         doc.reassignReferencedNamespaceId(d, best[1].getNamespaceId())
-      else: 
-        log(self, "Failed to find a match for what " +  os.path.basename(doc.originXML) + " refers to as ns=" + str(d) ,LOG_LEVEL_ERROR )
-      
+      else:
+        logger.error("Failed to find a match for what " +  os.path.basename(doc.originXML) + " refers to as ns=" + str(d))
+
   def preprocessAll(self):
   def preprocessAll(self):
     ##
     ##
     ## First: Gather statistics about the namespaces:
     ## First: Gather statistics about the namespaces:
     for doc in self.preProcDocuments:
     for doc in self.preProcDocuments:
       doc.analyze()
       doc.analyze()
-    
+
     # Preprocess step: Remove XML specific Naming scheme ("uax:")
     # Preprocess step: Remove XML specific Naming scheme ("uax:")
     # FIXME: Not implemented
     # FIXME: Not implemented
-    
+
     ##
     ##
     ## Preprocess step: Check namespace ID multiplicity and reassign IDs if necessary
     ## Preprocess step: Check namespace ID multiplicity and reassign IDs if necessary
     ##
     ##
     self.preprocess_assignUniqueNsIds()
     self.preprocess_assignUniqueNsIds()
     self.preprocess_linkDependantModels()
     self.preprocess_linkDependantModels()
-    
-    
-    ##  
+
+
+    ##
     ## Prep step: prevent any XML from using namespace 1 (reserved for instances)
     ## Prep step: prevent any XML from using namespace 1 (reserved for instances)
     ## FIXME: Not implemented
     ## FIXME: Not implemented
-    
+
     ##
     ##
     ## Final: Write modified XML tmp files
     ## Final: Write modified XML tmp files
     for doc in self.preProcDocuments:
     for doc in self.preProcDocuments:
       doc.finalize()
       doc.finalize()
-    
-    return True
-      
-  
 
 
+    return True

+ 140 - 138
tools/pyUANamespace/ua_builtin_types.py

@@ -19,10 +19,12 @@
 import sys
 import sys
 import xml.dom.minidom as dom
 import xml.dom.minidom as dom
 from ua_constants import *
 from ua_constants import *
-from logger import *
+import logging
 from time import strftime, strptime
 from time import strftime, strptime
 from open62541_MacroHelper import open62541_MacroHelper
 from open62541_MacroHelper import open62541_MacroHelper
 
 
+logger = logging.getLogger(__name__)
+
 def getNextElementNode(xmlvalue):
 def getNextElementNode(xmlvalue):
   if xmlvalue == None:
   if xmlvalue == None:
     return None
     return None
@@ -60,7 +62,7 @@ class opcua_value_t():
                        'qualifiedname', 'expandednodeid', 'xmlelement']
                        'qualifiedname', 'expandednodeid', 'xmlelement']
     self.dataType = None
     self.dataType = None
     self.encodingRule = []
     self.encodingRule = []
-  
+
   def getValueFieldByAlias(self, fieldname):
   def getValueFieldByAlias(self, fieldname):
     if not isinstance(self.value, list):
     if not isinstance(self.value, list):
       return None
       return None
@@ -70,7 +72,7 @@ class opcua_value_t():
       if val.alias() == fieldname:
       if val.alias() == fieldname:
 	return val.value
 	return val.value
     return None
     return None
-    
+
   def setEncodingRule(self, encoding):
   def setEncodingRule(self, encoding):
     self.encodingRule = encoding
     self.encodingRule = encoding
 
 
@@ -161,19 +163,19 @@ class opcua_value_t():
       t = opcua_BuiltinType_xmlelement_t(self.parent)
       t = opcua_BuiltinType_xmlelement_t(self.parent)
       t.setEncodingRule(encodingRule)
       t.setEncodingRule(encodingRule)
     else:
     else:
-      log(self, "No class representing stringName " + stringName + " was found. Cannot create builtinType.")
+      logger.debug("No class representing stringName " + stringName + " was found. Cannot create builtinType.")
       return None
       return None
     return t
     return t
 
 
   def parseXML(self, xmlvalue):
   def parseXML(self, xmlvalue):
-    log(self, "parsing xmlvalue for " + self.parent.browseName() + " (" + str(self.parent.id()) + ") according to " + str(self.parent.dataType().target().getEncoding()))
+    logger.debug("parsing xmlvalue for " + self.parent.browseName() + " (" + str(self.parent.id()) + ") according to " + str(self.parent.dataType().target().getEncoding()))
 
 
     if not "value" in xmlvalue.tagName.lower():
     if not "value" in xmlvalue.tagName.lower():
-      log(self, "Expected <Value> , but found " + xmlvalue.tagName + " instead. Value will not be parsed.", LOG_LEVEL_ERROR)
+      logger.error("Expected <Value> , but found " + xmlvalue.tagName + " instead. Value will not be parsed.")
       return
       return
 
 
     if len(xmlvalue.childNodes) == 0:
     if len(xmlvalue.childNodes) == 0:
-      log(self, "Expected childnodes for value, but none where found... Value will not be parsed.", LOG_LEVEL_ERROR)
+      logger.error("Expected childnodes for value, but none where found... Value will not be parsed.")
       return
       return
 
 
     for n in xmlvalue.childNodes:
     for n in xmlvalue.childNodes:
@@ -190,7 +192,7 @@ class opcua_value_t():
     else:
     else:
       self.value = [self.__parseXMLSingleValue(xmlvalue)]
       self.value = [self.__parseXMLSingleValue(xmlvalue)]
 
 
-    log(self, "Parsed Value: " + str(self.value))
+    logger.debug( "Parsed Value: " + str(self.value))
 
 
   def __parseXMLSingleValue(self, xmlvalue, alias=None, encodingPart=None):
   def __parseXMLSingleValue(self, xmlvalue, alias=None, encodingPart=None):
     # Parse an encoding list such as enc = [[Int32], ['Duration', ['DateTime']]],
     # Parse an encoding list such as enc = [[Int32], ['Duration', ['DateTime']]],
@@ -216,7 +218,7 @@ class opcua_value_t():
         # 0: 'BuiltinType'
         # 0: 'BuiltinType'
         if alias != None:
         if alias != None:
           if not xmlvalue.tagName == alias:
           if not xmlvalue.tagName == alias:
-            log(self, "Expected XML element with tag " + alias + " but found " + xmlvalue.tagName + " instead", LOG_LEVEL_ERROR)
+            logger.error("Expected XML element with tag " + alias + " but found " + xmlvalue.tagName + " instead")
             return None
             return None
           else:
           else:
             t = self.getTypeByString(enc[0], enc)
             t = self.getTypeByString(enc[0], enc)
@@ -225,7 +227,7 @@ class opcua_value_t():
             return t
             return t
         else:
         else:
           if not self.isBuiltinByString(xmlvalue.tagName):
           if not self.isBuiltinByString(xmlvalue.tagName):
-            log(self, "Expected XML describing builtin type " + enc[0] + " but found " + xmlvalue.tagName + " instead", LOG_LEVEL_ERROR)
+            logger.error("Expected XML describing builtin type " + enc[0] + " but found " + xmlvalue.tagName + " instead")
           else:
           else:
             t = self.getTypeByString(enc[0], enc)
             t = self.getTypeByString(enc[0], enc)
             t.parseXML(xmlvalue)
             t.parseXML(xmlvalue)
@@ -253,29 +255,29 @@ class opcua_value_t():
       #        Consider moving this ExtensionObject specific parsing into the
       #        Consider moving this ExtensionObject specific parsing into the
       #        builtin type and only determining the multipart type at this stage.
       #        builtin type and only determining the multipart type at this stage.
       if not xmlvalue.tagName == "ExtensionObject":
       if not xmlvalue.tagName == "ExtensionObject":
-        log(self, "Expected XML tag <ExtensionObject> for multipart type, but found " + xmlvalue.tagName + " instead.", LOG_LEVEL_ERROR)
+        logger.error("Expected XML tag <ExtensionObject> for multipart type, but found " + xmlvalue.tagName + " instead.")
         return None
         return None
 
 
       extobj = opcua_BuiltinType_extensionObject_t(self.parent)
       extobj = opcua_BuiltinType_extensionObject_t(self.parent)
       extobj.setEncodingRule(enc)
       extobj.setEncodingRule(enc)
       etype = xmlvalue.getElementsByTagName("TypeId")
       etype = xmlvalue.getElementsByTagName("TypeId")
       if len(etype) == 0:
       if len(etype) == 0:
-        log(self, "Did not find <TypeId> for ExtensionObject", LOG_LEVEL_ERROR)
+        logger.error("Did not find <TypeId> for ExtensionObject")
         return None
         return None
       etype = etype[0].getElementsByTagName("Identifier")
       etype = etype[0].getElementsByTagName("Identifier")
       if len(etype) == 0:
       if len(etype) == 0:
-        log(self, "Did not find <Identifier> for ExtensionObject", LOG_LEVEL_ERROR)
+        logger.error("Did not find <Identifier> for ExtensionObject")
         return None
         return None
       etype = self.parent.getNamespace().getNodeByIDString(etype[0].firstChild.data)
       etype = self.parent.getNamespace().getNodeByIDString(etype[0].firstChild.data)
       if etype == None:
       if etype == None:
-        log(self, "Identifier Node not found in namespace" , LOG_LEVEL_ERROR)
+        logger.error("Identifier Node not found in namespace" )
         return None
         return None
 
 
       extobj.typeId(etype)
       extobj.typeId(etype)
 
 
       ebody = xmlvalue.getElementsByTagName("Body")
       ebody = xmlvalue.getElementsByTagName("Body")
       if len(ebody) == 0:
       if len(ebody) == 0:
-        log(self, "Did not find <Body> for ExtensionObject", LOG_LEVEL_ERROR)
+        logger.error("Did not find <Body> for ExtensionObject")
         return None
         return None
       ebody = ebody[0]
       ebody = ebody[0]
 
 
@@ -284,11 +286,11 @@ class opcua_value_t():
       if not ebodypart.nodeType == ebodypart.ELEMENT_NODE:
       if not ebodypart.nodeType == ebodypart.ELEMENT_NODE:
         ebodypart = getNextElementNode(ebodypart)
         ebodypart = getNextElementNode(ebodypart)
       if ebodypart == None:
       if ebodypart == None:
-        log(self, "Expected ExtensionObject to hold a variable of type " + str(self.parent.dataType().target().browseName()) + " but found nothing.", LOG_LEVEL_ERROR)
+        logger.error("Expected ExtensionObject to hold a variable of type " + str(self.parent.dataType().target().browseName()) + " but found nothing.")
         return None
         return None
 
 
       if not ebodypart.tagName == self.parent.dataType().target().browseName():
       if not ebodypart.tagName == self.parent.dataType().target().browseName():
-        log(self, "Expected ExtensionObject to hold a variable of type " + str(self.parent.dataType().target().browseName()) + " but found " + str(ebodypart.tagName) + " instead.", LOG_LEVEL_ERROR)
+        logger.error("Expected ExtensionObject to hold a variable of type " + str(self.parent.dataType().target().browseName()) + " but found " + str(ebodypart.tagName) + " instead.")
         return None
         return None
       extobj.alias(ebodypart.tagName)
       extobj.alias(ebodypart.tagName)
 
 
@@ -296,7 +298,7 @@ class opcua_value_t():
       if not ebodypart.nodeType == ebodypart.ELEMENT_NODE:
       if not ebodypart.nodeType == ebodypart.ELEMENT_NODE:
         ebodypart = getNextElementNode(ebodypart)
         ebodypart = getNextElementNode(ebodypart)
       if ebodypart == None:
       if ebodypart == None:
-        log(self, "Description of dataType " + str(self.parent.dataType().target().browseName()) + " in ExtensionObject is empty/invalid.", LOG_LEVEL_ERROR)
+        logger.error("Description of dataType " + str(self.parent.dataType().target().browseName()) + " in ExtensionObject is empty/invalid.")
         return None
         return None
 
 
       extobj.value = []
       extobj.value = []
@@ -304,7 +306,7 @@ class opcua_value_t():
         if not ebodypart == None:
         if not ebodypart == None:
           extobj.value.append(extobj.__parseXMLSingleValue(ebodypart, alias=None, encodingPart=e))
           extobj.value.append(extobj.__parseXMLSingleValue(ebodypart, alias=None, encodingPart=e))
         else:
         else:
-          log(self, "Expected encoding " + str(e) + " but found none in body.", LOG_LEVEL_ERROR)
+          logger.error("Expected encoding " + str(e) + " but found none in body.")
         ebodypart = getNextElementNode(ebodypart)
         ebodypart = getNextElementNode(ebodypart)
       return extobj
       return extobj
 
 
@@ -348,27 +350,27 @@ class opcua_value_t():
       return code
       return code
     if not isinstance(self.value[0], opcua_value_t):
     if not isinstance(self.value[0], opcua_value_t):
       return code
       return code
-  
+
     if self.parent.valueRank() != -1 and (self.parent.valueRank() >=0 or (len(self.value) > 1 and (self.parent.valueRank() != -2 or self.parent.valueRank() != -3))):
     if self.parent.valueRank() != -1 and (self.parent.valueRank() >=0 or (len(self.value) > 1 and (self.parent.valueRank() != -2 or self.parent.valueRank() != -3))):
       # User the following strategy for all directly mappable values a la 'UA_Type MyInt = (UA_Type) 23;'
       # User the following strategy for all directly mappable values a la 'UA_Type MyInt = (UA_Type) 23;'
       if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_GUID:
       if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_GUID:
-        log(self, "Don't know how to print array of GUID in node " + str(self.parent.id()), LOG_LEVEL_WARN)
+        logger.warn("Don't know how to print array of GUID in node " + str(self.parent.id()))
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DATETIME:
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DATETIME:
-        log(self, "Don't know how to print array of DateTime in node " + str(self.parent.id()), LOG_LEVEL_WARN)
+        logger.warn("Don't know how to print array of DateTime in node " + str(self.parent.id()))
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DIAGNOSTICINFO:
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DIAGNOSTICINFO:
-        log(self, "Don't know how to print array of DiagnosticInfo in node " + str(self.parent.id()), LOG_LEVEL_WARN)
+        logger.warn("Don't know how to print array of DiagnosticInfo in node " + str(self.parent.id()))
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_STATUSCODE:
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_STATUSCODE:
-        log(self, "Don't know how to print array of StatusCode in node " + str(self.parent.id()), LOG_LEVEL_WARN)
+        logger.warn("Don't know how to print array of StatusCode in node " + str(self.parent.id()))
       else:
       else:
         if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_EXTENSIONOBJECT:
         if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_EXTENSIONOBJECT:
           for v in self.value:
           for v in self.value:
-            log(self, "Building extObj array index " + str(self.value.index(v)))
+            logger.debug("Building extObj array index " + str(self.value.index(v)))
             code = code + v.printOpen62541CCode_SubType_build(arrayIndex=self.value.index(v))
             code = code + v.printOpen62541CCode_SubType_build(arrayIndex=self.value.index(v))
         #code.append("attr.value.type = &UA_TYPES[UA_TYPES_" + self.value[0].stringRepresentation.upper() + "];")
         #code.append("attr.value.type = &UA_TYPES[UA_TYPES_" + self.value[0].stringRepresentation.upper() + "];")
         code.append("UA_" + self.value[0].stringRepresentation + " " + valueName + "[" + str(len(self.value)) + "];")
         code.append("UA_" + self.value[0].stringRepresentation + " " + valueName + "[" + str(len(self.value)) + "];")
         if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_EXTENSIONOBJECT:
         if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_EXTENSIONOBJECT:
           for v in self.value:
           for v in self.value:
-            log(self, "Printing extObj array index " + str(self.value.index(v)))
+            logger.debug("Printing extObj array index " + str(self.value.index(v)))
             code.append(valueName + "[" + str(self.value.index(v)) + "] = " + v.printOpen62541CCode_SubType(asIndirect=False) + ";")
             code.append(valueName + "[" + str(self.value.index(v)) + "] = " + v.printOpen62541CCode_SubType(asIndirect=False) + ";")
             code.append("UA_free(" + v.printOpen62541CCode_SubType() + ");")
             code.append("UA_free(" + v.printOpen62541CCode_SubType() + ");")
         else:
         else:
@@ -379,13 +381,13 @@ class opcua_value_t():
     else:
     else:
       # User the following strategy for all directly mappable values a la 'UA_Type MyInt = (UA_Type) 23;'
       # User the following strategy for all directly mappable values a la 'UA_Type MyInt = (UA_Type) 23;'
       if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_GUID:
       if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_GUID:
-        log(self, "Don't know how to print scalar GUID in node " + str(self.parent.id()), LOG_LEVEL_WARN)
+        logger.warn("Don't know how to print scalar GUID in node " + str(self.parent.id()))
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DATETIME:
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DATETIME:
-        log(self, "Don't know how to print scalar DateTime in node " + str(self.parent.id()), LOG_LEVEL_WARN)
+        logger.warn("Don't know how to print scalar DateTime in node " + str(self.parent.id()))
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DIAGNOSTICINFO:
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DIAGNOSTICINFO:
-        log(self, "Don't know how to print scalar DiagnosticInfo in node " + str(self.parent.id()), LOG_LEVEL_WARN)
+        logger.warn("Don't know how to print scalar DiagnosticInfo in node " + str(self.parent.id()))
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_STATUSCODE:
       elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_STATUSCODE:
-        log(self, "Don't know how to print scalar StatusCode in node " + str(self.parent.id()), LOG_LEVEL_WARN)
+        logger.warn("Don't know how to print scalar StatusCode in node " + str(self.parent.id()))
       else:
       else:
         # The following strategy applies to all other types, in particular strings and numerics.
         # The following strategy applies to all other types, in particular strings and numerics.
         if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_EXTENSIONOBJECT:
         if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_EXTENSIONOBJECT:
@@ -433,16 +435,16 @@ class opcua_BuiltinType_extensionObject_t(opcua_value_t):
     code = [""]
     code = [""]
     codegen = open62541_MacroHelper();
     codegen = open62541_MacroHelper();
 
 
-    log(self, "Building extensionObject for " + str(self.parent.id()))
-    log(self, "Value    " + str(self.value))
-    log(self, "Encoding " + str(self.getEncodingRule()))
+    logger.debug("Building extensionObject for " + str(self.parent.id()))
+    logger.debug("Value    " + str(self.value))
+    logger.debug("Encoding " + str(self.getEncodingRule()))
 
 
     self.setCodeInstanceName(recursionDepth, arrayIndex)
     self.setCodeInstanceName(recursionDepth, arrayIndex)
     # If there are any ExtensionObjects instide this ExtensionObject, we need to
     # If there are any ExtensionObjects instide this ExtensionObject, we need to
     # generate one-time-structs for them too before we can proceed;
     # generate one-time-structs for them too before we can proceed;
     for subv in self.value:
     for subv in self.value:
       if isinstance(subv, list):
       if isinstance(subv, list):
-        log(self, "ExtensionObject contains an ExtensionObject, which is currently not encodable!", LOG_LEVEL_ERR)
+        logger.debug("ExtensionObject contains an ExtensionObject, which is currently not encodable!", LOG_LEVEL_ERR)
 
 
     code.append("struct {")
     code.append("struct {")
     for field in self.getEncodingRule():
     for field in self.getEncodingRule():
@@ -463,7 +465,7 @@ class opcua_BuiltinType_extensionObject_t(opcua_value_t):
     for subv in self.value:
     for subv in self.value:
       encField = self.getEncodingRule()[encFieldIdx]
       encField = self.getEncodingRule()[encFieldIdx]
       encFieldIdx = encFieldIdx + 1;
       encFieldIdx = encFieldIdx + 1;
-      log(self, "Encoding of field " + subv.alias() + " is " + str(subv.getEncodingRule()) + "defined by " + str(encField))
+      logger.debug("Encoding of field " + subv.alias() + " is " + str(subv.getEncodingRule()) + "defined by " + str(encField))
       # Check if this is an array
       # Check if this is an array
       if encField[2] == 0:
       if encField[2] == 0:
         code.append(self.getCodeInstanceName()+"_struct."+subv.alias() + " = " + subv.printOpen62541CCode_SubType(asIndirect=False) + ";")
         code.append(self.getCodeInstanceName()+"_struct."+subv.alias() + " = " + subv.printOpen62541CCode_SubType(asIndirect=False) + ";")
@@ -472,10 +474,10 @@ class opcua_BuiltinType_extensionObject_t(opcua_value_t):
           # this is an array
           # this is an array
           code.append(self.getCodeInstanceName()+"_struct."+subv.alias() + "Size = " + str(len(subv)) + ";")
           code.append(self.getCodeInstanceName()+"_struct."+subv.alias() + "Size = " + str(len(subv)) + ";")
           code.append(self.getCodeInstanceName()+"_struct."+subv.alias()+" = (UA_" + subv.stringRepresentation + " *) UA_malloc(sizeof(UA_" + subv.stringRepresentation + ")*"+ str(len(subv))+");")
           code.append(self.getCodeInstanceName()+"_struct."+subv.alias()+" = (UA_" + subv.stringRepresentation + " *) UA_malloc(sizeof(UA_" + subv.stringRepresentation + ")*"+ str(len(subv))+");")
-          log(self, "Encoding included array of " + str(len(subv)) + " values.")
+          logger.debug("Encoding included array of " + str(len(subv)) + " values.")
           for subvidx in range(0,len(subv)):
           for subvidx in range(0,len(subv)):
             subvv = subv[subvidx]
             subvv = subv[subvidx]
-            log(self, "  " + str(subvix) + " " + str(subvv))
+            logger.debug("  " + str(subvix) + " " + str(subvv))
             code.append(self.getCodeInstanceName()+"_struct."+subv.alias() + "[" + str(subvidx) + "] = " + subvv.printOpen62541CCode_SubType(asIndirect=True) + ";")
             code.append(self.getCodeInstanceName()+"_struct."+subv.alias() + "[" + str(subvidx) + "] = " + subvv.printOpen62541CCode_SubType(asIndirect=True) + ";")
           code.append("}")
           code.append("}")
         else:
         else:
@@ -537,32 +539,32 @@ class opcua_BuiltinType_localizedtext_t(opcua_value_t):
     #        <LocalizedText> or </AliasName>
     #        <LocalizedText> or </AliasName>
     #
     #
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
       if self.alias() != None:
       if self.alias() != None:
-        log(self, "Neither locale nor text in XML description field " + self.alias() + ". Setting to default ['en_US','']")
+        logger.debug("Neither locale nor text in XML description field " + self.alias() + ". Setting to default ['en_US','']")
       else:
       else:
-        log(self, "Neither locale nor text in XML description. Setting to default ['en_US','']")
+        logger.debug("Neither locale nor text in XML description. Setting to default ['en_US','']")
       self.value = ['en_US','']
       self.value = ['en_US','']
       return
       return
 
 
     self.value = []
     self.value = []
     tmp = xmlvalue.getElementsByTagName("Locale")
     tmp = xmlvalue.getElementsByTagName("Locale")
     if len(tmp) == 0:
     if len(tmp) == 0:
-      log(self, "Did not find a locale. Setting to en_US per default.", LOG_LEVEL_WARN)
+      logger.warn("Did not find a locale. Setting to en_US per default.")
       self.value.append('en_US')
       self.value.append('en_US')
     else:
     else:
       if tmp[0].firstChild == None:
       if tmp[0].firstChild == None:
-        log(self, "Locale tag without contents. Setting to en_US per default.", LOG_LEVEL_WARN)
+        logger.warn("Locale tag without contents. Setting to en_US per default.")
         self.value.append('en_US')
         self.value.append('en_US')
       else:
       else:
         self.value.append(tmp[0].firstChild.data)
         self.value.append(tmp[0].firstChild.data)
@@ -574,11 +576,11 @@ class opcua_BuiltinType_localizedtext_t(opcua_value_t):
 
 
     tmp = xmlvalue.getElementsByTagName("Text")
     tmp = xmlvalue.getElementsByTagName("Text")
     if len(tmp) == 0:
     if len(tmp) == 0:
-      log(self, "Did not find a Text. Setting to empty string per default.", LOG_LEVEL_WARN)
+      logger.warn("Did not find a Text. Setting to empty string per default.")
       self.value.append('')
       self.value.append('')
     else:
     else:
       if tmp[0].firstChild == None:
       if tmp[0].firstChild == None:
-        log(self, "Text tag without content. Setting to empty string per default.", LOG_LEVEL_WARN)
+        logger.warn("Text tag without content. Setting to empty string per default.")
         self.value.append('')
         self.value.append('')
       else:
       else:
         self.value.append(tmp[0].firstChild.data)
         self.value.append(tmp[0].firstChild.data)
@@ -599,10 +601,10 @@ class opcua_BuiltinType_expandednodeid_t(opcua_value_t):
 
 
   def parseXML(self, xmlvalue):
   def parseXML(self, xmlvalue):
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
-    log(self, "Not implemented", LOG_LEVEL_ERR)
+    logger.debug("Not implemented", LOG_LEVEL_ERR)
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     #FIXME! This one is definetely broken!
     #FIXME! This one is definetely broken!
@@ -623,19 +625,19 @@ class opcua_BuiltinType_nodeid_t(opcua_value_t):
     #           </Identifier>
     #           </Identifier>
     #        </NodeId> or </Alias>
     #        </NodeId> or </Alias>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <NodeId />
     # Catch XML <NodeId />
     if xmlvalue.firstChild == None :
     if xmlvalue.firstChild == None :
-      log(self, "No value is given, which is illegal for Node Types...", LOG_LEVEL_ERROR)
+      logger.error("No value is given, which is illegal for Node Types...")
       self.value = None
       self.value = None
     else:
     else:
       # Check if there is an <Identifier> tag
       # Check if there is an <Identifier> tag
@@ -643,7 +645,7 @@ class opcua_BuiltinType_nodeid_t(opcua_value_t):
         xmlvalue = xmlvalue.getElementsByTagName("Identifier")[0]
         xmlvalue = xmlvalue.getElementsByTagName("Identifier")[0]
       self.value = self.parent.getNamespace().getNodeByIDString(unicode(xmlvalue.firstChild.data))
       self.value = self.parent.getNamespace().getNodeByIDString(unicode(xmlvalue.firstChild.data))
       if self.value == None:
       if self.value == None:
-        log(self, "Node with id " + str(unicode(xmlvalue.firstChild.data)) + " was not found in namespace.", LOG_LEVEL_ERROR)
+        logger.error("Node with id " + str(unicode(xmlvalue.firstChild.data)) + " was not found in namespace.")
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     if self.value == None:
     if self.value == None:
@@ -654,10 +656,10 @@ class opcua_BuiltinType_nodeid_t(opcua_value_t):
     elif nodeId.s != None:
     elif nodeId.s != None:
       return "UA_NODEID_STRING("  + str(nodeId.ns) + ", " + str(nodeId.s) + ")"
       return "UA_NODEID_STRING("  + str(nodeId.ns) + ", " + str(nodeId.s) + ")"
     elif nodeId.b != None:
     elif nodeId.b != None:
-      log(self, "NodeID Generation macro for bytestrings has not been implemented.")
+      logger.debug("NodeID Generation macro for bytestrings has not been implemented.")
       return "UA_NODEID_NUMERIC(0,0)"
       return "UA_NODEID_NUMERIC(0,0)"
     elif nodeId.g != None:
     elif nodeId.g != None:
-      log(self, "NodeID Generation macro for guids has not been implemented.")
+      logger.debug("NodeID Generation macro for guids has not been implemented.")
       return "UA_NODEID_NUMERIC(0,0)"
       return "UA_NODEID_NUMERIC(0,0)"
     return "UA_NODEID_NUMERIC(0,0)"
     return "UA_NODEID_NUMERIC(0,0)"
 
 
@@ -673,19 +675,19 @@ class opcua_BuiltinType_datetime_t(opcua_value_t):
     #        2013-08-13T21:00:05.0000L
     #        2013-08-13T21:00:05.0000L
     #        </DateTime> or </AliasName>
     #        </DateTime> or </AliasName>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <DateTime /> by setting the value to a default
     # Catch XML <DateTime /> by setting the value to a default
     if xmlvalue.firstChild == None :
     if xmlvalue.firstChild == None :
-      log(self, "No value is given. Setting to default now()")
+      logger.debug("No value is given. Setting to default now()")
       self.value = strptime(strftime("%Y-%m-%dT%H:%M%S"), "%Y-%m-%dT%H:%M%S")
       self.value = strptime(strftime("%Y-%m-%dT%H:%M%S"), "%Y-%m-%dT%H:%M%S")
     else:
     else:
       timestr = unicode(xmlvalue.firstChild.data)
       timestr = unicode(xmlvalue.firstChild.data)
@@ -699,7 +701,7 @@ class opcua_BuiltinType_datetime_t(opcua_value_t):
       try:
       try:
         self.value = strptime(timestr, "%Y-%m-%dT%H:%M:%S")
         self.value = strptime(timestr, "%Y-%m-%dT%H:%M:%S")
       except:
       except:
-        log(self, "Timestring format is illegible. Expected 2001-01-30T21:22:23, but got " + timestr + " instead. Time will be defaultet to now()", LOG_LEVEL_ERROR)
+        logger.error("Timestring format is illegible. Expected 2001-01-30T21:22:23, but got " + timestr + " instead. Time will be defaultet to now()")
         self.value = strptime(strftime("%Y-%m-%dT%H:%M%S"), "%Y-%m-%dT%H:%M%S")
         self.value = strptime(strftime("%Y-%m-%dT%H:%M%S"), "%Y-%m-%dT%H:%M%S")
 
 
 class opcua_BuiltinType_qualifiedname_t(opcua_value_t):
 class opcua_BuiltinType_qualifiedname_t(opcua_value_t):
@@ -715,19 +717,19 @@ class opcua_BuiltinType_qualifiedname_t(opcua_value_t):
     #           <Name>SomeString<Name>                # Speculation: Manditory if NamespaceIndex is given, omitted otherwise?
     #           <Name>SomeString<Name>                # Speculation: Manditory if NamespaceIndex is given, omitted otherwise?
     #        </QualifiedName> or </AliasName>
     #        </QualifiedName> or </AliasName>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <Qalified /> by setting the value to a default
     # Catch XML <Qalified /> by setting the value to a default
     if xmlvalue.firstChild == None :
     if xmlvalue.firstChild == None :
-      log(self, "No value is given. Setting to default empty string in ns=0: [0, '']")
+      logger.debug("No value is given. Setting to default empty string in ns=0: [0, '']")
       self.value = [0, '']
       self.value = [0, '']
     else:
     else:
       # Is a namespace index passed?
       # Is a namespace index passed?
@@ -737,10 +739,10 @@ class opcua_BuiltinType_qualifiedname_t(opcua_value_t):
         if len(xmlvalue.getElementsByTagName("Name")) != 0:
         if len(xmlvalue.getElementsByTagName("Name")) != 0:
           self.value.append(xmlvalue.getElementsByTagName("Name")[0].firstChild.data)
           self.value.append(xmlvalue.getElementsByTagName("Name")[0].firstChild.data)
         else:
         else:
-          log(self, "No name is specified, will default to empty string")
+          logger.debug("No name is specified, will default to empty string")
           self.value.append('')
           self.value.append('')
       else:
       else:
-        log(self, "No namespace is specified, will default to 0")
+        logger.debug("No namespace is specified, will default to 0")
         self.value = [0]
         self.value = [0]
         self.value.append(unicode(xmlvalue.firstChild.data))
         self.value.append(unicode(xmlvalue.firstChild.data))
 
 
@@ -757,9 +759,9 @@ class opcua_BuiltinType_statuscode_t(opcua_value_t):
 
 
   def parseXML(self, xmlvalue):
   def parseXML(self, xmlvalue):
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
-    log(self, "Not implemented", LOG_LEVEL_WARN)
+    logger.warn("Not implemented")
 
 
 class opcua_BuiltinType_diagnosticinfo_t(opcua_value_t):
 class opcua_BuiltinType_diagnosticinfo_t(opcua_value_t):
   def setStringReprentation(self):
   def setStringReprentation(self):
@@ -770,9 +772,9 @@ class opcua_BuiltinType_diagnosticinfo_t(opcua_value_t):
 
 
   def parseXML(self, xmlvalue):
   def parseXML(self, xmlvalue):
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
-    log(self, "Not implemented", LOG_LEVEL_WARN)
+    logger.warn("Not implemented")
 
 
 class opcua_BuiltinType_guid_t(opcua_value_t):
 class opcua_BuiltinType_guid_t(opcua_value_t):
   def setStringReprentation(self):
   def setStringReprentation(self):
@@ -783,19 +785,19 @@ class opcua_BuiltinType_guid_t(opcua_value_t):
 
 
   def parseXML(self, xmlvalue):
   def parseXML(self, xmlvalue):
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <Guid /> by setting the value to a default
     # Catch XML <Guid /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = [0,0,0,0]
       self.value = [0,0,0,0]
     else:
     else:
       self.value = unicode(xmlvalue.firstChild.data)
       self.value = unicode(xmlvalue.firstChild.data)
@@ -808,11 +810,11 @@ class opcua_BuiltinType_guid_t(opcua_value_t):
         try:
         try:
           tmp.append(int("0x"+g, 16))
           tmp.append(int("0x"+g, 16))
         except:
         except:
-          log(self, "Invalid formatting of Guid. Expected {01234567-89AB-CDEF-ABCD-0123456789AB}, got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+          logger.error("Invalid formatting of Guid. Expected {01234567-89AB-CDEF-ABCD-0123456789AB}, got " + unicode(xmlvalue.firstChild.data))
           self.value = [0,0,0,0,0]
           self.value = [0,0,0,0,0]
           ok = False
           ok = False
       if len(tmp) != 5:
       if len(tmp) != 5:
-        log(self, "Invalid formatting of Guid. Expected {01234567-89AB-CDEF-ABCD-0123456789AB}, got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Invalid formatting of Guid. Expected {01234567-89AB-CDEF-ABCD-0123456789AB}, got " + unicode(xmlvalue.firstChild.data))
         self.value = [0,0,0,0]
         self.value = [0,0,0,0]
         ok = False
         ok = False
       self.value = tmp
       self.value = tmp
@@ -828,19 +830,19 @@ class opcua_BuiltinType_boolean_t(opcua_value_t):
     # Expect <Boolean>value</Boolean> or
     # Expect <Boolean>value</Boolean> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <Boolean /> by setting the value to a default
     # Catch XML <Boolean /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = "false"
       self.value = "false"
     else:
     else:
       if "false" in unicode(xmlvalue.firstChild.data).lower():
       if "false" in unicode(xmlvalue.firstChild.data).lower():
@@ -862,25 +864,25 @@ class opcua_BuiltinType_byte_t(opcua_value_t):
     # Expect <Byte>value</Byte> or
     # Expect <Byte>value</Byte> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <Byte /> by setting the value to a default
     # Catch XML <Byte /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = 0
       self.value = 0
     else:
     else:
       try:
       try:
         self.value = int(unicode(xmlvalue.firstChild.data))
         self.value = int(unicode(xmlvalue.firstChild.data))
       except:
       except:
-        log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data))
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
@@ -896,25 +898,25 @@ class opcua_BuiltinType_sbyte_t(opcua_value_t):
     # Expect <SByte>value</SByte> or
     # Expect <SByte>value</SByte> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <SByte /> by setting the value to a default
     # Catch XML <SByte /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = 0
       self.value = 0
     else:
     else:
       try:
       try:
         self.value = int(unicode(xmlvalue.firstChild.data))
         self.value = int(unicode(xmlvalue.firstChild.data))
       except:
       except:
-        log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data))
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
@@ -930,25 +932,25 @@ class opcua_BuiltinType_int16_t(opcua_value_t):
     # Expect <Int16>value</Int16> or
     # Expect <Int16>value</Int16> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <Int16 /> by setting the value to a default
     # Catch XML <Int16 /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = 0
       self.value = 0
     else:
     else:
       try:
       try:
         self.value = int(unicode(xmlvalue.firstChild.data))
         self.value = int(unicode(xmlvalue.firstChild.data))
       except:
       except:
-        log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data))
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
@@ -964,25 +966,25 @@ class opcua_BuiltinType_uint16_t(opcua_value_t):
     # Expect <UInt16>value</UInt16> or
     # Expect <UInt16>value</UInt16> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <UInt16 /> by setting the value to a default
     # Catch XML <UInt16 /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = 0
       self.value = 0
     else:
     else:
       try:
       try:
         self.value = int(unicode(xmlvalue.firstChild.data))
         self.value = int(unicode(xmlvalue.firstChild.data))
       except:
       except:
-        log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data))
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
@@ -998,25 +1000,25 @@ class opcua_BuiltinType_int32_t(opcua_value_t):
     # Expect <Int32>value</Int32> or
     # Expect <Int32>value</Int32> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <Int32 /> by setting the value to a default
     # Catch XML <Int32 /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = 0
       self.value = 0
     else:
     else:
       try:
       try:
         self.value = int(unicode(xmlvalue.firstChild.data))
         self.value = int(unicode(xmlvalue.firstChild.data))
       except:
       except:
-        log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data))
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
@@ -1032,25 +1034,25 @@ class opcua_BuiltinType_uint32_t(opcua_value_t):
     # Expect <UInt32>value</UInt32> or
     # Expect <UInt32>value</UInt32> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <UInt32 /> by setting the value to a default
     # Catch XML <UInt32 /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = 0
       self.value = 0
     else:
     else:
       try:
       try:
         self.value = int(unicode(xmlvalue.firstChild.data))
         self.value = int(unicode(xmlvalue.firstChild.data))
       except:
       except:
-        log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data))
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
@@ -1067,20 +1069,20 @@ class opcua_BuiltinType_int64_t(opcua_value_t):
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <Int64 /> by setting the value to a default
     # Catch XML <Int64 /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = 0
       self.value = 0
     else:
     else:
       try:
       try:
         self.value = int(unicode(xmlvalue.firstChild.data))
         self.value = int(unicode(xmlvalue.firstChild.data))
       except:
       except:
-        log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data))
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
@@ -1096,25 +1098,25 @@ class opcua_BuiltinType_uint64_t(opcua_value_t):
     # Expect <UInt16>value</UInt16> or
     # Expect <UInt16>value</UInt16> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <UInt64 /> by setting the value to a default
     # Catch XML <UInt64 /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = 0
       self.value = 0
     else:
     else:
       try:
       try:
         self.value = int(unicode(xmlvalue.firstChild.data))
         self.value = int(unicode(xmlvalue.firstChild.data))
       except:
       except:
-        log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data))
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
@@ -1130,25 +1132,25 @@ class opcua_BuiltinType_float_t(opcua_value_t):
     # Expect <Float>value</Float> or
     # Expect <Float>value</Float> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <Float /> by setting the value to a default
     # Catch XML <Float /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = 0.0
       self.value = 0.0
     else:
     else:
       try:
       try:
         self.value = float(unicode(xmlvalue.firstChild.data))
         self.value = float(unicode(xmlvalue.firstChild.data))
       except:
       except:
-        log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data))
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
@@ -1164,25 +1166,25 @@ class opcua_BuiltinType_double_t(opcua_value_t):
     # Expect <Double>value</Double> or
     # Expect <Double>value</Double> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <Double /> by setting the value to a default
     # Catch XML <Double /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = 0.0
       self.value = 0.0
     else:
     else:
       try:
       try:
         self.value = float(unicode(xmlvalue.firstChild.data))
         self.value = float(unicode(xmlvalue.firstChild.data))
       except:
       except:
-        log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
+        logger.error("Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data))
 
 
   def printOpen62541CCode_SubType(self, asIndirect=True):
   def printOpen62541CCode_SubType(self, asIndirect=True):
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
     return "(UA_" + self.stringRepresentation + ") " + str(self.value)
@@ -1203,19 +1205,19 @@ class opcua_BuiltinType_string_t(opcua_value_t):
     # Expect <String>value</String> or
     # Expect <String>value</String> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <String /> by setting the value to a default
     # Catch XML <String /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = ""
       self.value = ""
     else:
     else:
       self.value = str(unicode(xmlvalue.firstChild.data))
       self.value = str(unicode(xmlvalue.firstChild.data))
@@ -1246,19 +1248,19 @@ class opcua_BuiltinType_bytestring_t(opcua_value_t):
     # Expect <ByteString>value</ByteString> or
     # Expect <ByteString>value</ByteString> or
     #        <Aliasname>value</Aliasname>
     #        <Aliasname>value</Aliasname>
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
     if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
-      log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
+      logger.error("Expected XML Element, but got junk...")
       return
       return
 
 
     if self.alias() != None:
     if self.alias() != None:
       if not self.alias() == xmlvalue.tagName:
       if not self.alias() == xmlvalue.tagName:
-        log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
     else:
     else:
       if not self.stringRepresentation == xmlvalue.tagName:
       if not self.stringRepresentation == xmlvalue.tagName:
-        log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
+        logger.warn("Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.")
 
 
     # Catch XML <ByteString /> by setting the value to a default
     # Catch XML <ByteString /> by setting the value to a default
     if xmlvalue.firstChild == None:
     if xmlvalue.firstChild == None:
-      log(self, "No value is given. Setting to default 0")
+      logger.debug("No value is given. Setting to default 0")
       self.value = ""
       self.value = ""
     else:
     else:
       self.value = str(unicode(xmlvalue.firstChild.data))
       self.value = str(unicode(xmlvalue.firstChild.data))
@@ -1268,7 +1270,7 @@ class opcua_BuiltinType_bytestring_t(opcua_value_t):
       for line in self.value:
       for line in self.value:
         bs = bs + str(line).replace("\n","");
         bs = bs + str(line).replace("\n","");
       outs = bs
       outs = bs
-      log(self, "Encoded Bytestring: " + outs, LOG_LEVEL_DEBUG)
+      logger.debug("Encoded Bytestring: " + outs)
 #      bs = bs.decode('base64')
 #      bs = bs.decode('base64')
 #      outs = ""
 #      outs = ""
 #      for s in bs:
 #      for s in bs:

+ 85 - 84
tools/pyUANamespace/ua_namespace.py

@@ -21,12 +21,15 @@ import sys
 from time import struct_time, strftime, strptime, mktime
 from time import struct_time, strftime, strptime, mktime
 from struct import pack as structpack
 from struct import pack as structpack
 
 
-from logger import *;
+import logging
 from ua_builtin_types import *;
 from ua_builtin_types import *;
 from ua_node_types import *;
 from ua_node_types import *;
 from ua_constants import *;
 from ua_constants import *;
 from open62541_MacroHelper import open62541_MacroHelper
 from open62541_MacroHelper import open62541_MacroHelper
 
 
+
+logger = logging.getLogger(__name__)
+
 def getNextElementNode(xmlvalue):
 def getNextElementNode(xmlvalue):
   if xmlvalue == None:
   if xmlvalue == None:
     return None
     return None
@@ -59,7 +62,7 @@ class opcua_namespace():
   name = ""
   name = ""
   knownNodeTypes = ""
   knownNodeTypes = ""
   namespaceIdentifiers = {} # list of 'int':'string' giving different namespace an array-mapable name
   namespaceIdentifiers = {} # list of 'int':'string' giving different namespace an array-mapable name
-  
+
   def __init__(self, name):
   def __init__(self, name):
     self.nodes = []
     self.nodes = []
     self.knownNodeTypes = ['variable', 'object', 'method', 'referencetype', \
     self.knownNodeTypes = ['variable', 'object', 'method', 'referencetype', \
@@ -73,7 +76,7 @@ class opcua_namespace():
 
 
   def addNamespace(self, numericId, stringURL):
   def addNamespace(self, numericId, stringURL):
     self.namespaceIdentifiers[numericId] = stringURL
     self.namespaceIdentifiers[numericId] = stringURL
-    
+
   def linkLater(self, pointer):
   def linkLater(self, pointer):
     """ Called by nodes or references who have parsed an XML reference to a
     """ Called by nodes or references who have parsed an XML reference to a
         node represented by a string.
         node represented by a string.
@@ -112,7 +115,7 @@ class opcua_namespace():
         dereferencing during pointer linkage (see linkOpenPointer()).
         dereferencing during pointer linkage (see linkOpenPointer()).
     """
     """
     if not xmlelement.tagName == "Aliases":
     if not xmlelement.tagName == "Aliases":
-      log(self, "XMLElement passed is not an Aliaslist", LOG_LEVEL_ERROR)
+      logger.error("XMLElement passed is not an Aliaslist")
       return
       return
     for al in xmlelement.childNodes:
     for al in xmlelement.childNodes:
       if al.nodeType == al.ELEMENT_NODE:
       if al.nodeType == al.ELEMENT_NODE:
@@ -124,10 +127,10 @@ class opcua_namespace():
             aliasnd = al.firstChild.data
             aliasnd = al.firstChild.data
           if not aliasst in self.aliases:
           if not aliasst in self.aliases:
             self.aliases[aliasst] = aliasnd
             self.aliases[aliasst] = aliasnd
-            log(self, "Added new alias \"" + str(aliasst) + "\" == \"" + str(aliasnd) + "\"")
+            logger.debug("Added new alias \"" + str(aliasst) + "\" == \"" + str(aliasnd) + "\"")
           else:
           else:
             if self.aliases[aliasst] != aliasnd:
             if self.aliases[aliasst] != aliasnd:
-              log(self, "Alias definitions for " + aliasst + " differ. Have " + self.aliases[aliasst] + " but XML defines " + aliasnd + ". Keeping current definition.", LOG_LEVEL_ERROR)
+              logger.error("Alias definitions for " + aliasst + " differ. Have " + self.aliases[aliasst] + " but XML defines " + aliasnd + ". Keeping current definition.")
 
 
   def getNodeByBrowseName(self, idstring):
   def getNodeByBrowseName(self, idstring):
     """ Returns the first node in the nodelist whose browseName matches idstring.
     """ Returns the first node in the nodelist whose browseName matches idstring.
@@ -137,7 +140,7 @@ class opcua_namespace():
       if idstring==str(n.browseName()):
       if idstring==str(n.browseName()):
         matches.append(n)
         matches.append(n)
     if len(matches) > 1:
     if len(matches) > 1:
-      log(self, "Found multiple nodes with same ID!?", LOG_LEVEL_ERROR)
+      logger.error("Found multiple nodes with same ID!?")
     if len(matches) == 0:
     if len(matches) == 0:
       return None
       return None
     else:
     else:
@@ -152,7 +155,7 @@ class opcua_namespace():
       if idstring==str(n.id()):
       if idstring==str(n.id()):
         matches.append(n)
         matches.append(n)
     if len(matches) > 1:
     if len(matches) > 1:
-      log(self, "Found multiple nodes with same ID!?", LOG_LEVEL_ERROR)
+      logger.error("Found multiple nodes with same ID!?")
     if len(matches) == 0:
     if len(matches) == 0:
       return None
       return None
     else:
     else:
@@ -187,10 +190,10 @@ class opcua_namespace():
         deferred and an error is logged.
         deferred and an error is logged.
     """
     """
     if not isinstance(xmlelement, dom.Element):
     if not isinstance(xmlelement, dom.Element):
-      log(self,  "Error: Can not create node from invalid XMLElement", LOG_LEVEL_ERROR)
+      logger.error( "Error: Can not create node from invalid XMLElement")
       return
       return
 
 
-    # An ID is manditory for everything but aliases!
+    # An ID is mandatory for everything but aliases!
     id = None
     id = None
     for idname in ['NodeId', 'NodeID', 'nodeid']:
     for idname in ['NodeId', 'NodeID', 'nodeid']:
       if xmlelement.hasAttribute(idname):
       if xmlelement.hasAttribute(idname):
@@ -199,17 +202,17 @@ class opcua_namespace():
       self.buildAliasList(xmlelement)
       self.buildAliasList(xmlelement)
       return
       return
     elif id == None:
     elif id == None:
-      log(self,  "Error: XMLElement has no id, node will not be created!", LOG_LEVEL_INFO)
+      logger.info( "Error: XMLElement has no id, node will not be created!")
       return
       return
     else:
     else:
       id = opcua_node_id_t(id)
       id = opcua_node_id_t(id)
 
 
     if str(id) in self.nodeids:
     if str(id) in self.nodeids:
       # Normal behavior: Do not allow duplicates, first one wins
       # Normal behavior: Do not allow duplicates, first one wins
-      #log(self,  "XMLElement with duplicate ID " + str(id) + " found, node will not be created!", LOG_LEVEL_ERROR)
+      #logger.error( "XMLElement with duplicate ID " + str(id) + " found, node will not be created!")
       #return
       #return
       # Open62541 behavior for header generation: Replace the duplicate with the new node
       # Open62541 behavior for header generation: Replace the duplicate with the new node
-      log(self,  "XMLElement with duplicate ID " + str(id) + " found, node will be replaced!", LOG_LEVEL_INFO)
+      logger.info( "XMLElement with duplicate ID " + str(id) + " found, node will be replaced!")
       nd = self.getNodeByIDString(str(id))
       nd = self.getNodeByIDString(str(id))
       self.nodes.remove(nd)
       self.nodes.remove(nd)
       self.nodeids.pop(str(nd.id()))
       self.nodeids.pop(str(nd.id()))
@@ -232,7 +235,7 @@ class opcua_namespace():
     elif (ndtype == 'referencetype'):
     elif (ndtype == 'referencetype'):
       node = opcua_node_referenceType_t(id, self)
       node = opcua_node_referenceType_t(id, self)
     else:
     else:
-      log(self,  "No node constructor for type " + ndtype, LOG_LEVEL_ERROR)
+      logger.error( "No node constructor for type " + ndtype)
 
 
     if node != None:
     if node != None:
       node.parseXML(xmlelement)
       node.parseXML(xmlelement)
@@ -245,7 +248,7 @@ class opcua_namespace():
     if nd == None:
     if nd == None:
       return False
       return False
 
 
-    log(self, "Removing nodeId " + str(nodeId), LOG_LEVEL_DEBUG)
+    logger.debug("Removing nodeId " + str(nodeId))
     self.nodes.remove(nd)
     self.nodes.remove(nd)
     if nd.getInverseReferences() != None:
     if nd.getInverseReferences() != None:
       for ref in nd.getInverseReferences():
       for ref in nd.getInverseReferences():
@@ -286,10 +289,10 @@ class opcua_namespace():
     typedict = {}
     typedict = {}
     UANodeSet = dom.parse(xmldoc).getElementsByTagName("UANodeSet")
     UANodeSet = dom.parse(xmldoc).getElementsByTagName("UANodeSet")
     if len(UANodeSet) == 0:
     if len(UANodeSet) == 0:
-      log(self,  "Error: No NodeSets found", LOG_LEVEL_ERROR)
+      logger.error( "Error: No NodeSets found")
       return
       return
     if len(UANodeSet) != 1:
     if len(UANodeSet) != 1:
-      log(self,  "Error: Found more than 1 Nodeset in XML File", LOG_LEVEL_ERROR)
+      logger.error( "Error: Found more than 1 Nodeset in XML File")
 
 
     UANodeSet = UANodeSet[0]
     UANodeSet = UANodeSet[0]
     for nd in UANodeSet.childNodes:
     for nd in UANodeSet.childNodes:
@@ -300,7 +303,7 @@ class opcua_namespace():
       if ndType[:2] == "ua":
       if ndType[:2] == "ua":
         ndType = ndType[2:]
         ndType = ndType[2:]
       elif not ndType in self.knownNodeTypes:
       elif not ndType in self.knownNodeTypes:
-        log(self, "XML Element or NodeType " + ndType + " is unknown and will be ignored", LOG_LEVEL_WARN)
+        logger.warn("XML Element or NodeType " + ndType + " is unknown and will be ignored")
         continue
         continue
 
 
       if not ndType in typedict:
       if not ndType in typedict:
@@ -309,7 +312,7 @@ class opcua_namespace():
         typedict[ndType] = typedict[ndType] + 1
         typedict[ndType] = typedict[ndType] + 1
 
 
       self.createNode(ndType, nd)
       self.createNode(ndType, nd)
-    log(self, "Currently " + str(len(self.nodes)) + " nodes in address space. Type distribution for this run was: " + str(typedict))
+    logger.debug("Currently " + str(len(self.nodes)) + " nodes in address space. Type distribution for this run was: " + str(typedict))
 
 
   def linkOpenPointers(self):
   def linkOpenPointers(self):
     """ Substitutes symbolic NodeIds in references for actual node instances.
     """ Substitutes symbolic NodeIds in references for actual node instances.
@@ -330,7 +333,7 @@ class opcua_namespace():
     """
     """
     linked = []
     linked = []
 
 
-    log(self,  str(self.unlinkedItemCount()) + " pointers need to get linked.")
+    logger.debug( str(self.unlinkedItemCount()) + " pointers need to get linked.")
     for l in self.__linkLater__:
     for l in self.__linkLater__:
       targetLinked = False
       targetLinked = False
       if not l.target() == None and not isinstance(l.target(), opcua_node_t):
       if not l.target() == None and not isinstance(l.target(), opcua_node_t):
@@ -346,30 +349,28 @@ class opcua_namespace():
              l.target()[:3] == "ns=" :
              l.target()[:3] == "ns=" :
             tgt = self.getNodeByIDString(str(l.target()))
             tgt = self.getNodeByIDString(str(l.target()))
             if tgt == None:
             if tgt == None:
-              log(self, "Failed to link pointer to target (node not found) " + l.target(), LOG_LEVEL_ERROR)
+              logger.error("Failed to link pointer to target (node not found) " + l.target())
             else:
             else:
               l.target(tgt)
               l.target(tgt)
               targetLinked = True
               targetLinked = True
           else:
           else:
-            log(self, "Failed to link pointer to target (target not Alias or Node) " + l.target(), LOG_LEVEL_ERROR)
+            logger.error("Failed to link pointer to target (target not Alias or Node) " + l.target())
         else:
         else:
-          log(self, "Failed to link pointer to target (don't know dummy type + " + str(type(l.target())) + " +) " + str(l.target()), LOG_LEVEL_ERROR)
+          logger.error("Failed to link pointer to target (don't know dummy type + " + str(type(l.target())) + " +) " + str(l.target()))
       else:
       else:
-        log(self, "Pointer has null target: " + str(l), LOG_LEVEL_ERROR)
+        logger.error("Pointer has null target: " + str(l))
 
 
 
 
       referenceLinked = False
       referenceLinked = False
       if not l.referenceType() == None:
       if not l.referenceType() == None:
         if l.referenceType() in self.aliases:
         if l.referenceType() in self.aliases:
           l.referenceType(self.aliases[l.referenceType()])
           l.referenceType(self.aliases[l.referenceType()])
-        if l.referenceType()[:2] == "i=" or l.referenceType()[:2] == "g=" or \
-           l.referenceType()[:2] == "b=" or l.referenceType()[:2] == "s=":
-          tgt = self.getNodeByIDString(str(l.referenceType()))
-          if tgt == None:
-            log(self, "Failed to link reference type to target (node not found) " + l.referenceType(), LOG_LEVEL_ERROR)
-          else:
-            l.referenceType(tgt)
-            referenceLinked = True
+        tgt = self.getNodeByIDString(str(l.referenceType()))
+        if tgt == None:
+          logger.error("Failed to link reference type to target (node not found) " + l.referenceType())
+        else:
+          l.referenceType(tgt)
+          referenceLinked = True
       else:
       else:
         referenceLinked = True
         referenceLinked = True
 
 
@@ -377,7 +378,7 @@ class opcua_namespace():
         linked.append(l)
         linked.append(l)
 
 
     # References marked as "not forward" must be inverted (removed from source node, assigned to target node and relinked)
     # References marked as "not forward" must be inverted (removed from source node, assigned to target node and relinked)
-    log(self, "Inverting reference direction for all references with isForward==False attribute (is this correct!?)", LOG_LEVEL_WARN)
+    logger.warn("Inverting reference direction for all references with isForward==False attribute (is this correct!?)")
     for n in self.nodes:
     for n in self.nodes:
       for r in n.getReferences():
       for r in n.getReferences():
         if r.isForward() == False:
         if r.isForward() == False:
@@ -388,7 +389,7 @@ class opcua_namespace():
             tgt.addReference(nref)
             tgt.addReference(nref)
 
 
     # Create inverse references for all nodes
     # Create inverse references for all nodes
-    log(self, "Updating all referencedBy fields in nodes for inverse lookups.")
+    logger.debug("Updating all referencedBy fields in nodes for inverse lookups.")
     for n in self.nodes:
     for n in self.nodes:
       n.updateInverseReferences()
       n.updateInverseReferences()
 
 
@@ -396,19 +397,19 @@ class opcua_namespace():
       self.__linkLater__.remove(l)
       self.__linkLater__.remove(l)
 
 
     if len(self.__linkLater__) != 0:
     if len(self.__linkLater__) != 0:
-      log(self, str(len(self.__linkLater__)) + " could not be linked.", LOG_LEVEL_WARN)
+      logger.warn(str(len(self.__linkLater__)) + " could not be linked.")
 
 
   def sanitize(self):
   def sanitize(self):
     remove = []
     remove = []
-    log(self, "Sanitizing nodes and references...")
+    logger.debug("Sanitizing nodes and references...")
     for n in self.nodes:
     for n in self.nodes:
       if n.sanitize() == False:
       if n.sanitize() == False:
         remove.append(n)
         remove.append(n)
     if not len(remove) == 0:
     if not len(remove) == 0:
-      log(self, str(len(remove)) + " nodes will be removed because they failed sanitation.", LOG_LEVEL_WARN)
+      logger.warn(str(len(remove)) + " nodes will be removed because they failed sanitation.")
     # FIXME: Some variable ns=0 nodes fail because they don't have DataType fields...
     # FIXME: Some variable ns=0 nodes fail because they don't have DataType fields...
     #        How should this be handles!?
     #        How should this be handles!?
-    log(self, "Not actually removing nodes... it's unclear if this is valid or not", LOG_LEVEL_WARN)
+    logger.warn("Not actually removing nodes... it's unclear if this is valid or not")
 
 
   def getRoot(self):
   def getRoot(self):
     """ Returns the first node instance with the browseName "Root".
     """ Returns the first node instance with the browseName "Root".
@@ -425,7 +426,7 @@ class opcua_namespace():
       if isinstance(n, opcua_node_dataType_t):
       if isinstance(n, opcua_node_dataType_t):
         n.buildEncoding()
         n.buildEncoding()
         stat[n.isEncodable()] = stat[n.isEncodable()] + 1
         stat[n.isEncodable()] = stat[n.isEncodable()] + 1
-    log(self, "Type definitions built/passed: " +  str(stat), LOG_LEVEL_DEBUG)
+    logger.debug("Type definitions built/passed: " +  str(stat))
 
 
   def allocateVariables(self):
   def allocateVariables(self):
     for n in self.nodes:
     for n in self.nodes:
@@ -448,10 +449,10 @@ class opcua_namespace():
       file.write(n.printDot())
       file.write(n.printDot())
     file.write("}\n")
     file.write("}\n")
     file.close()
     file.close()
-  
+
   def getSubTypesOf(self, tdNodes = None, currentNode = None, hasSubtypeRefNode = None):
   def getSubTypesOf(self, tdNodes = None, currentNode = None, hasSubtypeRefNode = None):
     # If this is a toplevel call, collect the following information as defaults
     # If this is a toplevel call, collect the following information as defaults
-    if tdNodes == None: 
+    if tdNodes == None:
       tdNodes = []
       tdNodes = []
     if currentNode == None:
     if currentNode == None:
       currentNode = self.getNodeByBrowseName("HasTypeDefinition")
       currentNode = self.getNodeByBrowseName("HasTypeDefinition")
@@ -462,16 +463,16 @@ class opcua_namespace():
       hasSubtypeRefNode = self.getNodeByBrowseName("HasSubtype")
       hasSubtypeRefNode = self.getNodeByBrowseName("HasSubtype")
       if hasSubtypeRefNode == None:
       if hasSubtypeRefNode == None:
         return tdNodes
         return tdNodes
-    
+
     # collect all subtypes of this node
     # collect all subtypes of this node
     for ref in currentNode.getReferences():
     for ref in currentNode.getReferences():
       if ref.isForward() and ref.referenceType().id() == hasSubtypeRefNode.id():
       if ref.isForward() and ref.referenceType().id() == hasSubtypeRefNode.id():
         tdNodes.append(ref.target())
         tdNodes.append(ref.target())
         self.getTypeDefinitionNodes(tdNodes=tdNodes, currentNode = ref.target(), hasSubtypeRefNode=hasSubtypeRefNode)
         self.getTypeDefinitionNodes(tdNodes=tdNodes, currentNode = ref.target(), hasSubtypeRefNode=hasSubtypeRefNode)
-    
+
     return tdNodes
     return tdNodes
-      
-  
+
+
   def printDotGraphWalk(self, depth=1, filename="out.dot", rootNode=None, followInverse = False, excludeNodeIds=[]):
   def printDotGraphWalk(self, depth=1, filename="out.dot", rootNode=None, followInverse = False, excludeNodeIds=[]):
     """ Outputs a graphiz/dot description the nodes centered around rootNode.
     """ Outputs a graphiz/dot description the nodes centered around rootNode.
 
 
@@ -545,14 +546,14 @@ class opcua_namespace():
         minweight = w
         minweight = w
         minweightnd = row[0]
         minweightnd = row[0]
     return (rind, minweightnd, minweight)
     return (rind, minweightnd, minweight)
-  
+
   def reorderNodesMinDependencies(self):
   def reorderNodesMinDependencies(self):
     # create a matrix represtantion of all node
     # create a matrix represtantion of all node
     #
     #
     nmatrix = []
     nmatrix = []
     for n in range(0,len(self.nodes)):
     for n in range(0,len(self.nodes)):
       nmatrix.append([None] + [0]*len(self.nodes))
       nmatrix.append([None] + [0]*len(self.nodes))
-    
+
     typeRefs = []
     typeRefs = []
     tn = self.getNodeByBrowseName("HasTypeDefinition")
     tn = self.getNodeByBrowseName("HasTypeDefinition")
     if tn != None:
     if tn != None:
@@ -563,13 +564,13 @@ class opcua_namespace():
     if tn  != None:
     if tn  != None:
       subTypeRefs.append(tn)
       subTypeRefs.append(tn)
       subTypeRefs = subTypeRefs + self.getSubTypesOf(currentNode=tn)
       subTypeRefs = subTypeRefs + self.getSubTypesOf(currentNode=tn)
-    
-    log(self, "Building connectivity matrix for node order optimization.")
+
+    logger.debug("Building connectivity matrix for node order optimization.")
     # Set column 0 to contain the node
     # Set column 0 to contain the node
     for node in self.nodes:
     for node in self.nodes:
       nind = self.nodes.index(node)
       nind = self.nodes.index(node)
       nmatrix[nind][0] = node
       nmatrix[nind][0] = node
-      
+
     # Determine the dependencies of all nodes
     # Determine the dependencies of all nodes
     for node in self.nodes:
     for node in self.nodes:
       nind = self.nodes.index(node)
       nind = self.nodes.index(node)
@@ -586,8 +587,8 @@ class opcua_namespace():
           # Else the target depends on us
           # Else the target depends on us
           elif ref.isForward():
           elif ref.isForward():
             nmatrix[tind][nind+1] += 1
             nmatrix[tind][nind+1] += 1
-    
-    log(self, "Using Djikstra topological sorting to determine printing order.")
+
+    logger.debug("Using Djikstra topological sorting to determine printing order.")
     reorder = []
     reorder = []
     while len(reorder) < len(self.nodes):
     while len(reorder) < len(self.nodes):
       (nind, node, w) = self.__reorder_getMinWeightNode__(nmatrix)
       (nind, node, w) = self.__reorder_getMinWeightNode__(nmatrix)
@@ -604,23 +605,23 @@ class opcua_namespace():
             nmatrix[tind][nind+1] -= 1
             nmatrix[tind][nind+1] -= 1
       nmatrix[nind][0] = None
       nmatrix[nind][0] = None
     self.nodes = reorder
     self.nodes = reorder
-    log(self, "Nodes reordered.")
+    logger.debug("Nodes reordered.")
     return
     return
-  
+
   def printOpen62541Header(self, printedExternally=[], supressGenerationOfAttribute=[], outfilename=""):
   def printOpen62541Header(self, printedExternally=[], supressGenerationOfAttribute=[], outfilename=""):
     unPrintedNodes = []
     unPrintedNodes = []
     unPrintedRefs  = []
     unPrintedRefs  = []
     code = []
     code = []
     header = []
     header = []
-    
+
     # Reorder our nodes to produce a bare minimum of bootstrapping dependencies
     # Reorder our nodes to produce a bare minimum of bootstrapping dependencies
-    log(self, "Reordering nodes for minimal dependencies during printing.")
+    logger.debug("Reordering nodes for minimal dependencies during printing.")
     self.reorderNodesMinDependencies()
     self.reorderNodesMinDependencies()
-    
+
     # Some macros (UA_EXPANDEDNODEID_MACRO()...) are easily created, but
     # Some macros (UA_EXPANDEDNODEID_MACRO()...) are easily created, but
     # bulky. This class will help to offload some code.
     # bulky. This class will help to offload some code.
     codegen = open62541_MacroHelper(supressGenerationOfAttribute=supressGenerationOfAttribute)
     codegen = open62541_MacroHelper(supressGenerationOfAttribute=supressGenerationOfAttribute)
-    
+
     # Populate the unPrinted-Lists with everything we have.
     # Populate the unPrinted-Lists with everything we have.
     # Every Time a nodes printfunction is called, it will pop itself and
     # Every Time a nodes printfunction is called, it will pop itself and
     #   all printed references from these lists.
     #   all printed references from these lists.
@@ -628,13 +629,13 @@ class opcua_namespace():
       if not n in printedExternally:
       if not n in printedExternally:
         unPrintedNodes.append(n)
         unPrintedNodes.append(n)
       else:
       else:
-        log(self, "Node " + str(n.id()) + " is being ignored.", LOG_LEVEL_DEBUG)
+        logger.debug("Node " + str(n.id()) + " is being ignored.")
     for n in unPrintedNodes:
     for n in unPrintedNodes:
       for r in n.getReferences():
       for r in n.getReferences():
         if (r.target() != None) and (r.target().id() != None) and (r.parent() != None):
         if (r.target() != None) and (r.target().id() != None) and (r.parent() != None):
           unPrintedRefs.append(r)
           unPrintedRefs.append(r)
 
 
-    log(self, str(len(unPrintedNodes)) + " Nodes, " + str(len(unPrintedRefs)) +  "References need to get printed.", LOG_LEVEL_DEBUG)
+    logger.debug(str(len(unPrintedNodes)) + " Nodes, " + str(len(unPrintedRefs)) +  "References need to get printed.")
     header.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */")
     header.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */")
     code.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */")
     code.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */")
 
 
@@ -652,10 +653,10 @@ class opcua_namespace():
     header.append('#include "open62541.h"')
     header.append('#include "open62541.h"')
     header.append('#define NULL ((void *)0)')
     header.append('#define NULL ((void *)0)')
     header.append('#endif')
     header.append('#endif')
-      
+
     code.append('#include "'+outfilename+'.h"')
     code.append('#include "'+outfilename+'.h"')
     code.append("UA_INLINE void "+outfilename+"(UA_Server *server) {")
     code.append("UA_INLINE void "+outfilename+"(UA_Server *server) {")
-    
+
     # Before printing nodes, we need to request additional namespace arrays from the server
     # Before printing nodes, we need to request additional namespace arrays from the server
     for nsid in self.namespaceIdentifiers:
     for nsid in self.namespaceIdentifiers:
       if nsid == 0 or nsid==1:
       if nsid == 0 or nsid==1:
@@ -664,11 +665,11 @@ class opcua_namespace():
         name =  self.namespaceIdentifiers[nsid]
         name =  self.namespaceIdentifiers[nsid]
         name = name.replace("\"","\\\"")
         name = name.replace("\"","\\\"")
         code.append("UA_Server_addNamespace(server, \"" + name.encode('UTF-8') + "\");")
         code.append("UA_Server_addNamespace(server, \"" + name.encode('UTF-8') + "\");")
-    
+
     # Find all references necessary to create the namespace and
     # Find all references necessary to create the namespace and
     # "Bootstrap" them so all other nodes can safely use these referencetypes whenever
     # "Bootstrap" them so all other nodes can safely use these referencetypes whenever
     # they can locate both source and target of the reference.
     # they can locate both source and target of the reference.
-    log(self, "Collecting all references used in the namespace.", LOG_LEVEL_DEBUG)
+    logger.debug("Collecting all references used in the namespace.")
     refsUsed = []
     refsUsed = []
     for n in self.nodes:
     for n in self.nodes:
       # Since we are already looping over all nodes, use this chance to print NodeId defines
       # Since we are already looping over all nodes, use this chance to print NodeId defines
@@ -676,39 +677,39 @@ class opcua_namespace():
         nc = n.nodeClass()
         nc = n.nodeClass()
         if nc != NODE_CLASS_OBJECT and nc != NODE_CLASS_VARIABLE and nc != NODE_CLASS_VIEW:
         if nc != NODE_CLASS_OBJECT and nc != NODE_CLASS_VARIABLE and nc != NODE_CLASS_VIEW:
           header = header + codegen.getNodeIdDefineString(n)
           header = header + codegen.getNodeIdDefineString(n)
-          
+
       # Now for the actual references...
       # Now for the actual references...
       for r in n.getReferences():
       for r in n.getReferences():
         # Only print valid refernces in namespace 0 (users will not want their refs bootstrapped)
         # Only print valid refernces in namespace 0 (users will not want their refs bootstrapped)
         if not r.referenceType() in refsUsed and r.referenceType() != None and r.referenceType().id().ns == 0:
         if not r.referenceType() in refsUsed and r.referenceType() != None and r.referenceType().id().ns == 0:
           refsUsed.append(r.referenceType())
           refsUsed.append(r.referenceType())
-    log(self, str(len(refsUsed)) + " reference types are used in the namespace, which will now get bootstrapped.", LOG_LEVEL_DEBUG)
+    logger.debug(str(len(refsUsed)) + " reference types are used in the namespace, which will now get bootstrapped.")
     for r in refsUsed:
     for r in refsUsed:
       code = code + r.printOpen62541CCode(unPrintedNodes, unPrintedRefs);
       code = code + r.printOpen62541CCode(unPrintedNodes, unPrintedRefs);
-    
+
     header.append("extern void "+outfilename+"(UA_Server *server);\n")
     header.append("extern void "+outfilename+"(UA_Server *server);\n")
     header.append("#endif /* "+outfilename.upper()+"_H_ */")
     header.append("#endif /* "+outfilename.upper()+"_H_ */")
-    
+
     # Note to self: do NOT - NOT! - try to iterate over unPrintedNodes!
     # Note to self: do NOT - NOT! - try to iterate over unPrintedNodes!
     #               Nodes remove themselves from this list when printed.
     #               Nodes remove themselves from this list when printed.
-    log(self, "Printing all other nodes.", LOG_LEVEL_DEBUG)
+    logger.debug("Printing all other nodes.")
     for n in self.nodes:
     for n in self.nodes:
       code = code + n.printOpen62541CCode(unPrintedNodes, unPrintedRefs, supressGenerationOfAttribute=supressGenerationOfAttribute)
       code = code + n.printOpen62541CCode(unPrintedNodes, unPrintedRefs, supressGenerationOfAttribute=supressGenerationOfAttribute)
 
 
     if len(unPrintedNodes) != 0:
     if len(unPrintedNodes) != 0:
-      log(self, "" + str(len(unPrintedNodes)) + " nodes could not be translated to code.", LOG_LEVEL_WARN)
+      logger.warn("" + str(len(unPrintedNodes)) + " nodes could not be translated to code.")
     else:
     else:
-      log(self, "Printing suceeded for all nodes", LOG_LEVEL_DEBUG)
+      logger.debug("Printing suceeded for all nodes")
 
 
     if len(unPrintedRefs) != 0:
     if len(unPrintedRefs) != 0:
-      log(self, "Attempting to print " + str(len(unPrintedRefs)) + " unprinted references.", LOG_LEVEL_DEBUG)
+      logger.debug("Attempting to print " + str(len(unPrintedRefs)) + " unprinted references.")
       tmprefs = []
       tmprefs = []
       for r in unPrintedRefs:
       for r in unPrintedRefs:
         if  not (r.target() not in unPrintedNodes) and not (r.parent() in unPrintedNodes):
         if  not (r.target() not in unPrintedNodes) and not (r.parent() in unPrintedNodes):
           if not isinstance(r.parent(), opcua_node_t):
           if not isinstance(r.parent(), opcua_node_t):
-            log(self, "Reference has no parent!", LOG_LEVEL_DEBUG)
+            logger.debug("Reference has no parent!")
           elif not isinstance(r.parent().id(), opcua_node_id_t):
           elif not isinstance(r.parent().id(), opcua_node_id_t):
-            log(self, "Parents nodeid is not a nodeID!", LOG_LEVEL_DEBUG)
+            logger.debug("Parents nodeid is not a nodeID!")
           else:
           else:
             if (len(tmprefs) == 0):
             if (len(tmprefs) == 0):
               code.append("//  Creating leftover references:")
               code.append("//  Creating leftover references:")
@@ -719,9 +720,9 @@ class opcua_namespace():
       for r in tmprefs:
       for r in tmprefs:
         unPrintedRefs.remove(r)
         unPrintedRefs.remove(r)
       if len(unPrintedRefs) != 0:
       if len(unPrintedRefs) != 0:
-        log(self, "" + str(len(unPrintedRefs)) + " references could not be translated to code.", LOG_LEVEL_WARN)
+        logger.warn("" + str(len(unPrintedRefs)) + " references could not be translated to code.")
     else:
     else:
-      log(self, "Printing succeeded for all references", LOG_LEVEL_DEBUG)
+      logger.debug("Printing succeeded for all references")
 
 
     code.append("}")
     code.append("}")
     return (header,code)
     return (header,code)
@@ -734,20 +735,20 @@ class testing:
   def __init__(self):
   def __init__(self):
     self.namespace = opcua_namespace("testing")
     self.namespace = opcua_namespace("testing")
 
 
-    log(self, "Phase 1: Reading XML file nodessets")
+    logger.debug("Phase 1: Reading XML file nodessets")
     self.namespace.parseXML("Opc.Ua.NodeSet2.xml")
     self.namespace.parseXML("Opc.Ua.NodeSet2.xml")
     #self.namespace.parseXML("Opc.Ua.NodeSet2.Part4.xml")
     #self.namespace.parseXML("Opc.Ua.NodeSet2.Part4.xml")
     #self.namespace.parseXML("Opc.Ua.NodeSet2.Part5.xml")
     #self.namespace.parseXML("Opc.Ua.NodeSet2.Part5.xml")
     #self.namespace.parseXML("Opc.Ua.SimulationNodeSet2.xml")
     #self.namespace.parseXML("Opc.Ua.SimulationNodeSet2.xml")
 
 
-    log(self, "Phase 2: Linking address space references and datatypes")
+    logger.debug("Phase 2: Linking address space references and datatypes")
     self.namespace.linkOpenPointers()
     self.namespace.linkOpenPointers()
     self.namespace.sanitize()
     self.namespace.sanitize()
 
 
-    log(self, "Phase 3: Comprehending DataType encoding rules")
+    logger.debug("Phase 3: Comprehending DataType encoding rules")
     self.namespace.buildEncodingRules()
     self.namespace.buildEncodingRules()
 
 
-    log(self, "Phase 4: Allocating variable value data")
+    logger.debug("Phase 4: Allocating variable value data")
     self.namespace.allocateVariables()
     self.namespace.allocateVariables()
 
 
     bin = self.namespace.buildBinary()
     bin = self.namespace.buildBinary()
@@ -775,7 +776,7 @@ class testing:
         ns.append(n)
         ns.append(n)
       print("...done, " + str(len(ns)) + " nodes discovered")
       print("...done, " + str(len(ns)) + " nodes discovered")
 
 
-    log(self, "Phase 5: Printing pretty graph")
+    logger.debug("Phase 5: Printing pretty graph")
     self.namespace.printDotGraphWalk(depth=1, rootNode=self.namespace.getNodeByIDString("i=84"), followInverse=False, excludeNodeIds=["i=29", "i=22", "i=25"])
     self.namespace.printDotGraphWalk(depth=1, rootNode=self.namespace.getNodeByIDString("i=84"), followInverse=False, excludeNodeIds=["i=29", "i=22", "i=25"])
     #self.namespace.printDot()
     #self.namespace.printDot()
 
 
@@ -783,17 +784,17 @@ class testing_open62541_header:
   def __init__(self):
   def __init__(self):
     self.namespace = opcua_namespace("testing")
     self.namespace = opcua_namespace("testing")
 
 
-    log(self, "Phase 1: Reading XML file nodessets")
+    logger.debug("Phase 1: Reading XML file nodessets")
     self.namespace.parseXML("Opc.Ua.NodeSet2.xml")
     self.namespace.parseXML("Opc.Ua.NodeSet2.xml")
     #self.namespace.parseXML("Opc.Ua.NodeSet2.Part4.xml")
     #self.namespace.parseXML("Opc.Ua.NodeSet2.Part4.xml")
     #self.namespace.parseXML("Opc.Ua.NodeSet2.Part5.xml")
     #self.namespace.parseXML("Opc.Ua.NodeSet2.Part5.xml")
     #self.namespace.parseXML("Opc.Ua.SimulationNodeSet2.xml")
     #self.namespace.parseXML("Opc.Ua.SimulationNodeSet2.xml")
 
 
-    log(self, "Phase 2: Linking address space references and datatypes")
+    logger.debug("Phase 2: Linking address space references and datatypes")
     self.namespace.linkOpenPointers()
     self.namespace.linkOpenPointers()
     self.namespace.sanitize()
     self.namespace.sanitize()
 
 
-    log(self, "Phase 3: Calling C Printers")
+    logger.debug("Phase 3: Calling C Printers")
     code = self.namespace.printOpen62541Header()
     code = self.namespace.printOpen62541Header()
 
 
     codeout = open("./open62541_namespace.c", "w+")
     codeout = open("./open62541_namespace.c", "w+")

+ 113 - 111
tools/pyUANamespace/ua_node_types.py

@@ -17,11 +17,13 @@
 ###
 ###
 
 
 import sys
 import sys
-from logger import *;
+import logging
 from ua_builtin_types import *;
 from ua_builtin_types import *;
 from open62541_MacroHelper import open62541_MacroHelper
 from open62541_MacroHelper import open62541_MacroHelper
 from ua_constants import *
 from ua_constants import *
 
 
+logger = logging.getLogger(__name__)
+
 def getNextElementNode(xmlvalue):
 def getNextElementNode(xmlvalue):
   if xmlvalue == None:
   if xmlvalue == None:
     return None
     return None
@@ -215,10 +217,10 @@ class opcua_node_id_t():
 
 
   def __str__(self):
   def __str__(self):
     return self.__mystrname__
     return self.__mystrname__
-  
-  def __eq__(self, nodeId2):    
+
+  def __eq__(self, nodeId2):
     return (self.toString() == nodeId2.toString())
     return (self.toString() == nodeId2.toString())
-  
+
   def __repr__(self):
   def __repr__(self):
     return self.__mystrname__
     return self.__mystrname__
 
 
@@ -322,11 +324,11 @@ class opcua_node_t:
     if not node in self.__node_referencedBy__:
     if not node in self.__node_referencedBy__:
       if not self.hasReferenceTarget(node):
       if not self.hasReferenceTarget(node):
         self.__node_referencedBy__.append(opcua_referencePointer_t(node, hidden=True, parentNode=self))
         self.__node_referencedBy__.append(opcua_referencePointer_t(node, hidden=True, parentNode=self))
-#        log(self, self.__node_browseName__ + " added reverse reference to " + str(node.__node_browseName__), LOG_LEVEL_DEBUG)
+#        logger.debug(self.__node_browseName__ + " added reverse reference to " + str(node.__node_browseName__))
 #      else:
 #      else:
-#        log(self, self.__node_browseName__ + " refusing reverse reference to " + str(node.__node_browseName__)  + " (referenced normally)", LOG_LEVEL_DEBUG)
+#        logger.debug(self.__node_browseName__ + " refusing reverse reference to " + str(node.__node_browseName__)  + " (referenced normally)")
 #    else:
 #    else:
-#      log(self, self.__node_browseName__ + " refusing reverse reference to " + str(node.__node_browseName__) + " (already reversed referenced)", LOG_LEVEL_DEBUG)
+#      logger.debug(self.__node_browseName__ + " refusing reverse reference to " + str(node.__node_browseName__) + " (already reversed referenced)")
 
 
   def getReferences(self):
   def getReferences(self):
     return self.__node_references__
     return self.__node_references__
@@ -389,10 +391,10 @@ class opcua_node_t:
     for r in self.getReferences():
     for r in self.getReferences():
       if isinstance(r.target(), opcua_node_t):
       if isinstance(r.target(), opcua_node_t):
         if not r.target().hasInverseReferenceTarget(self):
         if not r.target().hasInverseReferenceTarget(self):
-          #log(self, self.__node_browseName__ + " req. rev. referencing in" + str(r.target().__node_browseName__), LOG_LEVEL_DEBUG)
+          #logger.debug(self.__node_browseName__ + " req. rev. referencing in" + str(r.target().__node_browseName__))
           r.target().addInverseReferenceTarget(self)
           r.target().addInverseReferenceTarget(self)
       #else:
       #else:
-        #log(self, "Cannot register inverse link to " + str(r.target()) + " (not a node)")
+        #logger.debug("Cannot register inverse link to " + str(r.target()) + " (not a node)")
 
 
   def id(self):
   def id(self):
     return self.__node_id__
     return self.__node_id__
@@ -464,7 +466,7 @@ class opcua_node_t:
         with an actual instance of an opcua_node_t.
         with an actual instance of an opcua_node_t.
     """
     """
     if not xmlelement.tagName == "References":
     if not xmlelement.tagName == "References":
-      log(self, "XMLElement passed is not a reference list", LOG_LEVEL_ERROR)
+      logger.error("XMLElement passed is not a reference list")
       return
       return
     for ref in xmlelement.childNodes:
     for ref in xmlelement.childNodes:
       if ref.nodeType == ref.ELEMENT_NODE:
       if ref.nodeType == ref.ELEMENT_NODE:
@@ -478,7 +480,7 @@ class opcua_node_t:
             if "false" in av.lower():
             if "false" in av.lower():
               dummy.isForward(False)
               dummy.isForward(False)
           else:
           else:
-            log(self, "Don't know how to process attribute " + at + "(" + av + ") for references.", LOG_LEVEL_ERROR)
+            logger.error("Don't know how to process attribute " + at + "(" + av + ") for references.")
 
 
   def printDot(self):
   def printDot(self):
     cleanname = "node_" + str(self.id()).replace(";","").replace("=","")
     cleanname = "node_" + str(self.id()).replace(";","").replace("=","")
@@ -491,31 +493,31 @@ class opcua_node_t:
           dot = dot + cleanname + " -> " + tgtname + " [label=\"" + str(r.referenceType().browseName()) + "\"]\n"
           dot = dot + cleanname + " -> " + tgtname + " [label=\"" + str(r.referenceType().browseName()) + "\"]\n"
         else:
         else:
           if len(r.referenceType().inverseName()) == 0:
           if len(r.referenceType().inverseName()) == 0:
-            log(self, "Inverse name of reference is null " + str(r.referenceType().id()), LOG_LEVEL_WARN)
+            logger.warn("Inverse name of reference is null " + str(r.referenceType().id()))
           dot = dot + cleanname + " -> " + tgtname + " [label=\"" + str(r.referenceType().inverseName()) + "\"]\n"
           dot = dot + cleanname + " -> " + tgtname + " [label=\"" + str(r.referenceType().inverseName()) + "\"]\n"
     return dot
     return dot
 
 
   def sanitize(self):
   def sanitize(self):
     """ Check the health of this node.
     """ Check the health of this node.
 
 
-        Return True if all manditory attributes are valid and all references have been
+        Return True if all mandatory attributes are valid and all references have been
         correclty linked to nodes. Returns False on failure, which should indicate
         correclty linked to nodes. Returns False on failure, which should indicate
         that this node needs to be removed from the namespace.
         that this node needs to be removed from the namespace.
     """
     """
     # Do we have an id?
     # Do we have an id?
     if not isinstance(self.id(), opcua_node_id_t):
     if not isinstance(self.id(), opcua_node_id_t):
-      log(self, "HELP! I'm an id'less node!", LOG_LEVEL_ERROR)
+      logger.error("HELP! I'm an id'less node!")
       return False
       return False
 
 
     # Remove unlinked references
     # Remove unlinked references
     tmp = []
     tmp = []
     for r in self.getReferences():
     for r in self.getReferences():
       if not isinstance(r, opcua_referencePointer_t):
       if not isinstance(r, opcua_referencePointer_t):
-        log(self, "Reference is not a reference!?.", LOG_LEVEL_ERROR)
+        logger.error("Reference is not a reference!?.")
       elif not isinstance(r.referenceType(), opcua_node_t):
       elif not isinstance(r.referenceType(), opcua_node_t):
-        log(self, "Reference has no valid reference type and will be removed.", LOG_LEVEL_ERROR)
+        logger.error("Reference has no valid reference type and will be removed.")
       elif not isinstance(r.target(), opcua_node_t):
       elif not isinstance(r.target(), opcua_node_t):
-        log(self, "Reference to " + str(r.target()) + " is not a node. It has been removed.", LOG_LEVEL_WARN)
+        logger.warn("Reference to " + str(r.target()) + " is not a node. It has been removed.")
       else:
       else:
         tmp.append(r)
         tmp.append(r)
     self.__node_references__ = tmp
     self.__node_references__ = tmp
@@ -524,12 +526,12 @@ class opcua_node_t:
     tmp = []
     tmp = []
     for r in self.getInverseReferences():
     for r in self.getInverseReferences():
       if not isinstance(r.target(), opcua_node_t):
       if not isinstance(r.target(), opcua_node_t):
-        log(self, "Invers reference to " + str(r.target()) + " does not reference a real node. It has been removed.", LOG_LEVEL_WARN)
+        logger.warn("Invers reference to " + str(r.target()) + " does not reference a real node. It has been removed.")
       else:
       else:
         if r.target().hasReferenceTarget(self):
         if r.target().hasReferenceTarget(self):
           tmp.append(r)
           tmp.append(r)
         else:
         else:
-          log(self, "Node " + str(self.id()) + " was falsely under the impression that it is referenced by " + str(r.target().id()), LOG_LEVEL_WARN)
+          logger.warn("Node " + str(self.id()) + " was falsely under the impression that it is referenced by " + str(r.target().id()))
     self.__node_referencedBy__ = tmp
     self.__node_referencedBy__ = tmp
 
 
     # Remove references from inverse list if we can reach this not "the regular way"
     # Remove references from inverse list if we can reach this not "the regular way"
@@ -539,7 +541,7 @@ class opcua_node_t:
       if not self.hasReferenceTarget(r.target()):
       if not self.hasReferenceTarget(r.target()):
         tmp.append(r)
         tmp.append(r)
       else:
       else:
-        log(self, "Removing unnecessary inverse reference to " + str(r.target.id()))
+        logger.debug("Removing unnecessary inverse reference to " + str(r.target.id()))
     self.__node_referencedBy__ = tmp
     self.__node_referencedBy__ = tmp
 
 
     return self.sanitizeSubType()
     return self.sanitizeSubType()
@@ -629,7 +631,7 @@ class opcua_node_t:
 
 
   def printXML(self):
   def printXML(self):
     pass
     pass
-  
+
   def printOpen62541CCode_SubtypeEarly(self, bootstrapping = True):
   def printOpen62541CCode_SubtypeEarly(self, bootstrapping = True):
     """ printOpen62541CCode_SubtypeEarly
     """ printOpen62541CCode_SubtypeEarly
 
 
@@ -637,11 +639,11 @@ class opcua_node_t:
         the actual UA_Server_addNode or UA_NodeStore_insert calls.
         the actual UA_Server_addNode or UA_NodeStore_insert calls.
     """
     """
     return []
     return []
-  
+
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
     """ printOpen62541CCode_Subtype
     """ printOpen62541CCode_Subtype
 
 
-        Appends node type specific information to the nodes  UA_Server_addNode 
+        Appends node type specific information to the nodes  UA_Server_addNode
         or UA_NodeStore_insert calls.
         or UA_NodeStore_insert calls.
     """
     """
     return []
     return []
@@ -662,10 +664,10 @@ class opcua_node_t:
 
 
     # Just to be sure...
     # Just to be sure...
     if not (self in unPrintedNodes):
     if not (self in unPrintedNodes):
-      log(self, str(self) + " attempted to reprint already printed node " + str(self)+ ".", LOG_LEVEL_WARN)
+      logger.warn(str(self) + " attempted to reprint already printed node " + str(self)+ ".")
       return []
       return []
 
 
-    # If we are being passed a parent node by the namespace, use that for registering ourselves in the namespace   
+    # If we are being passed a parent node by the namespace, use that for registering ourselves in the namespace
     # Note: getFirstParentNode will return [parentNode, referenceToChild]
     # Note: getFirstParentNode will return [parentNode, referenceToChild]
     (parentNode, parentRef) = self.getFirstParentNode()
     (parentNode, parentRef) = self.getFirstParentNode()
     if not (parentNode in unPrintedNodes) and (parentNode != None) and (parentRef.referenceType() != None):
     if not (parentNode in unPrintedNodes) and (parentNode != None) and (parentRef.referenceType() != None):
@@ -691,13 +693,13 @@ class opcua_node_t:
       code.append("UA_RCU_LOCK();")
       code.append("UA_RCU_LOCK();")
       code.append("UA_NodeStore_insert(server->nodestore, (UA_Node*) " + self.getCodePrintableID() + ");")
       code.append("UA_NodeStore_insert(server->nodestore, (UA_Node*) " + self.getCodePrintableID() + ");")
       code.append("UA_RCU_UNLOCK();")
       code.append("UA_RCU_UNLOCK();")
-      
+
     # Try to print all references to nodes that already exist
     # Try to print all references to nodes that already exist
     # Note: we know the reference types exist, because the namespace class made sure they were
     # Note: we know the reference types exist, because the namespace class made sure they were
     #       the first ones being printed
     #       the first ones being printed
     tmprefs = []
     tmprefs = []
     for r in self.getReferences():
     for r in self.getReferences():
-      #log(self, "Checking if reference from " + str(r.parent()) + "can be created...", LOG_LEVEL_DEBUG)
+      #logger.debug("Checking if reference from " + str(r.parent()) + "can be created...")
       if not (r.target() in unPrintedNodes):
       if not (r.target() in unPrintedNodes):
         if r in unPrintedReferences:
         if r in unPrintedReferences:
           if (len(tmprefs) == 0):
           if (len(tmprefs) == 0):
@@ -712,12 +714,12 @@ class opcua_node_t:
     # not exist...
     # not exist...
     tmprefs = []
     tmprefs = []
     for r in unPrintedReferences:
     for r in unPrintedReferences:
-      #log(self, "Checking if another reference " + str(r.target()) + "can be created...", LOG_LEVEL_DEBUG)
+      #logger.debug("Checking if another reference " + str(r.target()) + "can be created...")
       if (r.target() == self) and not (r.parent() in unPrintedNodes):
       if (r.target() == self) and not (r.parent() in unPrintedNodes):
         if not isinstance(r.parent(), opcua_node_t):
         if not isinstance(r.parent(), opcua_node_t):
-          log(self, "Reference has no parent!", LOG_LEVEL_DEBUG)
+          logger.debug("Reference has no parent!")
         elif not isinstance(r.parent().id(), opcua_node_id_t):
         elif not isinstance(r.parent().id(), opcua_node_id_t):
-          log(self, "Parents nodeid is not a nodeID!", LOG_LEVEL_DEBUG)
+          logger.debug("Parents nodeid is not a nodeID!")
         else:
         else:
           if (len(tmprefs) == 0):
           if (len(tmprefs) == 0):
             code.append("//  Creating this node has resolved the following open references:")
             code.append("//  Creating this node has resolved the following open references:")
@@ -731,7 +733,7 @@ class opcua_node_t:
     if self in unPrintedNodes:
     if self in unPrintedNodes:
       # This is necessery to make printing work at all!
       # This is necessery to make printing work at all!
       unPrintedNodes.remove(self)
       unPrintedNodes.remove(self)
-    
+
     code.append("} while(0);")
     code.append("} while(0);")
     return code
     return code
 
 
@@ -770,7 +772,7 @@ class opcua_node_referenceType_t(opcua_node_t):
 
 
   def sanitizeSubType(self):
   def sanitizeSubType(self):
     if not isinstance(self.referenceType(), opcua_referencePointer_t):
     if not isinstance(self.referenceType(), opcua_referencePointer_t):
-      log(self, "ReferenceType " + str(self.referenceType()) + " of " + str(self.id()) + " is not a pointer (ReferenceType is manditory for references).", LOG_LEVEL_ERROR)
+      logger.error("ReferenceType " + str(self.referenceType()) + " of " + str(self.id()) + " is not a pointer (ReferenceType is mandatory for references).")
       self.__reference_referenceType__ = None
       self.__reference_referenceType__ = None
       return False
       return False
     return True
     return True
@@ -793,19 +795,19 @@ class opcua_node_referenceType_t(opcua_node_t):
           self.isAbstract(True)
           self.isAbstract(True)
         xmlelement.removeAttribute(at)
         xmlelement.removeAttribute(at)
       else:
       else:
-        log(self, "Don't know how to process attribute " + at + " (" + av + ")", LOG_LEVEL_ERROR)
+        logger.warn("Don't know how to process attribute " + at + " (" + av + ")")
 
 
     for x in xmlelement.childNodes:
     for x in xmlelement.childNodes:
       if x.nodeType == x.ELEMENT_NODE:
       if x.nodeType == x.ELEMENT_NODE:
         if x.tagName == "InverseName":
         if x.tagName == "InverseName":
           self.inverseName(str(unicode(x.firstChild.data)))
           self.inverseName(str(unicode(x.firstChild.data)))
         else:
         else:
-          log(self,  "Unprocessable XML Element: " + x.tagName, LOG_LEVEL_INFO)
+          logger.warn( "Unprocessable XML Element: " + x.tagName)
 
 
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
     code = []
     code = []
     codegen = open62541_MacroHelper()
     codegen = open62541_MacroHelper()
-    
+
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     if bootstrapping == False:
     if bootstrapping == False:
       typeDefs = self.getNamespace().getSubTypesOf() # defaults to TypeDefinition
       typeDefs = self.getNamespace().getSubTypesOf() # defaults to TypeDefinition
@@ -820,19 +822,19 @@ class opcua_node_referenceType_t(opcua_node_t):
             myTypeRef = ref
             myTypeRef = ref
             break
             break
       if myTypeRef==None:
       if myTypeRef==None:
-        log(self, str(self) + " failed to locate a type definition, assuming BaseDataType.", LOG_LEVEL_WARN)
+        logger.warn(str(self) + " failed to locate a type definition, assuming BaseDataType.")
         code.append("       // No valid typeDefinition found; assuming BaseDataType")
         code.append("       // No valid typeDefinition found; assuming BaseDataType")
         code.append("       UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE),")
         code.append("       UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE),")
       else:
       else:
         code.append("       " + codegen.getCreateExpandedNodeIDMacro(myTypeRef.target()) + ",")
         code.append("       " + codegen.getCreateExpandedNodeIDMacro(myTypeRef.target()) + ",")
         while myTypeRef in unPrintedReferences:
         while myTypeRef in unPrintedReferences:
           unPrintedReferences.remove(myTypeRef)
           unPrintedReferences.remove(myTypeRef)
-          
+
       code.append("       UA_LOCALIZEDTEXT(\"\",\"" + str(self.inverseName()) + "\"),");
       code.append("       UA_LOCALIZEDTEXT(\"\",\"" + str(self.inverseName()) + "\"),");
       code.append("       // FIXME: Missing, isAbstract")
       code.append("       // FIXME: Missing, isAbstract")
       code.append("       // FIXME: Missing, symmetric")
       code.append("       // FIXME: Missing, symmetric")
       return code
       return code
-    
+
     if self.isAbstract():
     if self.isAbstract():
       code.append(self.getCodePrintableID() + "->isAbstract = true;")
       code.append(self.getCodePrintableID() + "->isAbstract = true;")
     if self.symmetric():
     if self.symmetric():
@@ -863,16 +865,16 @@ class opcua_node_object_t(opcua_node_t):
         # Silently ignore this one
         # Silently ignore this one
         xmlelement.removeAttribute(at)
         xmlelement.removeAttribute(at)
       else:
       else:
-        log(self, "Don't know how to process attribute " + at + " (" + av + ")", LOG_LEVEL_ERROR)
+        logger.error("Don't know how to process attribute " + at + " (" + av + ")")
 
 
     for x in xmlelement.childNodes:
     for x in xmlelement.childNodes:
       if x.nodeType == x.ELEMENT_NODE:
       if x.nodeType == x.ELEMENT_NODE:
-        log(self,  "Unprocessable XML Element: " + x.tagName, LOG_LEVEL_INFO)
+        logger.info( "Unprocessable XML Element: " + x.tagName)
 
 
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
     code = []
     code = []
     codegen = open62541_MacroHelper()
     codegen = open62541_MacroHelper()
-      
+
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     if bootstrapping == False:
     if bootstrapping == False:
       typeDefs = self.getNamespace().getSubTypesOf() # defaults to TypeDefinition
       typeDefs = self.getNamespace().getSubTypesOf() # defaults to TypeDefinition
@@ -887,17 +889,17 @@ class opcua_node_object_t(opcua_node_t):
             myTypeRef = ref
             myTypeRef = ref
             break
             break
       if myTypeRef==None:
       if myTypeRef==None:
-        log(self, str(self) + " failed to locate a type definition, assuming BaseObjectType.", LOG_LEVEL_WARN)
+        logger.warn(str(self) + " failed to locate a type definition, assuming BaseObjectType.")
         code.append("       // No valid typeDefinition found; assuming BaseObjectType")
         code.append("       // No valid typeDefinition found; assuming BaseObjectType")
         code.append("       UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),")
         code.append("       UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),")
       else:
       else:
         code.append("       " + codegen.getCreateExpandedNodeIDMacro(myTypeRef.target()) + ",")
         code.append("       " + codegen.getCreateExpandedNodeIDMacro(myTypeRef.target()) + ",")
         while myTypeRef in unPrintedReferences:
         while myTypeRef in unPrintedReferences:
           unPrintedReferences.remove(myTypeRef)
           unPrintedReferences.remove(myTypeRef)
-      
+
       #FIXME: No event notifier in UA_Server_addNode call!
       #FIXME: No event notifier in UA_Server_addNode call!
       return code
       return code
-    
+
     # We are being bootstrapped! Add the raw attributes to the node.
     # We are being bootstrapped! Add the raw attributes to the node.
     code.append(self.getCodePrintableID() + "->eventNotifier = (UA_Byte) " + str(self.eventNotifier()) + ";")
     code.append(self.getCodePrintableID() + "->eventNotifier = (UA_Byte) " + str(self.eventNotifier()) + ";")
     return code
     return code
@@ -971,32 +973,32 @@ class opcua_node_variable_t(opcua_node_t):
 
 
   def sanitizeSubType(self):
   def sanitizeSubType(self):
     if not isinstance(self.dataType(), opcua_referencePointer_t):
     if not isinstance(self.dataType(), opcua_referencePointer_t):
-      log(self, "DataType " + str(self.dataType()) + " of " + str(self.id()) + " is not a pointer (DataType is manditory for variables).", LOG_LEVEL_ERROR)
+      logger.error("DataType " + str(self.dataType()) + " of " + str(self.id()) + " is not a pointer (DataType is mandatory for variables).")
       self.__dataType__ = None
       self.__dataType__ = None
       return False
       return False
 
 
     if not isinstance(self.dataType().target(), opcua_node_t):
     if not isinstance(self.dataType().target(), opcua_node_t):
-      log(self, "DataType " + str(self.dataType().target()) + " of " + str(self.id()) + " does not point to a node (DataType is manditory for variables).", LOG_LEVEL_ERROR)
+      logger.error("DataType " + str(self.dataType().target()) + " of " + str(self.id()) + " does not point to a node (DataType is mandatory for variables).")
       self.__dataType__ = None
       self.__dataType__ = None
       return False
       return False
     return True
     return True
 
 
   def allocateValue(self):
   def allocateValue(self):
     if not isinstance(self.dataType(), opcua_referencePointer_t):
     if not isinstance(self.dataType(), opcua_referencePointer_t):
-      log(self, "Variable " + self.browseName() + "/" + str(self.id()) + " does not reference a valid dataType.", LOG_LEVEL_ERROR)
+      logger.error("Variable " + self.browseName() + "/" + str(self.id()) + " does not reference a valid dataType.")
       return False
       return False
 
 
     if not isinstance(self.dataType().target(), opcua_node_dataType_t):
     if not isinstance(self.dataType().target(), opcua_node_dataType_t):
-      log(self, "Variable " + self.browseName() + "/" + str(self.id()) + " does not have a valid dataType reference.", LOG_LEVEL_ERROR)
+      logger.error("Variable " + self.browseName() + "/" + str(self.id()) + " does not have a valid dataType reference.")
       return False
       return False
 
 
     if not self.dataType().target().isEncodable():
     if not self.dataType().target().isEncodable():
-      log(self, "DataType for Variable " + self.browseName() + "/" + str(self.id()) + " is not encodable.", LOG_LEVEL_ERROR)
+      logger.error("DataType for Variable " + self.browseName() + "/" + str(self.id()) + " is not encodable.")
       return False
       return False
 
 
     # FIXME: Don't build at all or allocate "defaults"? I'm for not building at all.
     # FIXME: Don't build at all or allocate "defaults"? I'm for not building at all.
     if self.__xmlValueDef__ == None:
     if self.__xmlValueDef__ == None:
-      #log(self, "Variable " + self.browseName() + "/" + str(self.id()) + " is not initialized. No memory will be allocated.", LOG_LEVEL_WARN)
+      #logger.warn("Variable " + self.browseName() + "/" + str(self.id()) + " is not initialized. No memory will be allocated.")
       return False
       return False
 
 
     self.value(opcua_value_t(self))
     self.value(opcua_value_t(self))
@@ -1034,7 +1036,7 @@ class opcua_node_variable_t(opcua_node_t):
         # Silently ignore this one
         # Silently ignore this one
         xmlelement.removeAttribute(at)
         xmlelement.removeAttribute(at)
       else:
       else:
-        log(self, "Don't know how to process attribute " + at + " (" + av + ")", LOG_LEVEL_ERROR)
+        logger.error("Don't know how to process attribute " + at + " (" + av + ")")
 
 
     for x in xmlelement.childNodes:
     for x in xmlelement.childNodes:
       if x.nodeType == x.ELEMENT_NODE:
       if x.nodeType == x.ELEMENT_NODE:
@@ -1043,7 +1045,7 @@ class opcua_node_variable_t(opcua_node_t):
           # which can only be done if the namespace is linked.
           # which can only be done if the namespace is linked.
           # Store the Value for later parsing
           # Store the Value for later parsing
           self.__xmlValueDef__ = x
           self.__xmlValueDef__ = x
-          #log(self,  "Value description stored for later elaboration.", LOG_LEVEL_DEBUG)
+          #logger.debug( "Value description stored for later elaboration.")
         elif x.tagName == "DataType":
         elif x.tagName == "DataType":
           self.dataType(opcua_referencePointer_t(str(av), parentNode=self))
           self.dataType(opcua_referencePointer_t(str(av), parentNode=self))
           # dataType needs to be linked to a node once the namespace is read
           # dataType needs to be linked to a node once the namespace is read
@@ -1062,7 +1064,7 @@ class opcua_node_variable_t(opcua_node_t):
           if "true" in x.firstChild.data.lower():
           if "true" in x.firstChild.data.lower():
             self.historizing(True)
             self.historizing(True)
         else:
         else:
-          log(self,  "Unprocessable XML Element: " + x.tagName, LOG_LEVEL_INFO)
+          logger.info( "Unprocessable XML Element: " + x.tagName)
 
 
   def printOpen62541CCode_SubtypeEarly(self, bootstrapping = True):
   def printOpen62541CCode_SubtypeEarly(self, bootstrapping = True):
     code = []
     code = []
@@ -1078,11 +1080,11 @@ class opcua_node_variable_t(opcua_node_t):
       code.append("UA_Variant *" + self.getCodePrintableID() + "_variant = UA_alloca(sizeof(UA_Variant));")
       code.append("UA_Variant *" + self.getCodePrintableID() + "_variant = UA_alloca(sizeof(UA_Variant));")
       code.append("UA_Variant_init(" + self.getCodePrintableID() + "_variant);")
       code.append("UA_Variant_init(" + self.getCodePrintableID() + "_variant);")
     return code
     return code
-  
+
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
     code = []
     code = []
     codegen = open62541_MacroHelper()
     codegen = open62541_MacroHelper()
-    
+
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     if bootstrapping == False:
     if bootstrapping == False:
       code.append("       " + self.getCodePrintableID() + "_variant, ")
       code.append("       " + self.getCodePrintableID() + "_variant, ")
@@ -1091,7 +1093,7 @@ class opcua_node_variable_t(opcua_node_t):
       code.append("       // FIXME: missing userAccessLevel")
       code.append("       // FIXME: missing userAccessLevel")
       code.append("       // FIXME: missing valueRank")
       code.append("       // FIXME: missing valueRank")
       return code
       return code
-    
+
     if self.historizing():
     if self.historizing():
       code.append(self.getCodePrintableID() + "->historizing = true;")
       code.append(self.getCodePrintableID() + "->historizing = true;")
 
 
@@ -1145,15 +1147,15 @@ class opcua_node_method_t(opcua_node_t):
         # dataType needs to be linked to a node once the namespace is read
         # dataType needs to be linked to a node once the namespace is read
         self.getNamespace().linkLater(self.methodDeclaration())
         self.getNamespace().linkLater(self.methodDeclaration())
       else:
       else:
-        log(self, "Don't know how to process attribute " + at + " (" + av + ")", LOG_LEVEL_ERROR)
+        logger.error("Don't know how to process attribute " + at + " (" + av + ")")
 
 
     for x in xmlelement.childNodes:
     for x in xmlelement.childNodes:
       if x.nodeType == x.ELEMENT_NODE:
       if x.nodeType == x.ELEMENT_NODE:
-        log(self,  "Unprocessable XML Element: " + x.tagName, LOG_LEVEL_INFO)
+        logger.info( "Unprocessable XML Element: " + x.tagName)
 
 
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
     code = []
     code = []
-    
+
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     if bootstrapping == False:
     if bootstrapping == False:
       code.append("       // Note: in/outputArguments are added by attaching the variable nodes,")
       code.append("       // Note: in/outputArguments are added by attaching the variable nodes,")
@@ -1165,7 +1167,7 @@ class opcua_node_method_t(opcua_node_t):
       code.append("       // FIXME: Missing executable")
       code.append("       // FIXME: Missing executable")
       code.append("       // FIXME: Missing userExecutable")
       code.append("       // FIXME: Missing userExecutable")
       return code
       return code
-    
+
     # UA_False is default for booleans on _init()
     # UA_False is default for booleans on _init()
     if self.executable():
     if self.executable():
       code.append(self.getCodePrintableID() + "->executable = true;")
       code.append(self.getCodePrintableID() + "->executable = true;")
@@ -1193,16 +1195,16 @@ class opcua_node_objectType_t(opcua_node_t):
           self.isAbstract(False)
           self.isAbstract(False)
         xmlelement.removeAttribute(at)
         xmlelement.removeAttribute(at)
       else:
       else:
-        log(self, "Don't know how to process attribute " + at + " (" + av + ")", LOG_LEVEL_ERROR)
+        logger.error("Don't know how to process attribute " + at + " (" + av + ")")
 
 
     for x in xmlelement.childNodes:
     for x in xmlelement.childNodes:
       if x.nodeType == x.ELEMENT_NODE:
       if x.nodeType == x.ELEMENT_NODE:
-        log(self,  "Unprocessable XML Element: " + x.tagName, LOG_LEVEL_INFO)
+        logger.info( "Unprocessable XML Element: " + x.tagName)
 
 
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
     code = []
     code = []
     codegen = open62541_MacroHelper();
     codegen = open62541_MacroHelper();
-    
+
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     if bootstrapping == False:
     if bootstrapping == False:
       typeDefs = self.getNamespace().getSubTypesOf() # defaults to TypeDefinition
       typeDefs = self.getNamespace().getSubTypesOf() # defaults to TypeDefinition
@@ -1217,7 +1219,7 @@ class opcua_node_objectType_t(opcua_node_t):
             myTypeRef = ref
             myTypeRef = ref
             break
             break
       if myTypeRef==None:
       if myTypeRef==None:
-        log(self, str(self) + " failed to locate a type definition, assuming BaseObjectType.", LOG_LEVEL_WARN)
+        logger.warn(str(self) + " failed to locate a type definition, assuming BaseObjectType.")
         code.append("       // No valid typeDefinition found; assuming BaseObjectType")
         code.append("       // No valid typeDefinition found; assuming BaseObjectType")
         code.append("       UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),")
         code.append("       UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),")
       else:
       else:
@@ -1225,12 +1227,12 @@ class opcua_node_objectType_t(opcua_node_t):
         while myTypeRef in unPrintedReferences:
         while myTypeRef in unPrintedReferences:
           code.append("       // removed " + str(myTypeRef))
           code.append("       // removed " + str(myTypeRef))
           unPrintedReferences.remove(myTypeRef)
           unPrintedReferences.remove(myTypeRef)
-      
+
       if (self.isAbstract()):
       if (self.isAbstract()):
         code.append("       true,")
         code.append("       true,")
       else:
       else:
         code.append("       false,")
         code.append("       false,")
-    
+
     # Fallback mode for bootstrapping
     # Fallback mode for bootstrapping
     if (self.isAbstract()):
     if (self.isAbstract()):
       code.append(self.getCodePrintableID() + "->isAbstract = true;")
       code.append(self.getCodePrintableID() + "->isAbstract = true;")
@@ -1255,7 +1257,7 @@ class opcua_node_variableType_t(opcua_node_t):
     self.__xmlDefinition__ = None
     self.__xmlDefinition__ = None
 
 
   def value(self, data=None):
   def value(self, data=None):
-    log(self, "Setting data not implemented!", LOG_LEVEL_ERROR)
+    logger.error("Setting data not implemented!")
 
 
   def dataType(self, data=None):
   def dataType(self, data=None):
     if data != None:
     if data != None:
@@ -1282,15 +1284,15 @@ class opcua_node_variableType_t(opcua_node_t):
     # but if it does have a node set, it must obviously be a valid node
     # but if it does have a node set, it must obviously be a valid node
     if not self.dataType() != None:
     if not self.dataType() != None:
       if not isinstance(self.dataType(), opcua_referencePointer_t):
       if not isinstance(self.dataType(), opcua_referencePointer_t):
-        log(self, "DataType attribute of " + str(self.id()) + " is not a pointer", LOG_LEVEL_ERROR)
+        logger.error("DataType attribute of " + str(self.id()) + " is not a pointer")
         return False
         return False
       else:
       else:
         if not isinstance(self.dataType().target(), opcua_node_t):
         if not isinstance(self.dataType().target(), opcua_node_t):
-          log(self, "DataType attribute of " + str(self.id()) + " does not point to a node", LOG_LEVEL_ERROR)
+          logger.error("DataType attribute of " + str(self.id()) + " does not point to a node")
           return False
           return False
     else:
     else:
       # FIXME: It's unclear wether this is ok or not.
       # FIXME: It's unclear wether this is ok or not.
-      log(self, "DataType attribute of variableType " + str(self.id()) + " is not defined.", LOG_LEVEL_WARN)
+      logger.warn("DataType attribute of variableType " + str(self.id()) + " is not defined.")
       return False
       return False
 
 
   def parseXMLSubType(self, xmlelement):
   def parseXMLSubType(self, xmlelement):
@@ -1304,22 +1306,22 @@ class opcua_node_variableType_t(opcua_node_t):
       elif at == "ValueRank":
       elif at == "ValueRank":
         self.valueRank(int(av))
         self.valueRank(int(av))
         if self.valueRank() != -1:
         if self.valueRank() != -1:
-          log(self, "Array's or matrices are only permitted in variables and not supported for variableTypes. This attribute will effectively be ignored.", LOG_LEVEL_WARN)
+          logger.warn("Array's or matrices are only permitted in variables and not supported for variableTypes. This attribute (" + at + "=" + av + ") will effectively be ignored.")
         xmlelement.removeAttribute(at)
         xmlelement.removeAttribute(at)
       elif at == "DataType":
       elif at == "DataType":
         self.dataType(opcua_referencePointer_t(str(av), parentNode=self))
         self.dataType(opcua_referencePointer_t(str(av), parentNode=self))
         # dataType needs to be linked to a node once the namespace is read
         # dataType needs to be linked to a node once the namespace is read
         self.getNamespace().linkLater(self.dataType())
         self.getNamespace().linkLater(self.dataType())
       else:
       else:
-        log(self, "Don't know how to process attribute " + at + " (" + av + ")", LOG_LEVEL_ERROR)
+        logger.error("Don't know how to process attribute " + at + " (" + av + ")")
 
 
     for x in xmlelement.childNodes:
     for x in xmlelement.childNodes:
       if x.nodeType == x.ELEMENT_NODE:
       if x.nodeType == x.ELEMENT_NODE:
         if x.tagName == "Definition":
         if x.tagName == "Definition":
           self.__xmlDefinition__ = x
           self.__xmlDefinition__ = x
-          log(self,  "Definition stored for future processing", LOG_LEVEL_DEBUG)
+          logger.debug( "Definition stored for future processing")
         else:
         else:
-          log(self,  "Unprocessable XML Element: " + x.tagName, LOG_LEVEL_INFO)
+          logger.info( "Unprocessable XML Element: " + x.tagName)
 
 
   def printOpen62541CCode_SubtypeEarly(self, bootstrapping = True):
   def printOpen62541CCode_SubtypeEarly(self, bootstrapping = True):
     code = []
     code = []
@@ -1335,11 +1337,11 @@ class opcua_node_variableType_t(opcua_node_t):
       code.append("UA_Variant *" + self.getCodePrintableID() + "_variant = UA_alloca(sizeof(UA_Variant));")
       code.append("UA_Variant *" + self.getCodePrintableID() + "_variant = UA_alloca(sizeof(UA_Variant));")
       code.append("UA_Variant_init(" + self.getCodePrintableID() + "_variant);")
       code.append("UA_Variant_init(" + self.getCodePrintableID() + "_variant);")
     return code
     return code
-  
+
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
     code = []
     code = []
     codegen = open62541_MacroHelper()
     codegen = open62541_MacroHelper()
-    
+
     if bootstrapping == False:
     if bootstrapping == False:
       code.append("       " + self.getCodePrintableID() + "_variant, ")
       code.append("       " + self.getCodePrintableID() + "_variant, ")
       code.append("       " + str(self.valueRank()) + ",")
       code.append("       " + str(self.valueRank()) + ",")
@@ -1348,12 +1350,12 @@ class opcua_node_variableType_t(opcua_node_t):
       else:
       else:
         code.append("       false,")
         code.append("       false,")
       return code
       return code
-    
+
     if (self.isAbstract()):
     if (self.isAbstract()):
       code.append(self.getCodePrintableID() + "->isAbstract = true;")
       code.append(self.getCodePrintableID() + "->isAbstract = true;")
     else:
     else:
       code.append(self.getCodePrintableID() + "->isAbstract = false;")
       code.append(self.getCodePrintableID() + "->isAbstract = false;")
-    
+
     # The variant is guaranteed to exist by SubtypeEarly()
     # The variant is guaranteed to exist by SubtypeEarly()
     code.append(self.getCodePrintableID() + "->value.variant.value = *" + self.getCodePrintableID() + "_variant;")
     code.append(self.getCodePrintableID() + "->value.variant.value = *" + self.getCodePrintableID() + "_variant;")
     code.append(self.getCodePrintableID() + "->valueSource = UA_VALUESOURCE_VARIANT;")
     code.append(self.getCodePrintableID() + "->valueSource = UA_VALUESOURCE_VARIANT;")
@@ -1482,22 +1484,22 @@ class opcua_node_dataType_t(opcua_node_t):
 
 
     if self.__encodingBuilt__ == True:
     if self.__encodingBuilt__ == True:
       if self.isEncodable():
       if self.isEncodable():
-        log(self, prefix + str(self.__baseTypeEncoding__) + " (already analyzed)")
+        logger.debug(prefix + str(self.__baseTypeEncoding__) + " (already analyzed)")
       else:
       else:
-        log(self,  prefix + str(self.__baseTypeEncoding__) + "(already analyzed, not encodable!)")
+        logger.debug( prefix + str(self.__baseTypeEncoding__) + "(already analyzed, not encodable!)")
       return self.__baseTypeEncoding__
       return self.__baseTypeEncoding__
     self.__encodingBuilt__ = True # signify that we have attempted to built this type
     self.__encodingBuilt__ = True # signify that we have attempted to built this type
     self.__encodable__ = True
     self.__encodable__ = True
 
 
     if indent==0:
     if indent==0:
-      log(self, "Parsing DataType " + self.browseName() + " (" + str(self.id()) + ")")
+      logger.debug("Parsing DataType " + self.browseName() + " (" + str(self.id()) + ")")
 
 
     if proxy.isBuiltinByString(self.browseName()):
     if proxy.isBuiltinByString(self.browseName()):
       self.__baseTypeEncoding__ = [self.browseName()]
       self.__baseTypeEncoding__ = [self.browseName()]
       self.__encodable__ = True
       self.__encodable__ = True
-      log(self,  prefix + self.browseName() + "*")
-      log(self, "Encodable as: " + str(self.__baseTypeEncoding__))
-      log(self, "")
+      logger.debug( prefix + self.browseName() + "*")
+      logger.debug("Encodable as: " + str(self.__baseTypeEncoding__))
+      logger.debug("")
       return self.__baseTypeEncoding__
       return self.__baseTypeEncoding__
 
 
     if self.__xmlDefinition__ == None:
     if self.__xmlDefinition__ == None:
@@ -1505,7 +1507,7 @@ class opcua_node_dataType_t(opcua_node_t):
       for ref in self.getReferences():
       for ref in self.getReferences():
         if "hassubtype" in ref.referenceType().browseName().lower() and ref.isForward() == False:
         if "hassubtype" in ref.referenceType().browseName().lower() and ref.isForward() == False:
           if isinstance(ref.target(), opcua_node_dataType_t):
           if isinstance(ref.target(), opcua_node_dataType_t):
-            log(self,  prefix + "Attempting definition using supertype " + ref.target().browseName() + " for DataType " + " " + self.browseName())
+            logger.debug( prefix + "Attempting definition using supertype " + ref.target().browseName() + " for DataType " + " " + self.browseName())
             subenc = ref.target().buildEncoding(indent=indent+1)
             subenc = ref.target().buildEncoding(indent=indent+1)
             if not ref.target().isEncodable():
             if not ref.target().isEncodable():
               self.__encodable__ = False
               self.__encodable__ = False
@@ -1513,15 +1515,15 @@ class opcua_node_dataType_t(opcua_node_t):
             else:
             else:
               self.__baseTypeEncoding__ = self.__baseTypeEncoding__ + [self.browseName(), subenc, 0]
               self.__baseTypeEncoding__ = self.__baseTypeEncoding__ + [self.browseName(), subenc, 0]
       if len(self.__baseTypeEncoding__) == 0:
       if len(self.__baseTypeEncoding__) == 0:
-        log(self, prefix + "No viable definition for " + self.browseName() + " " + str(self.id()) + " found.")
+        logger.debug(prefix + "No viable definition for " + self.browseName() + " " + str(self.id()) + " found.")
         self.__encodable__ = False
         self.__encodable__ = False
 
 
       if indent==0:
       if indent==0:
         if not self.__encodable__:
         if not self.__encodable__:
-          log(self, "Not encodable (partial): " + str(self.__baseTypeEncoding__))
+          logger.debug("Not encodable (partial): " + str(self.__baseTypeEncoding__))
         else:
         else:
-          log(self, "Encodable as: " + str(self.__baseTypeEncoding__))
-        log(self,  "")
+          logger.debug("Encodable as: " + str(self.__baseTypeEncoding__))
+        logger.debug( "")
 
 
       return self.__baseTypeEncoding__
       return self.__baseTypeEncoding__
 
 
@@ -1552,14 +1554,14 @@ class opcua_node_dataType_t(opcua_node_t):
             isSubType = False
             isSubType = False
           elif at == "ValueRank":
           elif at == "ValueRank":
             hasValueRank = int(av)
             hasValueRank = int(av)
-            log(self, "Arrays or matrices (ValueRank) are not supported for datatypes. This DT will become scalar.", LOG_LEVEL_WARN)
+            logger.warn("Arrays or matrices (ValueRank) are not supported for datatypes. This DT will become scalar.")
           else:
           else:
-            log(self, "Unknown Field Attribute " + str(at), LOG_LEVEL_WARN)
+            logger.warn("Unknown Field Attribute " + str(at))
         # This can either be an enumeration OR a structure, not both.
         # This can either be an enumeration OR a structure, not both.
         # Figure out which of the dictionaries gets the newly read value pair
         # Figure out which of the dictionaries gets the newly read value pair
         if isEnum == isSubType:
         if isEnum == isSubType:
           # This is an error
           # This is an error
-          log(self, "DataType contains both enumeration and subtype (or neither)", LOG_LEVEL_WARN)
+          logger.warn("DataType contains both enumeration and subtype (or neither)")
           self.__encodable__ = False
           self.__encodable__ = False
           break
           break
         elif isEnum:
         elif isEnum:
@@ -1572,7 +1574,7 @@ class opcua_node_dataType_t(opcua_node_t):
           dtnode = self.getNamespace().getNodeByIDString(fdtype)
           dtnode = self.getNamespace().getNodeByIDString(fdtype)
           if dtnode == None:
           if dtnode == None:
             # Node found in datatype element is invalid
             # Node found in datatype element is invalid
-            log(self,  prefix + fname + " ?? " + av + " ??")
+            logger.debug( prefix + fname + " ?? " + av + " ??")
             self.__encodable__ = False
             self.__encodable__ = False
           else:
           else:
             # The node in the datatype element was found. we inherit its encoding,
             # The node in the datatype element was found. we inherit its encoding,
@@ -1581,7 +1583,7 @@ class opcua_node_dataType_t(opcua_node_t):
             if hasValueRank < 0:
             if hasValueRank < 0:
               hasValueRank = 0
               hasValueRank = 0
             fdtype = str(dtnode.browseName()) + "+"*hasValueRank
             fdtype = str(dtnode.browseName()) + "+"*hasValueRank
-            log(self,  prefix + fname + " : " + fdtype + " -> " + str(dtnode.id()))
+            logger.debug( prefix + fname + " : " + fdtype + " -> " + str(dtnode.id()))
             subenc = dtnode.buildEncoding(indent=indent+1)
             subenc = dtnode.buildEncoding(indent=indent+1)
             self.__baseTypeEncoding__ = self.__baseTypeEncoding__ + [[fname, subenc, hasValueRank]]
             self.__baseTypeEncoding__ = self.__baseTypeEncoding__ + [[fname, subenc, hasValueRank]]
             if not dtnode.isEncodable():
             if not dtnode.isEncodable():
@@ -1601,17 +1603,17 @@ class opcua_node_dataType_t(opcua_node_t):
       self.__baseTypeEncoding__ = self.__baseTypeEncoding__ + ['Int32']
       self.__baseTypeEncoding__ = self.__baseTypeEncoding__ + ['Int32']
       self.__definition__ = enumDict
       self.__definition__ = enumDict
       self.__isEnum__ = True
       self.__isEnum__ = True
-      log(self,  prefix+"Int32* -> enumeration with dictionary " + str(enumDict) + " encodable " + str(self.__encodable__))
+      logger.debug( prefix+"Int32* -> enumeration with dictionary " + str(enumDict) + " encodable " + str(self.__encodable__))
       return self.__baseTypeEncoding__
       return self.__baseTypeEncoding__
 
 
     if indent==0:
     if indent==0:
       if not self.__encodable__:
       if not self.__encodable__:
-        log(self,  "Not encodable (partial): " + str(self.__baseTypeEncoding__))
+        logger.debug( "Not encodable (partial): " + str(self.__baseTypeEncoding__))
       else:
       else:
-        log(self,  "Encodable as: " + str(self.__baseTypeEncoding__))
+        logger.debug( "Encodable as: " + str(self.__baseTypeEncoding__))
         self.__isEnum__ = False
         self.__isEnum__ = False
         self.__definition__ = typeDict
         self.__definition__ = typeDict
-      log(self,  "")
+      logger.debug( "")
     return self.__baseTypeEncoding__
     return self.__baseTypeEncoding__
 
 
   def parseXMLSubType(self, xmlelement):
   def parseXMLSubType(self, xmlelement):
@@ -1628,15 +1630,15 @@ class opcua_node_dataType_t(opcua_node_t):
           self.isAbstract(False)
           self.isAbstract(False)
         xmlelement.removeAttribute(at)
         xmlelement.removeAttribute(at)
       else:
       else:
-        log(self, "Don't know how to process attribute " + at + " (" + av + ")", LOG_LEVEL_WARN)
+        logger.warn("Don't know how to process attribute " + at + " (" + av + ")")
 
 
     for x in xmlelement.childNodes:
     for x in xmlelement.childNodes:
       if x.nodeType == x.ELEMENT_NODE:
       if x.nodeType == x.ELEMENT_NODE:
         if x.tagName == "Definition":
         if x.tagName == "Definition":
           self.__xmlDefinition__ = x
           self.__xmlDefinition__ = x
-          #log(self,  "Definition stored for future processing", LOG_LEVEL_DEBUG)
+          #logger.debug( "Definition stored for future processing")
         else:
         else:
-          log(self,  "Unprocessable XML Element: " + x.tagName, LOG_LEVEL_WARN)
+          logger.warn( "Unprocessable XML Element: " + x.tagName)
 
 
   def encodedTypeId(self):
   def encodedTypeId(self):
     """ Returns a number of the builtin Type that should be used
     """ Returns a number of the builtin Type that should be used
@@ -1669,7 +1671,7 @@ class opcua_node_dataType_t(opcua_node_t):
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
     code = []
     code = []
     codegen = open62541_MacroHelper()
     codegen = open62541_MacroHelper()
-    
+
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     if bootstrapping == False:
     if bootstrapping == False:
       typeDefs = self.getNamespace().getSubTypesOf() # defaults to TypeDefinition
       typeDefs = self.getNamespace().getSubTypesOf() # defaults to TypeDefinition
@@ -1684,20 +1686,20 @@ class opcua_node_dataType_t(opcua_node_t):
             myTypeRef = ref
             myTypeRef = ref
             break
             break
       if myTypeRef==None:
       if myTypeRef==None:
-        log(self, str(self) + " failed to locate a type definition, assuming BaseDataType.", LOG_LEVEL_WARN)
+        logger.warn(str(self) + " failed to locate a type definition, assuming BaseDataType.")
         code.append("       // No valid typeDefinition found; assuming BaseDataType")
         code.append("       // No valid typeDefinition found; assuming BaseDataType")
         code.append("       UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE),")
         code.append("       UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE),")
       else:
       else:
         code.append("       " + codegen.getCreateExpandedNodeIDMacro(myTypeRef.target()) + ",")
         code.append("       " + codegen.getCreateExpandedNodeIDMacro(myTypeRef.target()) + ",")
         while myTypeRef in unPrintedReferences:
         while myTypeRef in unPrintedReferences:
           unPrintedReferences.remove(myTypeRef)
           unPrintedReferences.remove(myTypeRef)
-      
+
       if (self.isAbstract()):
       if (self.isAbstract()):
         code.append("       true,")
         code.append("       true,")
       else:
       else:
         code.append("       false,")
         code.append("       false,")
       return code
       return code
-    
+
     if (self.isAbstract()):
     if (self.isAbstract()):
       code.append(self.getCodePrintableID() + "->isAbstract = true;")
       code.append(self.getCodePrintableID() + "->isAbstract = true;")
     else:
     else:
@@ -1725,16 +1727,16 @@ class opcua_node_view_t(opcua_node_t):
 
 
   def parseXMLSubtype(self, xmlelement):
   def parseXMLSubtype(self, xmlelement):
     for (at, av) in xmlelement.attributes.items():
     for (at, av) in xmlelement.attributes.items():
-      log(self, "Don't know how to process attribute " + at + " (" + av + ")", LOG_LEVEL_ERROR)
+      logger.error("Don't know how to process attribute " + at + " (" + av + ")")
 
 
     for x in xmlelement.childNodes:
     for x in xmlelement.childNodes:
       if x.nodeType == x.ELEMENT_NODE:
       if x.nodeType == x.ELEMENT_NODE:
-        log(self,  "Unprocessable XML Element: " + x.tagName, LOG_LEVEL_INFO)
+        logger.info( "Unprocessable XML Element: " + x.tagName)
 
 
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
   def printOpen62541CCode_Subtype(self, unPrintedReferences=[], bootstrapping = True):
     code = []
     code = []
     codegen = open62541_MacroHelper()
     codegen = open62541_MacroHelper()
-    
+
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     # Detect if this is bootstrapping or if we are attempting to use userspace...
     if bootstrapping == False:
     if bootstrapping == False:
       typeDefs = self.getNamespace().getSubTypesOf() # defaults to TypeDefinition
       typeDefs = self.getNamespace().getSubTypesOf() # defaults to TypeDefinition
@@ -1749,18 +1751,18 @@ class opcua_node_view_t(opcua_node_t):
             myTypeRef = ref
             myTypeRef = ref
             break
             break
       if myTypeRef==None:
       if myTypeRef==None:
-        log(self, str(self) + " failed to locate a type definition, assuming BaseViewType.", LOG_LEVEL_WARN)
+        logger.warn(str(self) + " failed to locate a type definition, assuming BaseViewType.")
         code.append("       // No valid typeDefinition found; assuming BaseViewType")
         code.append("       // No valid typeDefinition found; assuming BaseViewType")
         code.append("       UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEViewTYPE),")
         code.append("       UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEViewTYPE),")
       else:
       else:
         code.append("       " + codegen.getCreateExpandedNodeIDMacro(myTypeRef.target()) + ",")
         code.append("       " + codegen.getCreateExpandedNodeIDMacro(myTypeRef.target()) + ",")
         while myTypeRef in unPrintedReferences:
         while myTypeRef in unPrintedReferences:
           unPrintedReferences.remove(myTypeRef)
           unPrintedReferences.remove(myTypeRef)
-          
+
       code.append("       // FIXME: Missing eventNotifier")
       code.append("       // FIXME: Missing eventNotifier")
       code.append("       // FIXME: Missing containsNoLoops")
       code.append("       // FIXME: Missing containsNoLoops")
       return code
       return code
-    
+
     if self.containsNoLoops():
     if self.containsNoLoops():
       code.append(self.getCodePrintableID() + "->containsNoLoops = true;")
       code.append(self.getCodePrintableID() + "->containsNoLoops = true;")
     else:
     else: