bacnet/bacnet.py
changeset 2250 86f61c4dfe76
parent 2020 6dddf3070806
child 2309 d8fb90a2e11f
--- a/bacnet/bacnet.py	Wed Aug 08 10:17:19 2018 +0200
+++ b/bacnet/bacnet.py	Wed Aug 08 13:26:48 2018 +0200
@@ -19,51 +19,53 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#    
+#
 # This code is made available on the understanding that it will not be
 # used in safety-critical situations without a full and competent review.
 
-
-
-import os, sys
+from __future__ import absolute_import
+
+import os
 from collections import Counter
-from datetime    import datetime
-
-base_folder           = os.path.split(os.path.dirname(os.path.realpath(__file__)))[0]
-base_folder           = os.path.join(base_folder, "..")
-BacnetPath            = os.path.join(base_folder, "BACnet")
-BacnetLibraryPath     = os.path.join(BacnetPath, "lib")
-BacnetIncludePath     = os.path.join(BacnetPath, "include")
+from datetime import datetime
+import pickle
+
+import wx
+
+from bacnet.BacnetSlaveEditor import *
+from bacnet.BacnetSlaveEditor import ObjectProperties
+from PLCControler import LOCATION_CONFNODE, LOCATION_VAR_MEMORY
+
+base_folder = os.path.split(
+    os.path.dirname(os.path.realpath(__file__)))[0]
+base_folder = os.path.join(base_folder, "..")
+BacnetPath = os.path.join(base_folder, "BACnet")
+BacnetLibraryPath = os.path.join(BacnetPath, "lib")
+BacnetIncludePath = os.path.join(BacnetPath, "include")
 BacnetIncludePortPath = os.path.join(BacnetPath, "ports")
 BacnetIncludePortPath = os.path.join(BacnetIncludePortPath, "linux")
 
-import wx
-import pickle
-
-from BacnetSlaveEditor import *
-from BacnetSlaveEditor import ObjectProperties
-from ConfigTreeNode    import ConfigTreeNode
-from PLCControler      import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
-
 # Parameters to be monkey patched in beremiz customizations
-BACNET_VENDOR_ID = 9999 
+BACNET_VENDOR_ID = 9999
 BACNET_VENDOR_NAME = "Beremiz.org"
 BACNET_DEVICE_MODEL_NAME = "Beremiz PLC"
 
-###################################################
-###################################################
-#                                                 #
-#           S L A V E    D E V I C E              # 
-#                                                 #
-###################################################
-###################################################
+#
+#
+#
+# S L A V E    D E V I C E              #
+#
+#
+#
 
 # NOTE: Objects of class _BacnetSlavePlug are never instantiated directly.
 #       The objects are instead instantiated from class FinalCTNClass
 #       FinalCTNClass inherits from: - ConfigTreeNode
 #                                    - The tree node plug (in our case _BacnetSlavePlug)
-#class _BacnetSlavePlug:
-class RootClass:
+# class _BacnetSlavePlug:
+
+
+class RootClass(object):
     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <xsd:element name="BACnetServerNode">
@@ -77,7 +79,7 @@
                 </xsd:restriction>
             </xsd:simpleType>
           </xsd:attribute>
-          <xsd:attribute name="BACnet_Communication_Control_Password"     
+          <xsd:attribute name="BACnet_Communication_Control_Password"
                                                        type="xsd:string"  use="optional" default="Malba Tahan"/>
           <xsd:attribute name="BACnet_Device_ID"                          use="optional" default="0">
             <xsd:simpleType>
@@ -99,8 +101,7 @@
     #       so the Device instance ID is limited from 0 to 22^2-1 = 4194303
     #       However, 4194303 is reserved for special use (similar to NULL pointer), so last
     #       valid ID becomes 4194302
-    
-    
+
     # The class/object that will render the graphical interface to edit the
     #    BacnetSlavePlug's configuration parameters. The object of class BacnetSlaveEditorPlug
     #    will be instantiated by the ConfigTreeNode class.
@@ -117,17 +118,17 @@
     #       of classes ConfigTreeNode as well as FinalCTNClass (since they are always instantiated
     #       as a FinalCTNClass)
     EditorType = BacnetSlaveEditorPlug
-    
+
     # The following classes follow the model/viewer design pattern
     #
     # _BacnetSlavePlug       - contains the model (i.e. configuration parameters)
-    # BacnetSlaveEditorPlug  - contains the viewer (and editor, so it includes the 'controller' part of the 
+    # BacnetSlaveEditorPlug  - contains the viewer (and editor, so it includes the 'controller' part of the
     #                                    design pattern which in this case is not separated from the viewer)
     #
-    # The _BacnetSlavePlug      object is 'permanent', i.e. it exists as long as the beremiz project is open 
+    # The _BacnetSlavePlug      object is 'permanent', i.e. it exists as long as the beremiz project is open
     # The BacnetSlaveEditorPlug object is 'transient', i.e. it exists only while the editor is visible/open
     #                                                         in the editing panel. It is destoryed whenever
-    #                                                         the user closes the corresponding tab in the 
+    #                                                         the user closes the corresponding tab in the
     #                                                         editing panel, and a new object is created when
     #                                                         the editor is re-opened.
     #
@@ -136,9 +137,9 @@
     #                              and are therefore stored to a file)
     #
     # _BacnetSlavePlug contains:  AV_VarEditor, ...
-    #                             (these are the objects that implement a grid table to edit/view the 
+    #                             (these are the objects that implement a grid table to edit/view the
     #                              corresponding mode parameters)
-    #  
+    #
     #  Logic:
     #    - The xx_VarEditor classes inherit from wx.grid.Grid
     #    - The xx_ObjTable  classes inherit from wx.grid.PyGridTableBase
@@ -149,102 +150,117 @@
     #  Note that wx.grid.Grid is prepared to work with wx.grid.PyGridTableBase as the container of
     #  data that is displayed and edited in the Grid.
 
-    
     ConfNodeMethods = [
-        {"bitmap"  : "ExportSlave",
-         "name"    : _("Export slave"), 
-         "tooltip" : _("Export BACnet slave to EDE file"),
-         "method"  : "_ExportBacnetSlave"},
+        {"bitmap": "ExportSlave",
+         "name": _("Export slave"),
+         "tooltip": _("Export BACnet slave to EDE file"),
+         "method": "_ExportBacnetSlave"},
     ]
-    
+
     def __init__(self):
-        # Initialize the dictionary that stores the current configuration for the Analog/Digital/MultiValued Variables 
+        # Initialize the dictionary that stores the current configuration for the Analog/Digital/MultiValued Variables
         #   in this BACnet server.
         self.ObjTablesData = {}
