plugger.py
changeset 24 585d5b387b6a
parent 23 e007d9d466d7
child 25 fa7503684c28
equal deleted inserted replaced
23:e007d9d466d7 24:585d5b387b6a
   130     
   130     
   131     def PlugImport(self, src_PlugPath):
   131     def PlugImport(self, src_PlugPath):
   132         shutil.copytree(src_PlugPath, self.PlugPath)
   132         shutil.copytree(src_PlugPath, self.PlugPath)
   133         return True
   133         return True
   134 
   134 
   135     def PlugGenerate_C(self, buildpath, current_location, locations, logger):
   135     def PlugGenerate_C(self, buildpath, locations, logger):
   136         """
   136         """
   137         Generate C code
   137         Generate C code
   138         @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5)
       
   139         @param locations: List of complete variables locations \
   138         @param locations: List of complete variables locations \
   140             [{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...)
   139             [{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...)
   141             "NAME" : name of the variable (generally "__IW0_1_2" style)
   140             "NAME" : name of the variable (generally "__IW0_1_2" style)
   142             "DIR" : direction "Q","I" or "M"
   141             "DIR" : direction "Q","I" or "M"
   143             "SIZE" : size "X", "B", "W", "D", "L"
   142             "SIZE" : size "X", "B", "W", "D", "L"
   144             "LOC" : tuple of interger for IEC location (0,1,2,...)
   143             "LOC" : tuple of interger for IEC location (0,1,2,...)
   145             }, ...]
   144             }, ...]
   146         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
   145         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
   147         """
   146         """
   148         logger.write_warning(".".join(map(lambda x:str(x), current_location)) + " -> Nothing yo do\n")
   147         logger.write_warning(".".join(map(lambda x:str(x), self.GetCurrentLocation())) + " -> Nothing yo do\n")
   149         return [],""
   148         return [],""
   150     
   149     
   151     def _Generate_C(self, buildpath, current_location, locations, logger):
   150     def _Generate_C(self, buildpath, locations, logger):
   152         # Generate plugins [(Cfiles, CFLAGS)], LDFLAGS
   151         # Generate plugins [(Cfiles, CFLAGS)], LDFLAGS
   153         PlugCFilesAndCFLAGS, PlugLDFLAGS = self.PlugGenerate_C(buildpath, current_location, locations, logger)
   152         PlugCFilesAndCFLAGS, PlugLDFLAGS = self.PlugGenerate_C(buildpath, locations, logger)
   154         # recurse through all childs, and stack their results
   153         # recurse through all childs, and stack their results
   155         for PlugChild in self.IterChilds():
   154         for PlugChild in self.IterChilds():
   156             # Compute child's IEC location
   155             new_location = PlugChild.GetCurrentLocation()
   157             if current_location:
   156             # How deep are we in the tree ?
   158                 new_location = current_location + (self.BaseParams.getIEC_Channel())
   157             depth=len(new_location)
   159             else:
       
   160                 # root 
       
   161                 new_location = ()
       
   162             # Get childs [(Cfiles, CFLAGS)], LDFLAGS
       
   163             CFilesAndCFLAGS, LDFLAGS = \
   158             CFilesAndCFLAGS, LDFLAGS = \
   164                 PlugChild._Generate_C(
   159                 PlugChild._Generate_C(
   165                     #keep the same path
   160                     #keep the same path
   166                     buildpath,
   161                     buildpath,
   167                     # but update location (add curent IEC channel at the end)
       
   168                     new_location,
       
   169                     # filter locations that start with current IEC location
   162                     # filter locations that start with current IEC location
   170                     [loc for loc in locations if loc["LOC"][0:len(new_location)] == new_location ],
   163                     [loc for loc in locations if loc["LOC"][0:depth] == new_location ],
   171                     #propagete logger
   164                     #propagete logger
   172                     logger)
   165                     logger)
   173             # stack the result
   166             # stack the result
   174             PlugCFilesAndCFLAGS += CFilesAndCFLAGS
   167             PlugCFilesAndCFLAGS += CFilesAndCFLAGS
   175             PlugLDFLAGS += LDFLAGS
   168             PlugLDFLAGS += LDFLAGS
   206 
   199 
   207     def GetChildByIECLocation(self, Location):
   200     def GetChildByIECLocation(self, Location):
   208         return self._GetChildBySomething('_',"IEC_Channel", Name)
   201         return self._GetChildBySomething('_',"IEC_Channel", Name)
   209     
   202     
   210     def GetCurrentLocation(self):
   203     def GetCurrentLocation(self):
       
   204         """
       
   205         @return:  Tupple containing plugin IEC location of current plugin : %I0.0.4.5 => (0,0,4,5)
       
   206         """
   211         return self.PlugParent.GetCurrentLocation() + (self.BaseParams.getIEC_Channel(),)
   207         return self.PlugParent.GetCurrentLocation() + (self.BaseParams.getIEC_Channel(),)
   212 
   208 
   213     def GetPlugRoot(self):
   209     def GetPlugRoot(self):
   214         return self.PlugParent.GetPlugRoot()
   210         return self.PlugParent.GetPlugRoot()
   215 
   211 
   266         # Fetch the plugin
   262         # Fetch the plugin
   267         PlugInstance = self.GetChildByName(PlugName)
   263         PlugInstance = self.GetChildByName(PlugName)
   268         # Ask to his parent to remove it
   264         # Ask to his parent to remove it
   269         PlugInstance.PlugParent._doRemoveChild(PlugInstance)
   265         PlugInstance.PlugParent._doRemoveChild(PlugInstance)
   270 
   266 
   271     def PlugAddChild(self, PlugName, PlugType):
   267     def PlugAddChild(self, PlugName, PlugType, logger):
   272         """
   268         """
   273         Create the plugins that may be added as child to this node self
   269         Create the plugins that may be added as child to this node self
   274         @param PlugType: string desining the plugin class name (get name from PlugChildsTypes)
   270         @param PlugType: string desining the plugin class name (get name from PlugChildsTypes)
   275         @param PlugName: string for the name of the plugin instance
   271         @param PlugName: string for the name of the plugin instance
   276         """
   272         """
   319                     _self.FindNewIEC_Channel(_self.BaseParams.getIEC_Channel())
   315                     _self.FindNewIEC_Channel(_self.BaseParams.getIEC_Channel())
   320                     # Call the plugin real __init__
   316                     # Call the plugin real __init__
   321                     if getattr(PlugClass, "__init__", None):
   317                     if getattr(PlugClass, "__init__", None):
   322                         PlugClass.__init__(_self)
   318                         PlugClass.__init__(_self)
   323                     #Load and init all the childs
   319                     #Load and init all the childs
   324                     _self.LoadChilds()
   320                     _self.LoadChilds(logger)
   325                 else:
   321                 else:
   326                     # If plugin do not have corresponding file/dirs - they will be created on Save
   322                     # If plugin do not have corresponding file/dirs - they will be created on Save
   327                     # Set plugin name
   323                     # Set plugin name
   328                     _self.BaseParams.setName(PlugName)
   324                     _self.BaseParams.setName(PlugName)
   329                     os.mkdir(_self.PlugPath())
   325                     os.mkdir(_self.PlugPath())
   355             xmlfile = open(self.PluginXmlFilePath(PlugName), 'r')
   351             xmlfile = open(self.PluginXmlFilePath(PlugName), 'r')
   356             tree = minidom.parse(xmlfile)
   352             tree = minidom.parse(xmlfile)
   357             self.PlugParams[1].loadXMLTree(tree.childNodes[0])
   353             self.PlugParams[1].loadXMLTree(tree.childNodes[0])
   358             xmlfile.close()
   354             xmlfile.close()
   359         
   355         
   360     def LoadChilds(self):
   356     def LoadChilds(self, logger):
   361         # Iterate over all PlugName@PlugType in plugin directory, and try to open them
   357         # Iterate over all PlugName@PlugType in plugin directory, and try to open them
   362         for PlugDir in os.listdir(self.PlugPath()):
   358         for PlugDir in os.listdir(self.PlugPath()):
   363             if os.path.isdir(os.path.join(self.PlugPath(), PlugDir)) and \
   359             if os.path.isdir(os.path.join(self.PlugPath(), PlugDir)) and \
   364                PlugDir.count(NameTypeSeparator) == 1:
   360                PlugDir.count(NameTypeSeparator) == 1:
   365                 #try:
   361                 pname, ptype = PlugDir.split(NameTypeSeparator)
   366                 self.PlugAddChild(*PlugDir.split(NameTypeSeparator))
   362                 try:
   367                 #except Exception, e:
   363                     self.PlugAddChild(pname, ptype, logger)
   368                 #    print e
   364                 except Exception, e:
       
   365                     logger.write_error("Could not add child \"%s\", type %s :\n%s\n"%(pname, ptype, str(e)))
   369 
   366 
   370 def _GetClassFunction(name):
   367 def _GetClassFunction(name):
   371     def GetRootClass():
   368     def GetRootClass():
   372         return getattr(__import__("plugins." + name), name).RootClass
   369         return getattr(__import__("plugins." + name), name).RootClass
   373     return GetRootClass
   370     return GetRootClass
   533         self.PluggedChilds = {}
   530         self.PluggedChilds = {}
   534         # Keep track of the root plugin (i.e. project path)
   531         # Keep track of the root plugin (i.e. project path)
   535         self.ProjectPath = ProjectPath
   532         self.ProjectPath = ProjectPath
   536         return None
   533         return None
   537         
   534         
   538     def LoadProject(self, ProjectPath):
   535     def LoadProject(self, ProjectPath, logger):
   539         """
   536         """
   540         Load a project contained in a folder
   537         Load a project contained in a folder
   541         @param ProjectPath: path of the project folder
   538         @param ProjectPath: path of the project folder
   542         """
   539         """
   543         # Verify that project contains a PLCOpen program
   540         # Verify that project contains a PLCOpen program
   560             #Load the plugin.xml file into parameters members
   557             #Load the plugin.xml file into parameters members
   561             result = self.LoadXMLParams()
   558             result = self.LoadXMLParams()
   562             if result:
   559             if result:
   563                 return result
   560                 return result
   564             #Load and init all the childs
   561             #Load and init all the childs
   565             self.LoadChilds()
   562             self.LoadChilds(logger)
   566         return None
   563         return None
   567     
   564     
   568     def SaveProject(self):
   565     def SaveProject(self):
   569         if not self.PLCManager.SaveXMLFile():
   566         if not self.PLCManager.SaveXMLFile():
   570             self.PLCManager.SaveXMLFile(os.path.join(self.ProjectPath, 'plc.xml'))
   567             self.PLCManager.SaveXMLFile(os.path.join(self.ProjectPath, 'plc.xml'))
   574         return self.ProjectPath
   571         return self.ProjectPath
   575     
   572     
   576     def PluginXmlFilePath(self, PlugName=None):
   573     def PluginXmlFilePath(self, PlugName=None):
   577         return os.path.join(self.PlugPath(PlugName), "beremiz.xml")
   574         return os.path.join(self.PlugPath(PlugName), "beremiz.xml")
   578 
   575 
   579     def PlugGenerate_C(self, buildpath, current_location, locations, logger):
   576     def PlugGenerate_C(self, buildpath, locations, logger):
   580         """
   577         """
   581         Generate C code
   578         Generate C code
   582         @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5)
       
   583         @param locations: List of complete variables locations \
   579         @param locations: List of complete variables locations \
   584             [(IEC_loc, IEC_Direction, IEC_Type, Name)]\
   580             [(IEC_loc, IEC_Direction, IEC_Type, Name)]\
   585             ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...]
   581             ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...]
   586         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
   582         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
   587         """
   583         """
   661 
   657 
   662         # Eventually create build dir
   658         # Eventually create build dir
   663         if not os.path.exists(buildpath):
   659         if not os.path.exists(buildpath):
   664             os.mkdir(buildpath)
   660             os.mkdir(buildpath)
   665         
   661         
       
   662         logger.flush()
   666         logger.write("Start build in %s\n" % buildpath)
   663         logger.write("Start build in %s\n" % buildpath)
   667         
   664         
   668         # Generate SoftPLC code
   665         # Generate SoftPLC code
   669         if not self._Generate_SoftPLC(logger):
   666         if not self._Generate_SoftPLC(logger):
   670             logger.write_error("SoftPLC code generation failed !\n")
   667             logger.write_error("SoftPLC code generation failed !\n")
   671             return False
   668             return False
   672 
   669 
   673         logger.write("SoftPLC code generation successfull\n")
   670         logger.write("SoftPLC code generation successfull\n")
   674         
   671         
   675         # Generate C code and compilation params from plugin hierarchy
   672         # Generate C code and compilation params from plugin hierarchy
   676         #try:
   673         try:
   677         CFilesAndCFLAGS, LDFLAGS = self._Generate_C(
   674             CFilesAndCFLAGS, LDFLAGS = self._Generate_C(
   678             buildpath, 
   675                 buildpath, 
   679             None, #root has no location
   676                 self.PLCGeneratedLocatedVars,
   680             self.PLCGeneratedLocatedVars,
   677                 logger)
   681             logger)
   678         except Exception, msg:
   682         #except Exception, msg:
   679             logger.write_error("Plugins code generation Failed !\n")
   683         #    logger.write_error("Plugins code generation Failed !\n")
   680             logger.write_error(str(msg))
   684         #    logger.write_error(str(msg))
   681             return False
   685         #    return False
       
   686 
   682 
   687         logger.write("Plugins code generation successfull\n")
   683         logger.write("Plugins code generation successfull\n")
   688 
   684 
   689         # Compile the resulting code into object files.
   685         # Compile the resulting code into object files.
   690         for CFile, CFLAG in CFilesAndCFLAGS:
   686         for CFile, CFLAG in CFilesAndCFLAGS: