PLCGenerator.py
changeset 340 5a305b7c6735
parent 307 fd1f6ae26d4f
child 356 f6453b89e7f9
equal deleted inserted replaced
339:d4977f6d1621 340:5a305b7c6735
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    25 from plcopen import plcopen
    25 from plcopen import plcopen
    26 from plcopen.structures import *
    26 from plcopen.structures import *
    27 from types import *
    27 from types import *
       
    28 import re
    28 
    29 
    29 
    30 
    30 # Dictionary associating PLCOpen variable categories to the corresponding 
    31 # Dictionary associating PLCOpen variable categories to the corresponding 
    31 # IEC 61131-3 variable categories
    32 # IEC 61131-3 variable categories
    32 varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT", 
    33 varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT", 
   220             
   221             
   221             # Getting POU model from project
   222             # Getting POU model from project
   222             pou = self.Project.getpou(pou_name)
   223             pou = self.Project.getpou(pou_name)
   223             pou_type = pou.getpouType()
   224             pou_type = pou.getpouType()
   224             # Verify that POU type exists
   225             # Verify that POU type exists
   225             if pou_type in pouTypeNames:
   226             if pouTypeNames.has_key(pou_type):
   226                 # Create a POU program generator
   227                 # Create a POU program generator
   227                 pou_program = PouProgramGenerator(self, pou.getname(), pouTypeNames[pou_type], self.Errors, self.Warnings)
   228                 pou_program = PouProgramGenerator(self, pou.getname(), pouTypeNames[pou_type], self.Errors, self.Warnings)
   228                 program = pou_program.GenerateProgram(pou)
   229                 program = pou_program.GenerateProgram(pou)
   229                 self.Program += program
   230                 self.Program += program
   230             else:
   231             else:
   231                 raise PLCGenException, "Undefined pou type \"%s\""%pou_type
   232                 raise PLCGenException, "Undefined pou type \"%s\""%pou_type
       
   233     
       
   234     # Generate a POU defined and used in text
       
   235     def GeneratePouProgramInText(self, text):
       
   236         for pou_name in self.PouComputed.keys():
       
   237             model = re.compile("(?:^|[^0-9^A-Z])%s(?:$|[^0-9^A-Z])"%pou_name.upper())
       
   238             if model.search(text) is not None:
       
   239                 self.GeneratePouProgram(pou_name)
   232     
   240     
   233     # Generate a configuration from its model
   241     # Generate a configuration from its model
   234     def GenerateConfiguration(self, configuration):
   242     def GenerateConfiguration(self, configuration):
   235         tagname = self.Controler.ComputeConfigurationName(configuration.getname())
   243         tagname = self.Controler.ComputeConfigurationName(configuration.getname())
   236         config = [("\nCONFIGURATION ", ()),
   244         config = [("\nCONFIGURATION ", ()),
   612                             for connection in self.ExtractRelatedConnections(instance.connectionPointOut):
   620                             for connection in self.ExtractRelatedConnections(instance.connectionPointOut):
   613                                 self.ConnectionTypes[connection] = var_type
   621                                 self.ConnectionTypes[connection] = var_type
   614                         if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   622                         if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   615                             self.ConnectionTypes[instance.connectionPointIn] = var_type
   623                             self.ConnectionTypes[instance.connectionPointIn] = var_type
   616                             connected = self.GetConnectedConnector(instance.connectionPointIn, body)
   624                             connected = self.GetConnectedConnector(instance.connectionPointIn, body)
   617                             if connected and connected not in self.ConnectionTypes:
   625                             if connected and not self.ConnectionTypes.has_key(connected):
   618                                 for connection in self.ExtractRelatedConnections(connected):
   626                                 for connection in self.ExtractRelatedConnections(connected):
   619                                     self.ConnectionTypes[connection] = var_type
   627                                     self.ConnectionTypes[connection] = var_type
   620                 elif isinstance(instance, (plcopen.ldObjects_contact, plcopen.ldObjects_coil)):
   628                 elif isinstance(instance, (plcopen.ldObjects_contact, plcopen.ldObjects_coil)):
   621                     for connection in self.ExtractRelatedConnections(instance.connectionPointOut):
   629                     for connection in self.ExtractRelatedConnections(instance.connectionPointOut):
   622                         self.ConnectionTypes[connection] = "BOOL"
   630                         self.ConnectionTypes[connection] = "BOOL"
   623                     self.ConnectionTypes[instance.connectionPointIn] = "BOOL"
   631                     self.ConnectionTypes[instance.connectionPointIn] = "BOOL"
   624                     connected = self.GetConnectedConnector(instance.connectionPointIn, body)
   632                     connected = self.GetConnectedConnector(instance.connectionPointIn, body)
   625                     if connected and connected not in self.ConnectionTypes:
   633                     if connected and not self.ConnectionTypes.has_key(connected):
   626                         for connection in self.ExtractRelatedConnections(connected):
   634                         for connection in self.ExtractRelatedConnections(connected):
   627                             self.ConnectionTypes[connection] = "BOOL"
   635                             self.ConnectionTypes[connection] = "BOOL"
   628                 elif isinstance(instance, plcopen.ldObjects_leftPowerRail):
   636                 elif isinstance(instance, plcopen.ldObjects_leftPowerRail):
   629                     for connection in instance.getconnectionPointOut():
   637                     for connection in instance.getconnectionPointOut():
   630                         for related in self.ExtractRelatedConnections(connection):
   638                         for related in self.ExtractRelatedConnections(connection):
   631                             self.ConnectionTypes[related] = "BOOL"
   639                             self.ConnectionTypes[related] = "BOOL"
   632                 elif isinstance(instance, plcopen.ldObjects_rightPowerRail):
   640                 elif isinstance(instance, plcopen.ldObjects_rightPowerRail):
   633                     for connection in instance.getconnectionPointIn():
   641                     for connection in instance.getconnectionPointIn():
   634                         self.ConnectionTypes[connection] = "BOOL"
   642                         self.ConnectionTypes[connection] = "BOOL"
   635                         connected = self.GetConnectedConnector(connection, body)
   643                         connected = self.GetConnectedConnector(connection, body)
   636                         if connected and connected not in self.ConnectionTypes:
   644                         if connected and not self.ConnectionTypes.has_key(connected):
   637                             for connection in self.ExtractRelatedConnections(connected):
   645                             for connection in self.ExtractRelatedConnections(connected):
   638                                 self.ConnectionTypes[connection] = "BOOL"
   646                                 self.ConnectionTypes[connection] = "BOOL"
   639                 elif isinstance(instance, plcopen.sfcObjects_transition):
   647                 elif isinstance(instance, plcopen.sfcObjects_transition):
   640                     content = instance.condition.getcontent()
   648                     content = instance.condition.getcontent()
   641                     if content["name"] == "connection" and len(content["value"]) == 1:
   649                     if content["name"] == "connection" and len(content["value"]) == 1:
   642                         connected = self.GetLinkedConnector(content["value"][0], body)
   650                         connected = self.GetLinkedConnector(content["value"][0], body)
   643                         if connected and connected not in self.ConnectionTypes:
   651                         if connected and not self.ConnectionTypes.has_key(connected):
   644                             for connection in self.ExtractRelatedConnections(connected):
   652                             for connection in self.ExtractRelatedConnections(connected):
   645                                 self.ConnectionTypes[connection] = "BOOL"
   653                                 self.ConnectionTypes[connection] = "BOOL"
       
   654                 elif isinstance(instance, plcopen.commonObjects_continuation):
       
   655                     name = instance.getname()
       
   656                     connector = None
       
   657                     for element in body.getcontentInstances():
       
   658                         if isinstance(element, plcopen.commonObjects_connector) and element.getname() == name:
       
   659                             if connector is not None:
       
   660                                 raise PLCGenException, "More than one connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name)
       
   661                             connector = element
       
   662                     if connector is not None:
       
   663                         undefined = [instance.connectionPointOut, connector.connectionPointIn]
       
   664                         connected = self.GetConnectedConnector(connector.connectionPointIn, body)
       
   665                         if connected:
       
   666                             undefined.append(connected)
       
   667                         related = []
       
   668                         for connection in undefined:
       
   669                             if self.ConnectionTypes.has_key(connection):
       
   670                                 var_type = self.ConnectionTypes[connection]
       
   671                             else:
       
   672                                 related.extend(self.ExtractRelatedConnections(connection))
       
   673                         if var_type.startswith("ANY") and len(related) > 0:
       
   674                             self.RelatedConnections.append(related)
       
   675                         else:
       
   676                             for connection in related:
       
   677                                 self.ConnectionTypes[connection] = var_type
       
   678                     else:
       
   679                         raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name)
   646                 elif isinstance(instance, plcopen.fbdObjects_block):
   680                 elif isinstance(instance, plcopen.fbdObjects_block):
   647                     block_infos = self.GetBlockType(instance.gettypeName())
   681                     block_infos = self.GetBlockType(instance.gettypeName())
   648                     undefined = {}
   682                     undefined = {}
   649                     for variable in instance.outputVariables.getvariable():
   683                     for variable in instance.outputVariables.getvariable():
   650                         output_name = variable.getformalParameter()
   684                         output_name = variable.getformalParameter()
   651                         if output_name == "ENO":
   685                         if output_name == "ENO":
   652                             for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
   686                             for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
   653                                 self.ConnectionTypes[connection] = "BOOL"
   687                                 self.ConnectionTypes[connection] = "BOOL"
   654                         else:
   688                         else:
   655                             for oname, otype, oqualifier in block_infos["outputs"]:
   689                             for oname, otype, oqualifier in block_infos["outputs"]:
   656                                 if output_name == oname and variable.connectionPointOut not in self.ConnectionTypes:
   690                                 if output_name == oname:
   657                                     if otype.startswith("ANY"):
   691                                     if otype.startswith("ANY"):
   658                                         if otype not in undefined:
   692                                         if not undefined.has_key(otype):
   659                                             undefined[otype] = []
   693                                             undefined[otype] = []
   660                                         undefined[otype].append(variable.connectionPointOut)
   694                                         undefined[otype].append(variable.connectionPointOut)
   661                                     else:
   695                                     elif not self.ConnectionTypes.has_key(variable.connectionPointOut):
   662                                         for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
   696                                         for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
   663                                             self.ConnectionTypes[connection] = otype
   697                                             self.ConnectionTypes[connection] = otype
   664                     for variable in instance.inputVariables.getvariable():
   698                     for variable in instance.inputVariables.getvariable():
   665                         input_name = variable.getformalParameter()
   699                         input_name = variable.getformalParameter()
   666                         if input_name == "EN":
   700                         if input_name == "EN":
   668                                 self.ConnectionTypes[connection] = "BOOL"
   702                                 self.ConnectionTypes[connection] = "BOOL"
   669                         for iname, itype, iqualifier in block_infos["inputs"]:
   703                         for iname, itype, iqualifier in block_infos["inputs"]:
   670                             if input_name == iname:
   704                             if input_name == iname:
   671                                 connected = self.GetConnectedConnector(variable.connectionPointIn, body)
   705                                 connected = self.GetConnectedConnector(variable.connectionPointIn, body)
   672                                 if itype.startswith("ANY"):
   706                                 if itype.startswith("ANY"):
   673                                     if itype not in undefined:
   707                                     if not undefined.has_key(itype):
   674                                         undefined[itype] = []
   708                                         undefined[itype] = []
   675                                     undefined[itype].append(variable.connectionPointIn)
   709                                     undefined[itype].append(variable.connectionPointIn)
   676                                     if connected:
   710                                     if connected:
   677                                         undefined[itype].append(connected)
   711                                         undefined[itype].append(connected)
   678                                 else:
   712                                 else:
   679                                     self.ConnectionTypes[variable.connectionPointIn] = itype
   713                                     self.ConnectionTypes[variable.connectionPointIn] = itype
   680                                     if connected and connected not in self.ConnectionTypes:
   714                                     if connected and not self.ConnectionTypes.has_key(connected):
   681                                         for connection in self.ExtractRelatedConnections(connected):
   715                                         for connection in self.ExtractRelatedConnections(connected):
   682                                             self.ConnectionTypes[connection] = itype
   716                                             self.ConnectionTypes[connection] = itype
   683                     for var_type, connections in undefined.items():
   717                     for var_type, connections in undefined.items():
   684                         related = []
   718                         related = []
   685                         for connection in connections:
   719                         for connection in connections:
   686                             if connection in self.ConnectionTypes:
   720                             if self.ConnectionTypes.has_key(connection):
   687                                 var_type = self.ConnectionTypes[connection]
   721                                 var_type = self.ConnectionTypes[connection]
   688                             else:
   722                             else:
   689                                 related.extend(self.ExtractRelatedConnections(connection))
   723                                 related.extend(self.ExtractRelatedConnections(connection))
   690                         if var_type.startswith("ANY") and len(related) > 0:
   724                         if var_type.startswith("ANY") and len(related) > 0:
   691                             self.RelatedConnections.append(related)
   725                             self.RelatedConnections.append(related)
   696     def ComputeProgram(self, pou):
   730     def ComputeProgram(self, pou):
   697         body = pou.getbody()
   731         body = pou.getbody()
   698         body_content = body.getcontent()
   732         body_content = body.getcontent()
   699         body_type = body_content["name"]
   733         body_type = body_content["name"]
   700         if body_type in ["IL","ST"]:
   734         if body_type in ["IL","ST"]:
   701             self.Program = [(ReIndentText(body_content["value"].gettext(), len(self.CurrentIndent)), 
   735             text = body_content["value"].gettext()
       
   736             self.ParentGenerator.GeneratePouProgramInText(text.upper())
       
   737             self.Program = [(ReIndentText(text, len(self.CurrentIndent)), 
   702                             (self.TagName, "body", len(self.CurrentIndent)))]
   738                             (self.TagName, "body", len(self.CurrentIndent)))]
   703         elif body_type == "SFC":
   739         elif body_type == "SFC":
   704             self.IndentRight()
   740             self.IndentRight()
   705             for instance in body.getcontentInstances():
   741             for instance in body.getcontentInstances():
   706                 if isinstance(instance, plcopen.sfcObjects_step):
   742                 if isinstance(instance, plcopen.sfcObjects_step):