-        self.ObjTablesData[ "AV_Obj"] = [] # Each list will contain an entry for each row in the xxxxVar grid!!
-        self.ObjTablesData[ "AO_Obj"] = [] #   Each entry/row will be a dictionary
-        self.ObjTablesData[ "AI_Obj"] = [] #     Each dictionary will contain all entries/data 
-        self.ObjTablesData[ "BV_Obj"] = [] #     for one row in the grid.
-        self.ObjTablesData[ "BO_Obj"] = [] # Same structure as explained above...
-        self.ObjTablesData[ "BI_Obj"] = [] # Same structure as explained above...
-        self.ObjTablesData["MSV_Obj"] = [] # Same structure as explained above...
-        self.ObjTablesData["MSO_Obj"] = [] # Same structure as explained above...
-        self.ObjTablesData["MSI_Obj"] = [] # Same structure as explained above...
-        
-        self.ObjTablesData["EDEfile_parm"] = {"next_EDE_file_version":1} 
-                                                # EDE files inlcude extra parameters (ex. file version)
-                                                # We would like to save the parameters the user configures
-                                                # so they are available the next time the user opens the project.
-                                                # Since this plugin is only storing the ObjTablesData[] dict
-                                                # to file, we add that info to this dictionary too.
-                                                # Yes, I know this is kind of a hack.
-        
+
+        # Each list will contain an entry for each row in the xxxxVar grid!!
+        #   Each entry/row will be a dictionary
+        #     Each dictionary will contain all entries/data
+        # for one row in the grid.
+
+        self.ObjTablesData["AV_Obj"] = []
+        self.ObjTablesData["AO_Obj"] = []
+        self.ObjTablesData["AI_Obj"] = []
+        self.ObjTablesData["BV_Obj"] = []
+        self.ObjTablesData["BO_Obj"] = []
+        self.ObjTablesData["BI_Obj"] = []
+        self.ObjTablesData["MSV_Obj"] = []
+        self.ObjTablesData["MSO_Obj"] = []
+        self.ObjTablesData["MSI_Obj"] = []
+
+        self.ObjTablesData["EDEfile_parm"] = {"next_EDE_file_version": 1}
+
+        # EDE files inlcude extra parameters (ex. file version)
+        # We would like to save the parameters the user configures
+        # so they are available the next time the user opens the project.
+        # Since this plugin is only storing the ObjTablesData[] dict
+        # to file, we add that info to this dictionary too.
+        # Yes, I know this is kind of a
+        # hack.
+
         filepath = self.GetFileName()
-        if(os.path.isfile(filepath)):
+        if os.path.isfile(filepath):
             self.LoadFromFile(filepath)
 
         self.ObjTables = {}
-        self.ObjTables[ "AV_Obj"] = ObjectTable(self, self.ObjTablesData[ "AV_Obj"],  AVObject)
-        self.ObjTables[ "AO_Obj"] = ObjectTable(self, self.ObjTablesData[ "AO_Obj"],  AOObject)
-        self.ObjTables[ "AI_Obj"] = ObjectTable(self, self.ObjTablesData[ "AI_Obj"],  AIObject)
-        self.ObjTables[ "BV_Obj"] = ObjectTable(self, self.ObjTablesData[ "BV_Obj"],  BVObject)
-        self.ObjTables[ "BO_Obj"] = ObjectTable(self, self.ObjTablesData[ "BO_Obj"],  BOObject)
-        self.ObjTables[ "BI_Obj"] = ObjectTable(self, self.ObjTablesData[ "BI_Obj"],  BIObject)
-        self.ObjTables["MSV_Obj"] = ObjectTable(self, self.ObjTablesData["MSV_Obj"], MSVObject)
-        self.ObjTables["MSO_Obj"] = ObjectTable(self, self.ObjTablesData["MSO_Obj"], MSOObject)
-        self.ObjTables["MSI_Obj"] = ObjectTable(self, self.ObjTablesData["MSI_Obj"], MSIObject)
-        #   list containing the data in the table <--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
-
-
-    ######################################
+        self.ObjTables["AV_Obj"] = ObjectTable(
+            self, self.ObjTablesData["AV_Obj"],  AVObject)
+        self.ObjTables["AO_Obj"] = ObjectTable(
+            self, self.ObjTablesData["AO_Obj"],  AOObject)
+        self.ObjTables["AI_Obj"] = ObjectTable(
+            self, self.ObjTablesData["AI_Obj"],  AIObject)
+        self.ObjTables["BV_Obj"] = ObjectTable(
+            self, self.ObjTablesData["BV_Obj"],  BVObject)
+        self.ObjTables["BO_Obj"] = ObjectTable(
+            self, self.ObjTablesData["BO_Obj"],  BOObject)
+        self.ObjTables["BI_Obj"] = ObjectTable(
+            self, self.ObjTablesData["BI_Obj"],  BIObject)
+        self.ObjTables["MSV_Obj"] = ObjectTable(
+            self, self.ObjTablesData["MSV_Obj"], MSVObject)
+        self.ObjTables["MSO_Obj"] = ObjectTable(
+            self, self.ObjTablesData["MSO_Obj"], MSOObject)
+        self.ObjTables["MSI_Obj"] = ObjectTable(
+            self, self.ObjTablesData["MSI_Obj"], MSIObject)
+
+    #
     # Functions to be called by CTNClass #
-    ######################################
+    #
     # The following functions would be somewhat equvalent to virtual functions/methods in C++ classes
-    #  They will be called by the base class (CTNClass) from which this _BacnetSlavePlug class derives.
-    
+    # They will be called by the base class (CTNClass) from which this
+    # _BacnetSlavePlug class derives.
+
     def GetCurrentNodeName(self):
         return self.CTNName()
 
     def GetFileName(self):
         return os.path.join(self.CTNPath(), 'bacnet_slave')
-    
+
     def OnCTNSave(self, from_project_path=None):
-       return self.SaveToFile(self.GetFileName())
-
+        return self.SaveToFile(self.GetFileName())
 
     def CTNTestModified(self):
         # self.ChangesToSave: Check whether any of the parameters, defined in the XSD above, were changed.
         #                     This is handled by the ConfigTreeNode class
-        #                     (Remember that no objects are ever instantiated from _BacnetSlavePlug. 
+        #                     (Remember that no objects are ever instantiated from _BacnetSlavePlug.
         #                      Objects are instead created from FinalCTNClass, which derives from
         #                      _BacnetSlavePlug and ConfigTreeNode. This means that we can exceptionally
-        #                      consider that all objects of type _BacnetSlavePlug will also be a ConfigTreeNode).
-        result = self.ChangesToSave or self.ObjTables[ "AV_Obj"].ChangesToSave \
-                                    or self.ObjTables[ "AO_Obj"].ChangesToSave \
-                                    or self.ObjTables[ "AI_Obj"].ChangesToSave \
-                                    or self.ObjTables[ "BV_Obj"].ChangesToSave \
-                                    or self.ObjTables[ "BO_Obj"].ChangesToSave \
-                                    or self.ObjTables[ "BI_Obj"].ChangesToSave \
-                                    or self.ObjTables["MSV_Obj"].ChangesToSave \
-                                    or self.ObjTables["MSO_Obj"].ChangesToSave \
-                                    or self.ObjTables["MSI_Obj"].ChangesToSave
+        # consider that all objects of type _BacnetSlavePlug will also be a
+        # ConfigTreeNode).
+        result = self.ChangesToSave \
+            or self.ObjTables["AV_Obj"].ChangesToSave \
+            or self.ObjTables["AO_Obj"].ChangesToSave \
+            or self.ObjTables["AI_Obj"].ChangesToSave \
+            or self.ObjTables["BV_Obj"].ChangesToSave \
+            or self.ObjTables["BO_Obj"].ChangesToSave \
+            or self.ObjTables["BI_Obj"].ChangesToSave \
+            or self.ObjTables["MSV_Obj"].ChangesToSave \
+            or self.ObjTables["MSO_Obj"].ChangesToSave \
+            or self.ObjTables["MSI_Obj"].ChangesToSave
         return result
 
-    ### Currently not needed. Override _OpenView() in case we need to do some special stuff whenever the editor is opened!
-    ##def _OpenView(self, name=None, onlyopened=False):
-        ##print "_BacnetSlavePlug._OpenView() Called!!!"
-        ##ConfigTreeNode._OpenView(self, name, onlyopened)
-        ###print self._View
-        #####if self._View is not None:
-            #####self._View.SetBusId(self.GetCurrentLocation())
-        ##return self._View
-
+    # Currently not needed. Override _OpenView() in case we need to do some special stuff whenever the editor is opened!
+    # def _OpenView(self, name=None, onlyopened=False):
+        # print "_BacnetSlavePlug._OpenView() Called!!!"
+        # ConfigTreeNode._OpenView(self, name, onlyopened)
+        # print self._View
+        # if self._View is not None:
+        #     self._View.SetBusId(self.GetCurrentLocation())
+        # return self._View
 
     def GetVariableLocationTree(self):
         current_location = self.GetCurrentLocation()
         # see comment in CTNGenerate_C regarding identical line of code!
-        locstr = ".".join(map(str,current_location))
-        
+        locstr = ".".join(map(str, current_location))
+
         # IDs used by BACnet to identify object types/class.
         #     OBJECT_ANALOG_INPUT       =  0,
         #     OBJECT_ANALOG_OUTPUT      =  1,
@@ -270,78 +286,84 @@
         #   Value objects will be mapped onto %M
         #   Input objects will be mapped onto %I
         #  Output objects will be mapped onto %Q
-                
+
         BACnetEntries = []
         BACnetEntries.append(self.GetSlaveLocationTree(
-                      self.ObjTablesData[ "AV_Obj"], 32, 'REAL', 'D', locstr+ '.2', 'Analog Values'))
-        BACnetEntries.append(self.GetSlaveLocationTree(
-                      self.ObjTablesData[ "AO_Obj"], 32, 'REAL', 'D', locstr+ '.1', 'Analog Outputs'))
-        BACnetEntries.append(self.GetSlaveLocationTree(
-                      self.ObjTablesData[ "AI_Obj"], 32, 'REAL', 'D', locstr+ '.0', 'Analog Inputs'))
-        BACnetEntries.append(self.GetSlaveLocationTree(
-                      self.ObjTablesData[ "BV_Obj"],  1, 'BOOL', 'X', locstr+ '.5', 'Binary Values'))
-        BACnetEntries.append(self.GetSlaveLocationTree(
-                      self.ObjTablesData[ "BO_Obj"],  1, 'BOOL', 'X', locstr+ '.4', 'Binary Outputs'))
-        BACnetEntries.append(self.GetSlaveLocationTree(
-                      self.ObjTablesData[ "BI_Obj"],  1, 'BOOL', 'X', locstr+ '.3', 'Binary Inputs'))
-        BACnetEntries.append(self.GetSlaveLocationTree(
-                      self.ObjTablesData["MSV_Obj"],  8, 'BYTE', 'B', locstr+'.19', 'Multi State Values'))
-        BACnetEntries.append(self.GetSlaveLocationTree(
-                      self.ObjTablesData["MSO_Obj"],  8, 'BYTE', 'B', locstr+'.14', 'Multi State Outputs'))
-        BACnetEntries.append(self.GetSlaveLocationTree(
-                      self.ObjTablesData["MSI_Obj"],  8, 'BYTE', 'B', locstr+'.13', 'Multi State Inputs'))
-
-        return  {"name": self.BaseParams.getName(),
-                 "type": LOCATION_CONFNODE,
-                 "location": locstr + ".x",
-                 "children": BACnetEntries}
-
-
-    ############################
+            self.ObjTablesData["AV_Obj"], 32, 'REAL', 'D', locstr + '.2', 'Analog Values'))
+        BACnetEntries.append(self.GetSlaveLocationTree(
+            self.ObjTablesData["AO_Obj"], 32, 'REAL', 'D', locstr + '.1', 'Analog Outputs'))
+        BACnetEntries.append(self.GetSlaveLocationTree(
+            self.ObjTablesData["AI_Obj"], 32, 'REAL', 'D', locstr + '.0', 'Analog Inputs'))
+        BACnetEntries.append(self.GetSlaveLocationTree(
+            self.ObjTablesData["BV_Obj"],  1, 'BOOL', 'X', locstr + '.5', 'Binary Values'))
+        BACnetEntries.append(self.GetSlaveLocationTree(
+            self.ObjTablesData["BO_Obj"],  1, 'BOOL', 'X', locstr + '.4', 'Binary Outputs'))
+        BACnetEntries.append(self.GetSlaveLocationTree(
+            self.ObjTablesData["BI_Obj"],  1, 'BOOL', 'X', locstr + '.3', 'Binary Inputs'))
+        BACnetEntries.append(self.GetSlaveLocationTree(
+            self.ObjTablesData["MSV_Obj"],  8, 'BYTE', 'B', locstr + '.19', 'Multi State Values'))
+        BACnetEntries.append(self.GetSlaveLocationTree(
+            self.ObjTablesData["MSO_Obj"],  8, 'BYTE', 'B', locstr + '.14', 'Multi State Outputs'))
+        BACnetEntries.append(self.GetSlaveLocationTree(
+            self.ObjTablesData["MSI_Obj"],  8, 'BYTE', 'B', locstr + '.13', 'Multi State Inputs'))
+
+        return {"name": self.BaseParams.getName(),
+                "type": LOCATION_CONFNODE,
+                "location": locstr + ".x",
+                "children": BACnetEntries}
+
+    #
     # Helper functions/methods #
-    ############################
+    #
     # a helper function to GetVariableLocationTree()
     def GetSlaveLocationTree(self, ObjTablesData, size_in_bits, IECdatatype, location_size, location_str, name):
         BACnetObjectEntries = []
