plugger.py
changeset 17 ee8cb104dbe0
parent 16 b2c02ca6271e
child 18 0fac6d621a24
equal deleted inserted replaced
16:b2c02ca6271e 17:ee8cb104dbe0
     1 """
     1 """
     2 Base definitions for beremiz plugins
     2 Base definitions for beremiz plugins
     3 """
     3 """
     4 
     4 
     5 import os
     5 import os
       
     6 import plugins
     6 import types
     7 import types
     7 import shutil
     8 import shutil
     8 from xml.dom import minidom
     9 from xml.dom import minidom
     9 import plugins
       
    10 from xmlclass import GenerateClassesFromXSDstring
    10 from xmlclass import GenerateClassesFromXSDstring
       
    11 
       
    12 from PLCControler import PLCControler
    11 
    13 
    12 _BaseParamsClass = GenerateClassesFromXSDstring("""<?xml version="1.0" encoding="ISO-8859-1" ?>
    14 _BaseParamsClass = GenerateClassesFromXSDstring("""<?xml version="1.0" encoding="ISO-8859-1" ?>
    13         <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    15         <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    14           <xsd:element name="BaseParams">
    16           <xsd:element name="BaseParams">
    15             <xsd:complexType>
    17             <xsd:complexType>
    16               <xsd:attribute name="Name" type="xsd:string" use="required"/>
    18               <xsd:attribute name="Name" type="xsd:string" use="required"/>
    17               <xsd:attribute name="IEC_Channel" type="xsd:integer" use="required"  default="-1"/>
    19               <xsd:attribute name="IEC_Channel" type="xsd:integer" use="required"/>
    18               <xsd:attribute name="Enabled" type="xsd:boolean" use="required" default="true"/>
    20               <xsd:attribute name="Enabled" type="xsd:boolean" use="required" default="true"/>
    19             </xsd:complexType>
    21             </xsd:complexType>
    20           </xsd:element>
    22           </xsd:element>
    21         </xsd:schema>""")[0]["BaseParams"]
    23         </xsd:schema>""")[0]["BaseParams"]
    22 
    24 
    33     PluginMethods = []
    35     PluginMethods = []
    34 
    36 
    35     def _AddParamsMembers(self):
    37     def _AddParamsMembers(self):
    36         Classes = GenerateClassesFromXSDstring(self.XSD)[0]
    38         Classes = GenerateClassesFromXSDstring(self.XSD)[0]
    37         self.PlugParams = []
    39         self.PlugParams = []
    38         for name, XSDclass in Classes.items():
    40         Classes = [(name, XSDclass) for name, XSDclass in Classes.items() if XSDclass.IsBaseClass]
    39             if XSDclass.IsBaseClass:
    41         if len(Classes) == 1:
    40                 obj = XSDclass()
    42             name, XSDclass = Classes[0]
    41                 self.PlugParams.append( (name, obj) )
    43             obj = XSDclass()
    42                 setattr(self, name, obj)
    44             self.PlugParams = (name, obj)
    43 
    45             setattr(self, name, obj)
    44     def __init__(self, PlugPath):
    46 
       
    47     def __init__(self):
    45         # Create BaseParam 
    48         # Create BaseParam 
    46         self.BaseParams = _BaseParamsClass()
    49         self.BaseParams = _BaseParamsClass()
    47         self.MandatoryParams = [("BaseParams", self.BaseParams)]
    50         self.MandatoryParams = ("BaseParams", self.BaseParams)
    48         self._AddParamsMembers()
    51         self._AddParamsMembers()
    49         self.PluggedChilds = {}
    52         self.PluggedChilds = {}
       
    53 
       
    54     def PluginBaseXmlFilePath(self, PlugName=None):
       
    55         return os.path.join(self.PlugPath(PlugName), "baseplugin.xml")
    50     
    56     
    51     def PluginXmlFilePath(self, PlugName=None):
    57     def PluginXmlFilePath(self, PlugName=None):
    52         return os.path.join(self.PlugPath(PlugName), "plugin.xml")
    58         return os.path.join(self.PlugPath(PlugName), "plugin.xml")
    53 
    59 
    54     def PlugPath(self,PlugName=None):
    60     def PlugPath(self,PlugName=None):
    60         return False
    66         return False
    61         
    67         
    62     def OnPlugSave(self):
    68     def OnPlugSave(self):
    63         return True
    69         return True
    64 
    70 
       
    71     def GetPlugParamsAttributes(self):
       
    72         return self.PlugParams[1].getElementAttributes()
       
    73     
       
    74     def SetPlugParamsAttribute(self, name, value):
       
    75         attr = getattr(self.PlugParams[1], name, None)
       
    76         if isinstance(attr, types.ClassType):
       
    77             attr.SetValue(value)
       
    78         else:
       
    79             setattr(self.PlugParams[1], name, value)
       
    80 
    65     def PlugRequestSave(self):
    81     def PlugRequestSave(self):
    66         # If plugin do not have corresponding directory
    82         # If plugin do not have corresponding directory
    67         if not os.path.isdir(self.PlugPath(PlugName)):
    83         plugpath = self.PlugPath()
       
    84         if not os.path.isdir(plugpath):
    68             # Create it
    85             # Create it
    69             os.mkdir(self.PlugPath(PlugName))
    86             os.mkdir(plugpath)
    70 
    87 
    71         # generate XML for all XML parameters controllers of the plugin
    88         # generate XML for base XML parameters controller of the plugin
    72         XMLString = '<?xml version="1.0" encoding="UTF-8"?>'
    89         basexmlfilepath = self.PluginBaseXmlFilePath()
    73         for nodeName, XMLController in self.PlugParams + self.MandatoryParams:
    90         if basexmlfilepath:
    74             XMLString += XMLController.generateXMLTextMethod(self, nodeName, 0)
    91             BaseXMLFile = open(basexmlfilepath,'w')
    75         XMLFile = open(self.PluginXmlFilePath(PlugName),'w')
    92             BaseXMLFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
    76         XMLFile.write(XMLString)
    93             BaseXMLFile.write(self.MandatoryParams[1].generateXMLText(self.MandatoryParams[0], 0))
    77         XMLFile.close()
    94             BaseXMLFile.close()
       
    95         
       
    96         # generate XML for XML parameters controller of the plugin
       
    97         xmlfilepath = self.PluginXmlFilePath()
       
    98         if xmlfilepath:
       
    99             XMLFile = open(xmlfilepath,'w')
       
   100             XMLFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
       
   101             XMLFile.write(self.PlugParams[1].generateXMLText(self.PlugParams[0], 0))
       
   102             XMLFile.close()
    78         
   103         
    79         # Call the plugin specific OnPlugSave method
   104         # Call the plugin specific OnPlugSave method
    80         self.OnPlugSave()
   105         result = self.OnPlugSave()
       
   106         if not result:
       
   107             return "Error while saving \"%s\""%self.PlugPath()
    81         
   108         
    82         # go through all childs and do the same
   109         # go through all childs and do the same
    83         for PlugChild in self.IterChilds():
   110         for PlugChild in self.IterChilds():
    84             PlugChild.PlugRequestSave()
   111             result = PlugChild.PlugRequestSave()
       
   112             if result:
       
   113                 return result
       
   114         return None
    85     
   115     
    86     def PlugImport(self, src_PlugPath):
   116     def PlugImport(self, src_PlugPath):
    87         shutil.copytree(src_PlugPath, self.PlugPath)
   117         shutil.copytree(src_PlugPath, self.PlugPath)
    88         return True
   118         return True
    89 
   119 
    90     def PlugGenerate_C(self, buildpath, current_location, locations):
   120     def PlugGenerate_C(self, buildpath, current_location, locations):
    91         """
   121         """
    92         Generate C code
   122         Generate C code
    93         @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5)
   123         @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5)
    94         @param locations: List of complete variables locations \
   124         @param locations: List of complete variables locations \
    95             [(IEC_loc, IEC_Direction IEC_Type, Name)]\
   125             [(IEC_loc, IEC_Direction, IEC_Type, Name)]\
    96             ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...]
   126             ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...]
    97         """
   127         """
    98         return [],""
   128         return [],""
    99     
   129     
   100     def _Generate_C(self, buildpath, current_location, locations):
   130     def _Generate_C(self, buildpath, current_location, locations):
   130             for PlugInstance in PluggedChilds:
   160             for PlugInstance in PluggedChilds:
   131                    yield PlugInstance
   161                    yield PlugInstance
   132     
   162     
   133     def _GetChildBySomething(self, sep, something, matching):
   163     def _GetChildBySomething(self, sep, something, matching):
   134         toks = matching.split(sep,1)
   164         toks = matching.split(sep,1)
   135         for PlugInstance in self.IterChilds:
   165         for PlugInstance in self.IterChilds():
   136             # if match component of the name
   166             # if match component of the name
   137             if getattr(PlugInstance.BaseParams, something) == toks[0]:
   167             if getattr(PlugInstance.BaseParams, something) == toks[0]:
   138                 # if Name have other components
   168                 # if Name have other components
   139                 if len(toks) == 2:
   169                 if len(toks) == 2:
   140                     # Recurse in order to find the latest object
   170                     # Recurse in order to find the latest object
   147     def GetChildByName(self, Name):
   177     def GetChildByName(self, Name):
   148         return self._GetChildBySomething('.',"Name", Name)
   178         return self._GetChildBySomething('.',"Name", Name)
   149 
   179 
   150     def GetChildByIECLocation(self, Location):
   180     def GetChildByIECLocation(self, Location):
   151         return self._GetChildBySomething('_',"IEC_Channel", Name)
   181         return self._GetChildBySomething('_',"IEC_Channel", Name)
       
   182     
       
   183     def GetPlugInfos(self):
       
   184         childs = []
       
   185         for child in self.IterChilds():
       
   186             childs.append(child.GetPlugInfos())
       
   187         return {"name" : self.BaseParams.getName(), "type" : None, "values" : childs}
   152     
   188     
   153     def FindNewIEC_Channel(self, DesiredChannel):
   189     def FindNewIEC_Channel(self, DesiredChannel):
   154         """
   190         """
   155         Changes IEC Channel number to DesiredChannel if available, nearest available if not.
   191         Changes IEC Channel number to DesiredChannel if available, nearest available if not.
   156         @param DesiredChannel: The desired IEC channel (int)
   192         @param DesiredChannel: The desired IEC channel (int)
   215         # if PlugClass is a class factory, call it. (prevent unneeded imports)
   251         # if PlugClass is a class factory, call it. (prevent unneeded imports)
   216         if type(PlugClass) == types.FunctionType:
   252         if type(PlugClass) == types.FunctionType:
   217             PlugClass = PlugClass()
   253             PlugClass = PlugClass()
   218         
   254         
   219         # Eventualy Initialize child instance list for this class of plugin
   255         # Eventualy Initialize child instance list for this class of plugin
   220         PluggedChildsWithSameClass = self.PluggedChilds.setdefault(PlugType,list())
   256         PluggedChildsWithSameClass = self.PluggedChilds.setdefault(PlugType, list())
   221         # Check count
   257         # Check count
   222         if PlugClass.MaxCount and len(PluggedChildsWithSameClass) >= PlugClass.MaxCount:
   258         if getattr(PlugClass, "PlugMaxCount", None) and len(PluggedChildsWithSameClass) >= PlugClass.PlugMaxCount:
   223             raise Exception, "Max count (%d) reached for this plugin of type %s "%(PlugClass.MaxCount, PlugType)
   259             raise Exception, "Max count (%d) reached for this plugin of type %s "%(PlugClass.PlugMaxCount, PlugType)
   224         
   260         
   225         # create the final class, derived of provided plugin and template
   261         # create the final class, derived of provided plugin and template
   226         class FinalPlugClass(PlugClass, PlugTemplate):
   262         class FinalPlugClass(PlugClass, PlugTemplate):
   227             """
   263             """
   228             Plugin class is derivated into FinalPlugClass before being instanciated
   264             Plugin class is derivated into FinalPlugClass before being instanciated
   237                 # Call the base plugin template init - change XSD into class members
   273                 # Call the base plugin template init - change XSD into class members
   238                 PlugTemplate.__init__(_self)
   274                 PlugTemplate.__init__(_self)
   239                 # If dir have already be made, and file exist
   275                 # If dir have already be made, and file exist
   240                 if os.path.isdir(_self.PlugPath(PlugName)) and os.path.isfile(_self.PluginXmlFilePath(PlugName)):
   276                 if os.path.isdir(_self.PlugPath(PlugName)) and os.path.isfile(_self.PluginXmlFilePath(PlugName)):
   241                     #Load the plugin.xml file into parameters members
   277                     #Load the plugin.xml file into parameters members
   242                     _self.LoadXMLParams()
   278                     _self.LoadXMLParams(PlugName)
   243                     # Check that IEC_Channel is not already in use.
   279                     # Check that IEC_Channel is not already in use.
   244                     self.FindNewIEC_Channel(self.BaseParams.getIEC_Channel())
   280                     self.FindNewIEC_Channel(self.BaseParams.getIEC_Channel())
   245                     # Call the plugin real __init__
   281                     # Call the plugin real __init__
   246                     PlugClass.__init__(_self)
   282                     if getattr(PlugClass, "__init__", None):
       
   283                         PlugClass.__init__(_self)
   247                     #Load and init all the childs
   284                     #Load and init all the childs
   248                     _self.LoadChilds()
   285                     _self.LoadChilds()
   249                 else:
   286                 else:
   250                     # If plugin do not have corresponding file/dirs - they will be created on Save
   287                     # If plugin do not have corresponding file/dirs - they will be created on Save
   251                     # Set plugin name
   288                     # Set plugin name
   252                     _self.BaseParams.setName(PlugName)
   289                     _self.BaseParams.setName(PlugName)
       
   290                     os.mkdir(_self.PlugPath())
   253                     # Find an IEC number
   291                     # Find an IEC number
   254                     _self.FindNewIEC_Channel(0)
   292                     _self.FindNewIEC_Channel(0)
   255                     # Call the plugin real __init__
   293                     # Call the plugin real __init__
   256                     PlugClass.__init__(_self)
   294                     if getattr(PlugClass, "__init__", None):
       
   295                         PlugClass.__init__(_self)
       
   296                     _self.PlugRequestSave()
   257 
   297 
   258         # Create the object out of the resulting class
   298         # Create the object out of the resulting class
   259         newPluginOpj = FinalPlugClass()
   299         newPluginOpj = FinalPlugClass()
   260         # Store it in PluggedChils
   300         # Store it in PluggedChils
   261         PluggedChildsWithSameClass.append(newPluginOpj)
   301         PluggedChildsWithSameClass.append(newPluginOpj)
   262         
   302         
   263         return newPluginOpj
   303         return newPluginOpj
   264             
   304             
   265 
   305 
   266     def LoadXMLParams(self):
   306     def LoadXMLParams(self, PlugName = None, test = True):
   267         # PlugParams have been filled, make a local dict to work with
   307         # Get the base xml tree
   268         PlugParams = dict(self.PlugParams + self.MandatoryParams)
   308         basexmlfilepath = self.PluginBaseXmlFilePath(PlugName)
       
   309         if basexmlfilepath:
       
   310             basexmlfile = open(basexmlfilepath, 'r')
       
   311             basetree = minidom.parse(basexmlfile)
       
   312             self.MandatoryParams[1].loadXMLTree(basetree.childNodes[0])
       
   313             basexmlfile.close()
       
   314         
   269         # Get the xml tree
   315         # Get the xml tree
   270         xmlfile = open(self.PluginXmlFilePath(PlugName), 'r')
   316         xmlfilepath = self.PluginXmlFilePath(PlugName)
   271         tree = minidom.parse(xmlfile)
   317         if xmlfilepath:
   272         xmlfile.close()
   318             xmlfile = open(xmlfilepath, 'r')
   273         # for each root elements
   319             tree = minidom.parse(xmlfile)
   274         for subtree in tree.childNodes:
   320             self.PlugParams[1].loadXMLTree(tree.childNodes[0])
   275             # if a plugin specific parameter set
   321             xmlfile.close()
   276             if subtree.nodeName in PlugParams:
   322         
   277                 #Load into associated xmlclass.
   323         if test:
   278                 PlugParams[subtree.nodeName].loadXMLTree(subtree)
   324             # Basic check. Better to fail immediately.
   279         
   325             if not PlugName:
   280         # Basic check. Better to fail immediately.
   326                 PlugName = os.path.split(self.PlugPath())[1].split(NameTypeSeparator)[0]
   281         if(self.BaseParams.getName() != PlugName):
   327             if (self.BaseParams.getName() != PlugName):
   282             raise Exception, "Project tree layout do not match plugin.xml %s!=%s "%(PlugName,self.BaseParams.getName())
   328                 raise Exception, "Project tree layout do not match plugin.xml %s!=%s "%(PlugName, self.BaseParams.getName())
   283         # Now, self.PlugPath() should be OK
   329             # Now, self.PlugPath() should be OK
   284 
   330 
   285     def LoadChilds(self):
   331     def LoadChilds(self):
   286         # Iterate over all PlugName@PlugType in plugin directory, and try to open them
   332         # Iterate over all PlugName@PlugType in plugin directory, and try to open them
   287         for PlugDir in os.listdir(self.PlugPath()):
   333         for PlugDir in os.listdir(self.PlugPath()):
   288             if os.path.isdir(os.path.join(self.PlugPath(),PlugDir)) and \
   334             if os.path.isdir(os.path.join(self.PlugPath(), PlugDir)) and \
   289                PlugDir.count(NameTypeSeparator) == 1:
   335                PlugDir.count(NameTypeSeparator) == 1:
   290                 try:
   336                 try:
   291                     self.PlugAddChild(*PlugDir.split[NameTypeSeparator])
   337                     self.PlugAddChild(*PlugDir.split(NameTypeSeparator))
   292                 except Exception, e:
   338                 except Exception, e:
   293                     print e
   339                     print e
   294 
   340 
       
   341 def _GetClassFunction(name):
       
   342     def GetRootClass():
       
   343         return getattr(__import__("plugins." + name), name).RootClass
       
   344     return GetRootClass
       
   345 
   295 class PluginsRoot(PlugTemplate):
   346 class PluginsRoot(PlugTemplate):
   296 
   347 
   297     # For root object, available Childs Types are modules of the plugin packages.
   348     # For root object, available Childs Types are modules of the plugin packages.
   298     PlugChildsTypes = [(name,lambda : getattr(__import__("plugins." + name), name).RootClass) for name in plugins.__all__]
   349     PlugChildsTypes = [(name, _GetClassFunction(name)) for name in plugins.__all__]
   299 
   350 
   300     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
   351     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
   301     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   352     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   302       <xsd:simpleType name="Win32Compiler">
   353       <xsd:simpleType name="Win32Compiler">
   303         <xsd:restriction base="xsd:string">
   354         <xsd:restriction base="xsd:string">
   312             <xsd:complexType>
   363             <xsd:complexType>
   313               <xsd:choice>
   364               <xsd:choice>
   314                 <xsd:element name="Win32">
   365                 <xsd:element name="Win32">
   315                   <xsd:complexType>
   366                   <xsd:complexType>
   316                     <xsd:attribute name="ToolChain" type="ppx:Win32Compiler" use="required" default="MinGW"/>
   367                     <xsd:attribute name="ToolChain" type="ppx:Win32Compiler" use="required" default="MinGW"/>
   317                     <xsd:attribute name="Priority" type="xsd:integer" use="required" default="0"/>
   368                     <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
   318                   </xsd:complexType>
   369                   </xsd:complexType>
   319                 </xsd:element>
   370                 </xsd:element>
   320                 <xsd:element name="Linux">
   371                 <xsd:element name="Linux">
   321                   <xsd:complexType>
   372                   <xsd:complexType>
   322                     <xsd:attribute name="Compiler" type="xsd:string" use="required" default="gcc"/>
   373                     <xsd:attribute name="Compiler" type="xsd:string" use="required" default="gcc"/>
   323                     <xsd:attribute name="Nice" type="xsd:integer" use="required" default="0"/>
   374                     <xsd:attribute name="Nice" type="xsd:integer" use="required"/>
   324                   </xsd:complexType>
   375                   </xsd:complexType>
   325                 </xsd:element>
   376                 </xsd:element>
   326                 <xsd:element name="Xenomai">
   377                 <xsd:element name="Xenomai">
   327                   <xsd:complexType>
   378                   <xsd:complexType>
   328                     <xsd:attribute name="xeno-config" type="xsd:string" use="required" default="/usr/xenomai/"/>
   379                     <xsd:attribute name="xeno-config" type="xsd:string" use="required" default="/usr/xenomai/"/>
   329                     <xsd:attribute name="Compiler" type="xsd:string" use="required" default="0"/>
   380                     <xsd:attribute name="Compiler" type="xsd:string" use="required"/>
   330                     <xsd:attribute name="Priority" type="xsd:integer" use="required" default="0"/>
   381                     <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
   331                   </xsd:complexType>
   382                   </xsd:complexType>
   332                 </xsd:element>
   383                 </xsd:element>
   333                 <xsd:element name="RTAI">
   384                 <xsd:element name="RTAI">
   334                   <xsd:complexType>
   385                   <xsd:complexType>
   335                     <xsd:attribute name="xeno-config" type="xsd:string" use="required" default="0"/>
   386                     <xsd:attribute name="xeno-config" type="xsd:string" use="required"/>
   336                     <xsd:attribute name="Compiler" type="xsd:string" use="required" default="0"/>
   387                     <xsd:attribute name="Compiler" type="xsd:string" use="required"/>
   337                     <xsd:attribute name="Priority" type="xsd:integer" use="required" default="0"/>
   388                     <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
   338                   </xsd:complexType>
   389                   </xsd:complexType>
   339                 </xsd:element>
   390                 </xsd:element>
   340                 <xsd:element name="Library">
   391                 <xsd:element name="Library">
   341                   <xsd:complexType>
   392                   <xsd:complexType>
   342                     <xsd:attribute name="Dynamic" type="xsd:boolean" default="true"/>
   393                     <xsd:attribute name="Dynamic" type="xsd:boolean" use="required" default="true"/>
   343                     <xsd:attribute name="Compiler" type="xsd:string" use="required" default="0"/>
   394                     <xsd:attribute name="Compiler" type="xsd:string" use="required"/>
   344                   </xsd:complexType>
   395                   </xsd:complexType>
   345                 </xsd:element>
   396                 </xsd:element>
   346               </xsd:choice>
   397               </xsd:choice>
   347             </xsd:complexType>
   398             </xsd:complexType>
   348           </xsd:element>
   399           </xsd:element>
   349         </xsd:complexType>
   400         </xsd:complexType>
   350       </xsd:element>
   401       </xsd:element>
   351     </xsd:schema>
   402     </xsd:schema>
   352     """
   403     """
   353 
   404 
   354     def __init__(self, ProjectPath):
   405     def __init__(self):
       
   406         PlugTemplate.__init__(self)
   355         # self is the parent
   407         # self is the parent
   356         self.PlugParent = None
   408         self.PlugParent = None
   357         # Keep track of the plugin type name
   409         # Keep track of the plugin type name
   358         self.PlugType = "Beremiz"
   410         self.PlugType = "Beremiz"
   359         # Keep track of the root plugin (i.e. project path)
   411         
   360         self.ProjectPath = ProjectPath
   412         self.ProjectPath = ""
       
   413         self.PLCManager = None
       
   414     
       
   415     def HasProjectOpened(self):
       
   416         """
       
   417         Return if a project is actually opened
       
   418         """
       
   419         return self.ProjectPath != ""
       
   420     
       
   421     def GetProjectPath(self):
       
   422         return self.ProjectPath
       
   423     
       
   424     def GetTargetTypes(self):
       
   425         return self.BeremizRoot.TargetType.getChoices().keys()
       
   426     
       
   427     def ChangeTargetType(self, target_type):
       
   428         self.BeremizRoot.TargetType.addContent(target_type)
       
   429         
       
   430     def GetTargetAttributes(self):
       
   431         content = self.BeremizRoot.TargetType.getContent()
       
   432         if content:
       
   433             return content["value"].getElementAttributes()
       
   434         else:
       
   435             return []
       
   436         
       
   437     def SetTargetAttribute(self, name, value):
       
   438         content = self.BeremizRoot.TargetType.getContent()
       
   439         if content:
       
   440             attr = getattr(content["value"], name, None)
       
   441             if isinstance(attr, types.ClassType):
       
   442                 attr.SetValue(value)
       
   443             else:
       
   444                 setattr(content["value"], name, value)
       
   445     
       
   446     def GetTargetType(self):
       
   447         content = self.BeremizRoot.TargetType.getContent()
       
   448         if content:
       
   449             return content["name"]
       
   450         else:
       
   451             return ""
       
   452     
       
   453     def NewProject(self, ProjectPath, PLCParams):
       
   454         """
       
   455         Create a new project in an empty folder
       
   456         @param ProjectPath: path of the folder where project have to be created
       
   457         @param PLCParams: properties of the PLCOpen program created
       
   458         """
       
   459         # Verify that choosen folder is empty
       
   460         if not os.path.isdir(ProjectPath) or len(os.listdir(ProjectPath)) > 0:
       
   461             return "Folder choosen isn't empty. You can't use it for a new project!"
       
   462         # Create Controler for PLCOpen program
       
   463         self.PLCManager = PLCControler()
       
   464         self.PLCManager.CreateNewProject(PLCParams.pop("projectName"))
       
   465         self.PLCManager.SetProjectProperties(properties = PLCParams)
   361         # Change XSD into class members
   466         # Change XSD into class members
   362         self._AddParamsMembers()
   467         self._AddParamsMembers()
   363         self.PluggedChilds = {}
   468         self.PluggedChilds = {}
   364         # No IEC channel, name, etc...
   469         # No IEC channel, name, etc...
   365         self.MandatoryParams = []
   470         self.MandatoryParams = []
       
   471         # Keep track of the root plugin (i.e. project path)
       
   472         self.ProjectPath = ProjectPath
       
   473         self.BaseParams.setName(os.path.split(ProjectPath)[1])
       
   474         return None
       
   475         
       
   476     def LoadProject(self, ProjectPath):
       
   477         """
       
   478         Load a project contained in a folder
       
   479         @param ProjectPath: path of the project folder
       
   480         """
       
   481         # Verify that project contains a PLCOpen program
       
   482         plc_file = os.path.join(ProjectPath, "plc.xml")
       
   483         if not os.path.isfile(plc_file):
       
   484             return "Folder choosen doesn't contain a program. It's not a valid project!"
       
   485         # Create Controler for PLCOpen program
       
   486         self.PLCManager = PLCControler()
       
   487         # Load PLCOpen file
       
   488         result = self.PLCManager.OpenXMLFile(plc_file)
       
   489         if result:
       
   490             return result
       
   491         # Change XSD into class members
       
   492         self._AddParamsMembers()
       
   493         self.PluggedChilds = {}
       
   494         # No IEC channel, name, etc...
       
   495         self.MandatoryParams = None
       
   496         # Keep track of the root plugin (i.e. project path)
       
   497         self.ProjectPath = ProjectPath
   366         # If dir have already be made, and file exist
   498         # If dir have already be made, and file exist
   367         if os.path.isdir(_self.PlugPath(PlugName)) and os.path.isfile(_self.PluginXmlFilePath(PlugName)):
   499         if os.path.isdir(self.PlugPath()) and os.path.isfile(self.PluginXmlFilePath()):
   368             #Load the plugin.xml file into parameters members
   500             #Load the plugin.xml file into parameters members
   369             _self.LoadXMLParams()
   501             result = self.LoadXMLParams(test = False)
       
   502             if result:
       
   503                 return result
   370             #Load and init all the childs
   504             #Load and init all the childs
   371             _self.LoadChilds()
   505             self.LoadChilds()
   372 
   506         self.BaseParams.setName(os.path.split(ProjectPath)[1])
   373     def PlugPath(self,PlugName=None):
   507         return None
       
   508     
       
   509     def SaveProject(self):
       
   510         if not self.PLCManager.SaveXMLFile():
       
   511             self.PLCManager.SaveXMLFile(os.path.join(self.ProjectPath, 'plc.xml'))
       
   512         self.PlugRequestSave()
       
   513     
       
   514     def PlugPath(self, PlugName=None):
   374         return self.ProjectPath
   515         return self.ProjectPath
   375         
   516     
       
   517     def PluginBaseXmlFilePath(self, PlugName=None):
       
   518         return None
       
   519     
   376     def PluginXmlFilePath(self, PlugName=None):
   520     def PluginXmlFilePath(self, PlugName=None):
   377         return os.path.join(self.PlugPath(PlugName), "beremiz.xml")
   521         return os.path.join(self.PlugPath(PlugName), "beremiz.xml")
   378     
       
   379