-        for  xx_ObjProp in ObjTablesData:
+        for xx_ObjProp in ObjTablesData:
             BACnetObjectEntries.append({
                 "name": str(xx_ObjProp["Object Identifier"]) + ': ' + xx_ObjProp["Object Name"],
-                "type": LOCATION_VAR_MEMORY, # LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, or LOCATION_VAR_MEMORY
-                "size": size_in_bits, # 1 or 16
-                "IEC_type": IECdatatype, # 'BOOL', 'WORD', ...
-                "var_name": "var_name", # seems to be ignored??
+                "type": LOCATION_VAR_MEMORY,  # LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, or LOCATION_VAR_MEMORY
+                "size": size_in_bits,  # 1 or 16
+                "IEC_type": IECdatatype,  # 'BOOL', 'WORD', ...
+                "var_name": "var_name",  # seems to be ignored??
                 "location": location_size + location_str + "." + str(xx_ObjProp["Object Identifier"]),
-                "description": "description", # seems to be ignored?
+                "description": "description",  # seems to be ignored?
                 "children": []})
-        
-        BACnetEntries = []        
-        return  {"name": name,
-                 "type": LOCATION_CONFNODE,
-                 "location": location_str + ".x",
-                 "children": BACnetObjectEntries}
-    
-    
+
+        return {"name": name,
+                "type": LOCATION_CONFNODE,
+                "location": location_str + ".x",
+                "children": BACnetObjectEntries}
+
     # Returns a dictionary with:
     #      keys: names  of BACnet objects
-    #     value: number of BACnet objects using this same name 
+    #     value: number of BACnet objects using this same name
     #            (values larger than 1 indicates an error as BACnet requires unique names)
     def GetObjectNamesCount(self):
-        # The dictionary is built by first creating a list containing the names of _ALL_ 
+        # The dictionary is built by first creating a list containing the names of _ALL_
         # BACnet objects currently configured by the user (using the GUI)
         ObjectNames = []
-        ObjectNames.extend(self.ObjTables[ "AV_Obj"].GetAllValuesByName("Object Name"))
-        ObjectNames.extend(self.ObjTables[ "AO_Obj"].GetAllValuesByName("Object Name"))
-        ObjectNames.extend(self.ObjTables[ "AI_Obj"].GetAllValuesByName("Object Name"))
-        ObjectNames.extend(self.ObjTables[ "BV_Obj"].GetAllValuesByName("Object Name"))
-        ObjectNames.extend(self.ObjTables[ "BO_Obj"].GetAllValuesByName("Object Name"))
-        ObjectNames.extend(self.ObjTables[ "BI_Obj"].GetAllValuesByName("Object Name"))
-        ObjectNames.extend(self.ObjTables["MSV_Obj"].GetAllValuesByName("Object Name"))
-        ObjectNames.extend(self.ObjTables["MSO_Obj"].GetAllValuesByName("Object Name"))
-        ObjectNames.extend(self.ObjTables["MSI_Obj"].GetAllValuesByName("Object Name"))
+        ObjectNames.extend(
+            self.ObjTables["AV_Obj"].GetAllValuesByName("Object Name"))
+        ObjectNames.extend(
+            self.ObjTables["AO_Obj"].GetAllValuesByName("Object Name"))
+        ObjectNames.extend(
+            self.ObjTables["AI_Obj"].GetAllValuesByName("Object Name"))
+        ObjectNames.extend(
+            self.ObjTables["BV_Obj"].GetAllValuesByName("Object Name"))
+        ObjectNames.extend(
+            self.ObjTables["BO_Obj"].GetAllValuesByName("Object Name"))
+        ObjectNames.extend(
+            self.ObjTables["BI_Obj"].GetAllValuesByName("Object Name"))
+        ObjectNames.extend(
+            self.ObjTables["MSV_Obj"].GetAllValuesByName("Object Name"))
+        ObjectNames.extend(
+            self.ObjTables["MSO_Obj"].GetAllValuesByName("Object Name"))
+        ObjectNames.extend(
+            self.ObjTables["MSI_Obj"].GetAllValuesByName("Object Name"))
         # This list is then transformed into a collections.Counter class
         # Which is then transformed into a dictionary using dict()
         return dict(Counter(ObjectNames))
-      
+
     # Check whether the current configuration contains BACnet objects configured
     # with the same identical object name  (returns True or False)
     def HasDuplicateObjectNames(self):
@@ -354,26 +376,25 @@
     # Check whether any object ID is used more than once (not valid in BACnet)
     # (returns True or False)
     def HasDuplicateObjectIDs(self):
-        res =        self.ObjTables[ "AV_Obj"].HasDuplicateObjectIDs()
-        res = res or self.ObjTables[ "AO_Obj"].HasDuplicateObjectIDs()
-        res = res or self.ObjTables[ "AI_Obj"].HasDuplicateObjectIDs()
-        res = res or self.ObjTables[ "BV_Obj"].HasDuplicateObjectIDs()
-        res = res or self.ObjTables[ "BO_Obj"].HasDuplicateObjectIDs()
-        res = res or self.ObjTables[ "BI_Obj"].HasDuplicateObjectIDs()
+        res = self.ObjTables["AV_Obj"].HasDuplicateObjectIDs()
+        res = res or self.ObjTables["AO_Obj"].HasDuplicateObjectIDs()
+        res = res or self.ObjTables["AI_Obj"].HasDuplicateObjectIDs()
+        res = res or self.ObjTables["BV_Obj"].HasDuplicateObjectIDs()
+        res = res or self.ObjTables["BO_Obj"].HasDuplicateObjectIDs()
+        res = res or self.ObjTables["BI_Obj"].HasDuplicateObjectIDs()
         res = res or self.ObjTables["MSV_Obj"].HasDuplicateObjectIDs()
         res = res or self.ObjTables["MSO_Obj"].HasDuplicateObjectIDs()
         res = res or self.ObjTables["MSI_Obj"].HasDuplicateObjectIDs()
         return res
 
-    
-    #######################################################
+    #
     # Methods related to files (saving/loading/exporting) #
-    #######################################################
+    #
     def SaveToFile(self, filepath):
         # Save node data in file
         # The configuration data declared in the XSD string will be saved by the ConfigTreeNode class,
         # so we only need to save the data that is stored in ObjTablesData objects
-        # Note that we do not store the ObjTables objects. ObjTables is of a class that 
+        # Note that we do not store the ObjTables objects. ObjTables is of a class that
         # contains more stuff we do not need to store. Actually it is a bad idea to store
         # this extra stuff (as we would make the files we generate dependent on the actual
         # version of the wx library we are using!!! Remember that ObjTables evetually
@@ -383,19 +404,20 @@
             fd = open(filepath,   "w")
             pickle.dump(self.ObjTablesData, fd)
             fd.close()
-            # On successfull save, reset flags to indicate no more changes that need saving
-            self.ObjTables[ "AV_Obj"].ChangesToSave = False
-            self.ObjTables[ "AO_Obj"].ChangesToSave = False
-            self.ObjTables[ "AI_Obj"].ChangesToSave = False
-            self.ObjTables[ "BV_Obj"].ChangesToSave = False
-            self.ObjTables[ "BO_Obj"].ChangesToSave = False
-            self.ObjTables[ "BI_Obj"].ChangesToSave = False
+            # On successfull save, reset flags to indicate no more changes that
+            # need saving
+            self.ObjTables["AV_Obj"].ChangesToSave = False
+            self.ObjTables["AO_Obj"].ChangesToSave = False
+            self.ObjTables["AI_Obj"].ChangesToSave = False
+            self.ObjTables["BV_Obj"].ChangesToSave = False
+            self.ObjTables["BO_Obj"].ChangesToSave = False
+            self.ObjTables["BI_Obj"].ChangesToSave = False
             self.ObjTables["MSV_Obj"].ChangesToSave = False
             self.ObjTables["MSO_Obj"].ChangesToSave = False
             self.ObjTables["MSI_Obj"].ChangesToSave = False
             return True
         except:
-            return _("Unable to save to file \"%s\"!")%filepath
+            return _("Unable to save to file \"%s\"!") % filepath
 
     def LoadFromFile(self, filepath):
         # Load the data that is saved in SaveToFile()
@@ -405,157 +427,181 @@
             fd.close()
             return True
         except:
-            return _("Unable to load file \"%s\"!")%filepath
+            return _("Unable to load file \"%s\"!") % filepath
 
     def _ExportBacnetSlave(self):
-        dialog = wx.FileDialog(self.GetCTRoot().AppFrame, 
-                               _("Choose a file"), 
-                               os.path.expanduser("~"), 
-                               "%s_EDE.csv" % self.CTNName(),  
+        dialog = wx.FileDialog(self.GetCTRoot().AppFrame,
+                               _("Choose a file"),
+                               os.path.expanduser("~"),
+                               "%s_EDE.csv" % self.CTNName(),
                                _("EDE files (*_EDE.csv)|*_EDE.csv|All files|*.*"),
-                               wx.SAVE|wx.OVERWRITE_PROMPT)
+                               wx.SAVE | wx.OVERWRITE_PROMPT)
         if dialog.ShowModal() == wx.ID_OK:
             result = self.GenerateEDEFile(dialog.GetPath())
             result = False
             if result:
-                self.GetCTRoot().logger.write_error(_("Error: Export slave failed\n"))
-        dialog.Destroy()  
-
+                self.GetCTRoot().logger.write_error(
+                    _("Error: Export slave failed\n"))
+        dialog.Destroy()
 
     def GenerateEDEFile(self, filename):
-        template_file_dir     = os.path.join(os.path.split(__file__)[0],"ede_files")
-        
-        #The BACnetServerNode attribute is added dynamically by ConfigTreeNode._AddParamsMembers()
-        # It will be an XML parser object created by GenerateParserFromXSDstring(self.XSD).CreateRoot()
+        template_file_dir = os.path.join(
+            os.path.split(__file__)[0], "ede_files")
+
+        # The BACnetServerNode attribute is added dynamically by ConfigTreeNode._AddParamsMembers()
+        # It will be an XML parser object created by
+        # GenerateParserFromXSDstring(self.XSD).CreateRoot()
         BACnet_Device_ID = self.BACnetServerNode.getBACnet_Device_ID()
-        
+
         # The EDE file contains a header that includes general project data (name, author, ...)
         # Instead of asking the user for this data, we get it from the configuration
         # of the Beremiz project itself.
         # We ask the root Config Tree Node for the data...
         ProjProp = {}
         FileProp = {}
-        CTN_Root      = self.GetCTRoot()   # this should be an object of class ProjectController
-        Project       = CTN_Root.Project   # this should be an object capable of parsing
-                                           # PLCopen XML files. The parser is created automatically
-                                           # (i.e. using GenerateParserFromXSD() from xmlclass module)
-                                           # using the PLCopen XSD file defining the format of the XML.
-                                           # See the file plcopen/plcopen.py
+
+        # this should be an object of class ProjectController
+        CTN_Root = self.GetCTRoot()
+
+        # this should be an object capable of parsing
+        # PLCopen XML files. The parser is created automatically
+        # (i.e. using GenerateParserFromXSD() from xmlclass module)
+        # using the PLCopen XSD file defining the format of the XML.
+        # See the file plcopen/plcopen.py
+        Project = CTN_Root.Project
         if Project is not None:
-          # getcontentHeader() and getfileHeader() are functions that are conditionally defined in
-          # plcopn/plcopen.py    We cannot rely on their existance
-          if getattr(Project, "getcontentHeader", None) is not None:
-            ProjProp = Project.getcontentHeader()
-            # getcontentHeader() returns a dictionary. Available keys are:
-            # "projectName", "projectVersion", "modificationDateTime", 
-            # "organization", "authorName", "language", "pageSize", "scaling"
-          if getattr(Project, "getfileHeader", None) is not None:
-            FileProp = Project.getfileHeader()
-            # getfileHeader() returns a dictionary. Available keys are:
-            # "companyName", "companyURL", "productName", "productVersion",
-            # "productRelease", "creationDateTime", "contentDescription"
-
-        ProjName   = ""
+            # getcontentHeader() and getfileHeader() are functions that are conditionally defined in
+            # plcopn/plcopen.py    We cannot rely on their existance
+            if getattr(Project, "getcontentHeader", None) is not None:
+                ProjProp = Project.getcontentHeader()
+                # getcontentHeader() returns a dictionary. Available keys are:
+                # "projectName", "projectVersion", "modificationDateTime",
+                # "organization", "authorName", "language", "pageSize", "scaling"
+            if getattr(Project, "getfileHeader", None) is not None:
+                FileProp = Project.getfileHeader()
+                # getfileHeader() returns a dictionary. Available keys are:
+                # "companyName", "companyURL", "productName", "productVersion",
+                # "productRelease", "creationDateTime", "contentDescription"
+
+        ProjName = ""
         if "projectName" in ProjProp:
-            ProjName    = ProjProp["projectName"]
+            ProjName = ProjProp["projectName"]
         ProjAuthor = ""
         if "companyName" in FileProp:
             ProjAuthor += "(" + FileProp["companyName"] + ")"
         if "authorName" in ProjProp:
-            ProjAuthor  = ProjProp["authorName"] + " " + ProjAuthor
-            
+            ProjAuthor = ProjProp["authorName"] + " " + ProjAuthor
+
         projdata_dict = {}
-        projdata_dict["Project Name"]     = ProjName
-        projdata_dict["Project Author"]   = ProjAuthor
-        projdata_dict["Current Time"]     = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-        projdata_dict["EDE file version"] = self.ObjTablesData["EDEfile_parm"]["next_EDE_file_version"]
+        projdata_dict["Project Name"] = ProjName
+        projdata_dict["Project Author"] = ProjAuthor
+        projdata_dict["Current Time"] = datetime.now().strftime(
+            '%Y-%m-%d %H:%M:%S')
+        projdata_dict["EDE file version"] = self.ObjTablesData[
+            "EDEfile_parm"]["next_EDE_file_version"]
 
         # Next time we generate an EDE file, use another version!
         self.ObjTablesData["EDEfile_parm"]["next_EDE_file_version"] += 1
 
-        AX_params_format = "%(Object Name)s;" + str(BACnet_Device_ID) + ";%(Object Name)s;%(BACnetObjTypeID)s;%(Object Identifier)s;%(Description)s;0;;;%(Settable)s;N;;;;%(Unit ID)s;"
-
-        BX_params_format = "%(Object Name)s;" + str(BACnet_Device_ID) + ";%(Object Name)s;%(BACnetObjTypeID)s;%(Object Identifier)s;%(Description)s;0;0;1;%(Settable)s;N;;;;;"
-
-        MSX_params_format = "%(Object Name)s;" + str(BACnet_Device_ID) + ";%(Object Name)s;%(BACnetObjTypeID)s;%(Object Identifier)s;%(Description)s;1;1;%(Number of States)s;%(Settable)s;N;;;;;"
-        
+        AX_params_format = "%(Object Name)s;" + str(BACnet_Device_ID) + \
+            ";%(Object Name)s;%(BACnetObjTypeID)s;%(Object Identifier)s;%(Description)s;0;;;%(Settable)s;N;;;;%(Unit ID)s;"
+
+        BX_params_format = "%(Object Name)s;" + str(BACnet_Device_ID) + \
+            ";%(Object Name)s;%(BACnetObjTypeID)s;%(Object Identifier)s;%(Description)s;0;0;1;%(Settable)s;N;;;;;"
+
+        MSX_params_format = "%(Object Name)s;" + str(BACnet_Device_ID) + \
+            ";%(Object Name)s;%(BACnetObjTypeID)s;%(Object Identifier)s;%(Description)s;1;1;%(Number of States)s;%(Settable)s;N;;;;;"
+
         Objects_List = []
-        for  ObjType,     params_format   in [
-            ("AV" ,  AX_params_format ), ("AO" ,  AX_params_format ), ("AI" ,  AX_params_format ),
-            ("BV" ,  BX_params_format ), ("BO" ,  BX_params_format ), ("BI" ,  BX_params_format ),
-            ("MSV", MSX_params_format ), ("MSO", MSX_params_format ), ("MSI", MSX_params_format )
-            ]:
+        for ObjType, params_format in [("AV",  AX_params_format),
+                                       ("AO",  AX_params_format),
+                                       ("AI",  AX_params_format),
+                                       ("BV",  BX_params_format),
+                                       ("BO",  BX_params_format),
+                                       ("BI",  BX_params_format),
+                                       ("MSV", MSX_params_format),
+                                       ("MSO", MSX_params_format),
+                                       ("MSI", MSX_params_format)]:
             self.ObjTables[ObjType + "_Obj"].UpdateAllVirtualProperties()
             for ObjProp in self.ObjTablesData[ObjType + "_Obj"]:
                 Objects_List.append(params_format % ObjProp)
-        
+
         # Normalize filename
         for extension in ["_EDE.csv", "_ObjTypes.csv", "_StateTexts.csv", "_Units.csv"]:
             if filename.lower().endswith(extension.lower()):
                 filename = filename[:-len(extension)]
-        
+
         # EDE_header
-        generate_file_name    = filename + "_EDE.csv"
-        template_file_name    = os.path.join(template_file_dir,"template_EDE.csv")
+        generate_file_name = filename + "_EDE.csv"
+        template_file_name = os.path.join(
+            template_file_dir, "template_EDE.csv")
         generate_file_content = open(template_file_name).read() % projdata_dict
-        generate_file_handle  = open(generate_file_name,'w')
+        generate_file_handle = open(generate_file_name, 'w')
         generate_file_handle  .write(generate_file_content)
         generate_file_handle  .write("\n".join(Objects_List))
         generate_file_handle  .close()
-        
-        # templates of remaining files do not need changes. They are simply copied unchanged!
+
+        # templates of remaining files do not need changes. They are simply
+        # copied unchanged!
         for extension in ["_ObjTypes.csv", "_StateTexts.csv", "_Units.csv"]:
-            generate_file_name    = filename + extension
-            template_file_name    = os.path.join(template_file_dir,"template" + extension)
+            generate_file_name = filename + extension
+            template_file_name = os.path.join(
+                template_file_dir, "template" + extension)
             generate_file_content = open(template_file_name).read()
-            generate_file_handle  = open(generate_file_name,'w')
+            generate_file_handle = open(generate_file_name, 'w')
             generate_file_handle  .write(generate_file_content)
             generate_file_handle  .close()
 
-    
-    #############################
+    #
     # Generate the source files #
-    #############################
-    def CTNGenerate_C(self, buildpath, locations):        
-        # Determine the current location in Beremiz's project configuration tree 
+    #
+    def CTNGenerate_C(self, buildpath, locations):
+        # Determine the current location in Beremiz's project configuration
+        # tree
         current_location = self.GetCurrentLocation()
-        # The current location of this plugin in Beremiz's configuration tree, separated by underscores 
+        # The current location of this plugin in Beremiz's configuration tree, separated by underscores
         #  NOTE: Since BACnet plugin currently does not use sub-branches in the tree (in other words, this
         #        _BacnetSlavePlug class was actually renamed as the RootClass), the current_location_dots
         #        will actually be a single number (e.g.: 0 or 3 or 6, corresponding to the location
         #        in which the plugin was inserted in the Beremiz configuration tree on Beremiz's left panel).
-        locstr = "_".join(map(str,current_location))
-
-        # First check whether all the current parameters (inserted by user in the GUI) are valid...
+        locstr = "_".join(map(str, current_location))
+
+        # First check whether all the current parameters (inserted by user in
+        # the GUI) are valid...
         if self.HasDuplicateObjectNames():
-            self.GetCTRoot().logger.write_warning(_("Error: BACnet server '%s.x: %s' contains objects with duplicate object names.\n")%(locstr, self.CTNName()))
-            raise Exception, False
-            # TODO: return an error code instead of raising an exception (currently unsupported by Beremiz)
+            self.GetCTRoot().logger.write_warning(
+                _("Error: BACnet server '%s.x: %s' contains objects with duplicate object names.\n") % (locstr, self.CTNName()))
+            raise Exception(False)
+            # TODO: return an error code instead of raising an exception
+            # (currently unsupported by Beremiz)
 
         if self.HasDuplicateObjectIDs():
-            self.GetCTRoot().logger.write_warning(_("Error: BACnet server '%s.x: %s' contains objects with duplicate object identifiers.\n")%(locstr, self.CTNName()))
-            raise Exception, False
-            # TODO: return an error code instead of raising an exception (currently unsupported by Beremiz)
-            
-        #-------------------------------------------------------------------------------
+            self.GetCTRoot().logger.write_warning(
+                _("Error: BACnet server '%s.x: %s' contains objects with duplicate object identifiers.\n") % (locstr, self.CTNName()))
+            raise Exception(False)
+            # TODO: return an error code instead of raising an exception
+            # (currently unsupported by Beremiz)
+
+        # -------------------------------------------------------------------------------
         # Create and populate the loc_dict dictionary with all parameters needed to configure
         #  the generated source code (.c and .h files)
-        #-------------------------------------------------------------------------------
-        
+        # ----------------------------------------------------------------------
+
         # 1) Create the dictionary (loc_dict = {})
         loc_dict = {}
-        loc_dict["locstr"]              =         locstr
-
-        #The BACnetServerNode attribute is added dynamically by ConfigTreeNode._AddParamsMembers()
-        # It will be an XML parser object created by GenerateParserFromXSDstring(self.XSD).CreateRoot()
-        loc_dict["network_interface"]            = self.BACnetServerNode.getNetwork_Interface()
-        loc_dict["port_number"]                  = self.BACnetServerNode.getUDP_Port_Number()
-        loc_dict["BACnet_Device_ID"]             = self.BACnetServerNode.getBACnet_Device_ID()
-        loc_dict["BACnet_Device_Name"]           = self.BACnetServerNode.getBACnet_Device_Name()
+        loc_dict["locstr"] = locstr
+
+        # The BACnetServerNode attribute is added dynamically by ConfigTreeNode._AddParamsMembers()
+        # It will be an XML parser object created by
+        # GenerateParserFromXSDstring(self.XSD).CreateRoot()
+        loc_dict["network_interface"] = self.BACnetServerNode.getNetwork_Interface()
+        loc_dict["port_number"] = self.BACnetServerNode.getUDP_Port_Number()
+        loc_dict["BACnet_Device_ID"] = self.BACnetServerNode.getBACnet_Device_ID()
+        loc_dict["BACnet_Device_Name"] = self.BACnetServerNode.getBACnet_Device_Name()
         loc_dict["BACnet_Comm_Control_Password"] = self.BACnetServerNode.getBACnet_Communication_Control_Password()
-        loc_dict["BACnet_Device_Location"]       = self.BACnetServerNode.getBACnet_Device_Location()
-        loc_dict["BACnet_Device_Description"]    = self.BACnetServerNode.getBACnet_Device_Description()
-        loc_dict["BACnet_Device_AppSoft_Version"]= self.BACnetServerNode.getBACnet_Device_Application_Software_Version()
+        loc_dict["BACnet_Device_Location"] = self.BACnetServerNode.getBACnet_Device_Location()
+        loc_dict["BACnet_Device_Description"] = self.BACnetServerNode.getBACnet_Device_Description()
+        loc_dict["BACnet_Device_AppSoft_Version"] = self.BACnetServerNode.getBACnet_Device_Application_Software_Version()
         loc_dict["BACnet_Vendor_ID"] = BACNET_VENDOR_ID
         loc_dict["BACnet_Vendor_Name"] = BACNET_VENDOR_NAME
         loc_dict["BACnet_Model_Name"] = BACNET_DEVICE_MODEL_NAME
@@ -563,90 +609,95 @@
         # 2) Add the data specific to each BACnet object type
         # For each BACnet object type, start off by creating some intermediate helpful lists
         #  a) parameters_list containing the strings that will
-        #     be included in the C source code, and which will initialize the struct with the 
+        #     be included in the C source code, and which will initialize the struct with the
         #     object (Analog Value, Binary Value, or Multi State Value) parameters
         #  b) locatedvar_list containing the strings that will
-        #     declare the memory to store the located variables, as well as the 
+        #     declare the memory to store the located variables, as well as the
         #     pointers (required by matiec) that point to that memory.
 
-        # format for delaring IEC 61131-3 variable (and pointer) onto which BACnet object is mapped
+        # format for delaring IEC 61131-3 variable (and pointer) onto which
+        # BACnet object is mapped
         locvar_format = '%(Ctype)s ___%(loc)s_%(Object Identifier)s; ' + \
                         '%(Ctype)s *__%(loc)s_%(Object Identifier)s = &___%(loc)s_%(Object Identifier)s;'
 
         # format for initializing a ANALOG_VALUE_DESCR struct in C code
         #    also valid for ANALOG_INPUT and ANALOG_OUTPUT
         AX_params_format = '{&___%(loc)s_%(Object Identifier)s, ' + \
-                          '%(Object Identifier)s, "%(Object Name)s", "%(Description)s", %(Unit ID)d}'
+            '%(Object Identifier)s, "%(Object Name)s", "%(Description)s", %(Unit ID)d}'
         # format for initializing a BINARY_VALUE_DESCR struct in C code
         #    also valid for BINARY_INPUT and BINARY_OUTPUT
         BX_params_format = '{&___%(loc)s_%(Object Identifier)s, ' + \
-                          '%(Object Identifier)s, "%(Object Name)s", "%(Description)s"}'
+            '%(Object Identifier)s, "%(Object Name)s", "%(Description)s"}'
 
         # format for initializing a MULTISTATE_VALUE_DESCR struct in C code
         #    also valid for MULTISTATE_INPUT and MULTISTATE_OUTPUT
         MSX_params_format = '{&___%(loc)s_%(Object Identifier)s, ' + \
-                           '%(Object Identifier)s, "%(Object Name)s", "%(Description)s", %(Number of States)s}'
-
-        AV_locstr  = 'MD' + locstr+'_2'  # see the comment in GetVariableLocationTree() to grok the '_2'
-        AO_locstr  = 'QD' + locstr+'_1'  # see the comment in GetVariableLocationTree() to grok the '_1'
-        AI_locstr  = 'ID' + locstr+'_0'  # see the comment in GetVariableLocationTree() to grok the '_0'
-        BV_locstr  = 'MX' + locstr+'_5'  # see the comment in GetVariableLocationTree() to grok the '_5'
-        BO_locstr  = 'QX' + locstr+'_4'  # see the comment in GetVariableLocationTree() to grok the '_4'
-        BI_locstr  = 'IX' + locstr+'_3'  # see the comment in GetVariableLocationTree() to grok the '_3'
-        MSV_locstr = 'MB' + locstr+'_19' # see the comment in GetVariableLocationTree() to grok the '_19'
-        MSO_locstr = 'QB' + locstr+'_14' # see the comment in GetVariableLocationTree() to grok the '_14'
-        MSI_locstr = 'IB' + locstr+'_13' # see the comment in GetVariableLocationTree() to grok the '_13'
-        
-        
-        for  ObjType,  ObjLocStr,     params_format   in [
-            ("AV"   ,  AV_locstr,  AX_params_format ),
-            ("AO"   ,  AO_locstr,  AX_params_format ),
-            ("AI"   ,  AI_locstr,  AX_params_format ),
-            ("BV"   ,  BV_locstr,  BX_params_format ),
-            ("BO"   ,  BO_locstr,  BX_params_format ),
-            ("BI"   ,  BI_locstr,  BX_params_format ),
-            ("MSV"  , MSV_locstr, MSX_params_format ),
-            ("MSO"  , MSO_locstr, MSX_params_format ),
-            ("MSI"  , MSI_locstr, MSX_params_format )
-            ]:
+            '%(Object Identifier)s, "%(Object Name)s", "%(Description)s", %(Number of States)s}'
+
+        # see the comment in GetVariableLocationTree()
+        AV_locstr = 'MD' + locstr + '_2'
+        AO_locstr = 'QD' + locstr + '_1'
+        AI_locstr = 'ID' + locstr + '_0'
+        BV_locstr = 'MX' + locstr + '_5'
+        BO_locstr = 'QX' + locstr + '_4'
+        BI_locstr = 'IX' + locstr + '_3'
+        MSV_locstr = 'MB' + locstr + '_19'
+        MSO_locstr = 'QB' + locstr + '_14'
+        MSI_locstr = 'IB' + locstr + '_13'
+
+        for ObjType,  ObjLocStr,     params_format in [
+                ("AV",  AV_locstr,  AX_params_format),
+                ("AO",  AO_locstr,  AX_params_format),
+                ("AI",  AI_locstr,  AX_params_format),
+                ("BV",  BV_locstr,  BX_params_format),
+                ("BO",  BO_locstr,  BX_params_format),
+                ("BI",  BI_locstr,  BX_params_format),
+                ("MSV", MSV_locstr, MSX_params_format),
+                ("MSO", MSO_locstr, MSX_params_format),
+                ("MSI", MSI_locstr, MSX_params_format)]:
             parameters_list = []
             locatedvar_list = []
             self.ObjTables[ObjType + "_Obj"].UpdateAllVirtualProperties()
             for ObjProp in self.ObjTablesData[ObjType + "_Obj"]:
-                ObjProp["loc" ] = ObjLocStr
+                ObjProp["loc"] = ObjLocStr
                 parameters_list.append(params_format % ObjProp)
                 locatedvar_list.append(locvar_format % ObjProp)
-            loc_dict[ ObjType + "_count"]           =          len( parameters_list )
-            loc_dict[ ObjType + "_param"]           =   ",\n".join( parameters_list )
-            loc_dict[ ObjType + "_lvars"]           =    "\n".join( locatedvar_list )
-
-        #----------------------------------------------------------------------
+            loc_dict[ObjType + "_count"] = len(parameters_list)
+            loc_dict[ObjType + "_param"] = ",\n".join(parameters_list)
+            loc_dict[ObjType + "_lvars"] = "\n".join(locatedvar_list)
+
+        # ----------------------------------------------------------------------
         # Create the C source files that implement the BACnet server
-        #----------------------------------------------------------------------
-        
+        # ----------------------------------------------------------------------
+
         # Names of the .c files that will be generated, based on a template file with same name
         #   (names without '.c'  --> this will be added later)
         #   main server.c file is handled separately
         Generated_BACnet_c_mainfile = "server"
-        Generated_BACnet_c_files = ["ai", "ao", "av", "bi", "bo", "bv", "msi", "mso", "msv", "device"]
+        Generated_BACnet_c_files = [
+            "ai", "ao", "av", "bi", "bo", "bv", "msi", "mso", "msv", "device"]
 
         # Names of the .h files that will be generated, based on a template file with same name
         #   (names without '.h'  --> this will be added later)
-        Generated_BACnet_h_files = ["server", "device", "config_bacnet_for_beremiz",
-                                    "ai", "ao", "av", "bi", "bo", "bv", "msi", "mso", "msv"
-                                   ]
+        Generated_BACnet_h_files = [
+            "server", "device", "config_bacnet_for_beremiz",
+            "ai", "ao", "av", "bi", "bo", "bv", "msi", "mso", "msv"
+        ]
 
         # Generate the files with the source code
         postfix = "_".join(map(str, current_location))
-        template_file_dir     = os.path.join(os.path.split(__file__)[0],"runtime")
-        
-        def generate_file(file_name, extension): 
-            generate_file_name    = os.path.join(buildpath, "%s_%s.%s"%(file_name,postfix,extension))
-            template_file_name    = os.path.join(template_file_dir,"%s.%s"%(file_name,extension))
+        template_file_dir = os.path.join(
+            os.path.split(__file__)[0], "runtime")
+
+        def generate_file(file_name, extension):
+            generate_file_name = os.path.join(
+                buildpath, "%s_%s.%s" % (file_name, postfix, extension))
+            template_file_name = os.path.join(
+                template_file_dir, "%s.%s" % (file_name, extension))
             generate_file_content = open(template_file_name).read() % loc_dict
-            generate_file_handle  = open(generate_file_name,'w')
-            generate_file_handle  .write(generate_file_content)
-            generate_file_handle  .close()
+            generate_file_handle = open(generate_file_name, 'w')
+            generate_file_handle.write(generate_file_content)
+            generate_file_handle.close()
 
         for file_name in Generated_BACnet_c_files:
             generate_file(file_name, "c")
@@ -654,44 +705,23 @@
             generate_file(file_name, "h")
         generate_file(Generated_BACnet_c_mainfile, "c")
         Generated_BACnet_c_mainfile_name = \
-            os.path.join(buildpath, "%s_%s.%s"%(Generated_BACnet_c_mainfile,postfix,"c"))
-
-        #----------------------------------------------------------------------
+            os.path.join(buildpath, "%s_%s.%s" %
+                         (Generated_BACnet_c_mainfile, postfix, "c"))
+
+        # ----------------------------------------------------------------------
         # Finally, define the compilation and linking commands and flags
-        #----------------------------------------------------------------------
-        
+        # ----------------------------------------------------------------------
+
         LDFLAGS = []
         # when using dynamically linked library...
-        #LDFLAGS.append(' -lbacnet')   
-        #LDFLAGS.append(' -L"'+BacnetLibraryPath+'"')
-        #LDFLAGS.append(' "-Wl,-rpath,' + BacnetLibraryPath + '"')
+        # LDFLAGS.append(' -lbacnet')
+        # LDFLAGS.append(' -L"'+BacnetLibraryPath+'"')
+        # LDFLAGS.append(' "-Wl,-rpath,' + BacnetLibraryPath + '"')
         # when using static library:
-        LDFLAGS.append(' "'+os.path.join(BacnetLibraryPath, "libbacnet.a")+'"')  
-
-        CFLAGS   = ' -I"'+BacnetIncludePath+'"'
-        CFLAGS  += ' -I"'+BacnetIncludePortPath+'"'
-        
+        LDFLAGS.append(
+            ' "' + os.path.join(BacnetLibraryPath, "libbacnet.a") + '"')
+
+        CFLAGS = ' -I"' + BacnetIncludePath + '"'
+        CFLAGS += ' -I"' + BacnetIncludePortPath + '"'
+
         return [(Generated_BACnet_c_mainfile_name, CFLAGS)], LDFLAGS, True
-
-
-
-###################################################
-###################################################
-#                                                 #
-#             R O O T    C L A S S                # 
-#                                                 #
-###################################################
-###################################################
-#class RootClass:
-    #XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
-    #<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-      #<xsd:element name="BACnetRoot">
-      #</xsd:element>
-    #</xsd:schema>
-    #"""
-    #CTNChildrenTypes = [("BacnetSlave", _BacnetSlavePlug,  "Bacnet Slave")
-                       ##,("XXX",_XXXXPlug, "XXX")
-                       #]
-    
-    #def CTNGenerate_C(self, buildpath, locations):        
-        #return [], "", True