PLCGenerator.py
changeset 1418 c97dc5281419
parent 1358 fe7770a30527
child 1420 71b1545d746f
equal deleted inserted replaced
1417:374238039643 1418:c97dc5281419
     1 #!/usr/bin/env python
     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     2 # -*- coding: utf-8 -*-
     3 
     3 
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
     5 #based on the plcopen standard. 
     5 #based on the plcopen standard.
     6 #
     6 #
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     8 #
     8 #
     9 #See COPYING file for copyrights details.
     9 #See COPYING file for copyrights details.
    10 #
    10 #
    25 from plcopen import PLCOpenParser
    25 from plcopen import PLCOpenParser
    26 from plcopen.structures import *
    26 from plcopen.structures import *
    27 from types import *
    27 from types import *
    28 import re
    28 import re
    29 
    29 
    30 # Dictionary associating PLCOpen variable categories to the corresponding 
    30 # Dictionary associating PLCOpen variable categories to the corresponding
    31 # IEC 61131-3 variable categories
    31 # IEC 61131-3 variable categories
    32 varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT", 
    32 varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT",
    33                 "outputVars" : "VAR_OUTPUT", "inOutVars" : "VAR_IN_OUT", "externalVars" : "VAR_EXTERNAL",
    33                 "outputVars" : "VAR_OUTPUT", "inOutVars" : "VAR_IN_OUT", "externalVars" : "VAR_EXTERNAL",
    34                 "globalVars" : "VAR_GLOBAL", "accessVars" : "VAR_ACCESS"}
    34                 "globalVars" : "VAR_GLOBAL", "accessVars" : "VAR_ACCESS"}
    35 
    35 
    36 
    36 
    37 # Dictionary associating PLCOpen POU categories to the corresponding 
    37 # Dictionary associating PLCOpen POU categories to the corresponding
    38 # IEC 61131-3 POU categories
    38 # IEC 61131-3 POU categories
    39 pouTypeNames = {"function" : "FUNCTION", "functionBlock" : "FUNCTION_BLOCK", "program" : "PROGRAM"}
    39 pouTypeNames = {"function" : "FUNCTION", "functionBlock" : "FUNCTION_BLOCK", "program" : "PROGRAM"}
    40 
    40 
    41 
    41 
    42 errorVarTypes = {
    42 errorVarTypes = {
   123     def GenerateDataType(self, datatype_name):
   123     def GenerateDataType(self, datatype_name):
   124         # Verify that data type hasn't been generated yet
   124         # Verify that data type hasn't been generated yet
   125         if not self.DatatypeComputed.get(datatype_name, True):
   125         if not self.DatatypeComputed.get(datatype_name, True):
   126             # If not mark data type as computed
   126             # If not mark data type as computed
   127             self.DatatypeComputed[datatype_name] = True
   127             self.DatatypeComputed[datatype_name] = True
   128             
   128 
   129             # Getting datatype model from project
   129             # Getting datatype model from project
   130             datatype = self.Project.getdataType(datatype_name)
   130             datatype = self.Project.getdataType(datatype_name)
   131             tagname = self.Controler.ComputeDataTypeName(datatype.getname())
   131             tagname = self.Controler.ComputeDataTypeName(datatype.getname())
   132             datatype_def = [("  ", ()), 
   132             datatype_def = [("  ", ()),
   133                             (datatype.getname(), (tagname, "name")),
   133                             (datatype.getname(), (tagname, "name")),
   134                             (" : ", ())]
   134                             (" : ", ())]
   135             basetype_content = datatype.baseType.getcontent()
   135             basetype_content = datatype.baseType.getcontent()
   136             basetype_content_type = basetype_content.getLocalTag()
   136             basetype_content_type = basetype_content.getLocalTag()
   137             # Data type derived directly from a user defined type 
   137             # Data type derived directly from a user defined type
   138             if basetype_content_type == "derived":
   138             if basetype_content_type == "derived":
   139                 basetype_name = basetype_content.getname()
   139                 basetype_name = basetype_content.getname()
   140                 self.GenerateDataType(basetype_name)
   140                 self.GenerateDataType(basetype_name)
   141                 datatype_def += [(basetype_name, (tagname, "base"))]
   141                 datatype_def += [(basetype_name, (tagname, "base"))]
   142             # Data type is a subrange
   142             # Data type is a subrange
   143             elif basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]:
   143             elif basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]:
   144                 base_type = basetype_content.baseType.getcontent()
   144                 base_type = basetype_content.baseType.getcontent()
   145                 base_type_type = base_type.getLocalTag()
   145                 base_type_type = base_type.getLocalTag()
   146                 # Subrange derived directly from a user defined type 
   146                 # Subrange derived directly from a user defined type
   147                 if base_type_type == "derived":
   147                 if base_type_type == "derived":
   148                     basetype_name = base_type_type.getname()
   148                     basetype_name = base_type_type.getname()
   149                     self.GenerateDataType(basetype_name)
   149                     self.GenerateDataType(basetype_name)
   150                 # Subrange derived directly from an elementary type 
   150                 # Subrange derived directly from an elementary type
   151                 else:
   151                 else:
   152                     basetype_name = base_type_type
   152                     basetype_name = base_type_type
   153                 min_value = basetype_content.range.getlower()
   153                 min_value = basetype_content.range.getlower()
   154                 max_value = basetype_content.range.getupper()
   154                 max_value = basetype_content.range.getupper()
   155                 datatype_def += [(basetype_name, (tagname, "base")),
   155                 datatype_def += [(basetype_name, (tagname, "base")),
   160                                  (")",())]
   160                                  (")",())]
   161             # Data type is an enumerated type
   161             # Data type is an enumerated type
   162             elif basetype_content_type == "enum":
   162             elif basetype_content_type == "enum":
   163                 values = [[(value.getname(), (tagname, "value", i))]
   163                 values = [[(value.getname(), (tagname, "value", i))]
   164                           for i, value in enumerate(
   164                           for i, value in enumerate(
   165                               basetype_content.xpath("ppx:values/ppx:value", 
   165                               basetype_content.xpath("ppx:values/ppx:value",
   166                                   namespaces=PLCOpenParser.NSMAP))]
   166                                   namespaces=PLCOpenParser.NSMAP))]
   167                 datatype_def += [("(", ())]
   167                 datatype_def += [("(", ())]
   168                 datatype_def += JoinList([(", ", ())], values)
   168                 datatype_def += JoinList([(", ", ())], values)
   169                 datatype_def += [(")", ())]
   169                 datatype_def += [(")", ())]
   170             # Data type is an array
   170             # Data type is an array
   171             elif basetype_content_type == "array":
   171             elif basetype_content_type == "array":
   172                 base_type = basetype_content.baseType.getcontent()
   172                 base_type = basetype_content.baseType.getcontent()
   173                 base_type_type = base_type.getLocalTag()
   173                 base_type_type = base_type.getLocalTag()
   174                 # Array derived directly from a user defined type 
   174                 # Array derived directly from a user defined type
   175                 if base_type_type == "derived":
   175                 if base_type_type == "derived":
   176                     basetype_name = base_type.getname()
   176                     basetype_name = base_type.getname()
   177                     self.GenerateDataType(basetype_name)
   177                     self.GenerateDataType(basetype_name)
   178                 # Array derived directly from an elementary type 
   178                 # Array derived directly from an elementary type
   179                 else:
   179                 else:
   180                     basetype_name = base_type_type.upper()
   180                     basetype_name = base_type_type.upper()
   181                 dimensions = [[("%s"%dimension.getlower(), (tagname, "range", i, "lower")),
   181                 dimensions = [[("%s"%dimension.getlower(), (tagname, "range", i, "lower")),
   182                                ("..", ()),
   182                                ("..", ()),
   183                                ("%s"%dimension.getupper(), (tagname, "range", i, "upper"))] 
   183                                ("%s"%dimension.getupper(), (tagname, "range", i, "upper"))]
   184                               for i, dimension in enumerate(basetype_content.getdimension())]
   184                               for i, dimension in enumerate(basetype_content.getdimension())]
   185                 datatype_def += [("ARRAY [", ())]
   185                 datatype_def += [("ARRAY [", ())]
   186                 datatype_def += JoinList([(",", ())], dimensions)
   186                 datatype_def += JoinList([(",", ())], dimensions)
   187                 datatype_def += [("] OF " , ()),
   187                 datatype_def += [("] OF " , ()),
   188                                  (basetype_name, (tagname, "base"))]
   188                                  (basetype_name, (tagname, "base"))]
   190             elif basetype_content_type == "struct":
   190             elif basetype_content_type == "struct":
   191                 elements = []
   191                 elements = []
   192                 for i, element in enumerate(basetype_content.getvariable()):
   192                 for i, element in enumerate(basetype_content.getvariable()):
   193                     element_type = element.type.getcontent()
   193                     element_type = element.type.getcontent()
   194                     element_type_type = element_type.getLocalTag()
   194                     element_type_type = element_type.getLocalTag()
   195                     # Structure element derived directly from a user defined type 
   195                     # Structure element derived directly from a user defined type
   196                     if element_type_type == "derived":
   196                     if element_type_type == "derived":
   197                         elementtype_name = element_type.getname()
   197                         elementtype_name = element_type.getname()
   198                         self.GenerateDataType(elementtype_name)
   198                         self.GenerateDataType(elementtype_name)
   199                     elif element_type_type == "array":
   199                     elif element_type_type == "array":
   200                         base_type = element_type.baseType.getcontent()
   200                         base_type = element_type.baseType.getcontent()
   201                         base_type_type = base_type.getLocalTag()
   201                         base_type_type = base_type.getLocalTag()
   202                         # Array derived directly from a user defined type 
   202                         # Array derived directly from a user defined type
   203                         if base_type_type == "derived":
   203                         if base_type_type == "derived":
   204                             basetype_name = base_type.getname()
   204                             basetype_name = base_type.getname()
   205                             self.GenerateDataType(basetype_name)
   205                             self.GenerateDataType(basetype_name)
   206                         # Array derived directly from an elementary type 
   206                         # Array derived directly from an elementary type
   207                         else:
   207                         else:
   208                             basetype_name = base_type_type.upper()
   208                             basetype_name = base_type_type.upper()
   209                         dimensions = ["%s..%s" % (dimension.getlower(), dimension.getupper())
   209                         dimensions = ["%s..%s" % (dimension.getlower(), dimension.getupper())
   210                                       for dimension in element_type.getdimension()]
   210                                       for dimension in element_type.getdimension()]
   211                         elementtype_name = "ARRAY [%s] OF %s" % (",".join(dimensions), basetype_name)
   211                         elementtype_name = "ARRAY [%s] OF %s" % (",".join(dimensions), basetype_name)
   212                     # Structure element derived directly from an elementary type 
   212                     # Structure element derived directly from an elementary type
   213                     else:
   213                     else:
   214                         elementtype_name = element_type_type.upper()
   214                         elementtype_name = element_type_type.upper()
   215                     element_text = [("\n    ", ()),
   215                     element_text = [("\n    ", ()),
   216                                     (element.getname(), (tagname, "struct", i, "name")),
   216                                     (element.getname(), (tagname, "struct", i, "name")),
   217                                     (" : ", ()),
   217                                     (" : ", ()),
   222                     element_text.append((";", ()))
   222                     element_text.append((";", ()))
   223                     elements.append(element_text)
   223                     elements.append(element_text)
   224                 datatype_def += [("STRUCT", ())]
   224                 datatype_def += [("STRUCT", ())]
   225                 datatype_def += JoinList([("", ())], elements)
   225                 datatype_def += JoinList([("", ())], elements)
   226                 datatype_def += [("\n  END_STRUCT", ())]
   226                 datatype_def += [("\n  END_STRUCT", ())]
   227             # Data type derived directly from a elementary type 
   227             # Data type derived directly from a elementary type
   228             else:
   228             else:
   229                 datatype_def += [(basetype_content_type.upper(), (tagname, "base"))]
   229                 datatype_def += [(basetype_content_type.upper(), (tagname, "base"))]
   230             # Data type has an initial value
   230             # Data type has an initial value
   231             if datatype.initialValue is not None:
   231             if datatype.initialValue is not None:
   232                 datatype_def += [(" := ", ()),
   232                 datatype_def += [(" := ", ()),
   238     def GeneratePouProgram(self, pou_name):
   238     def GeneratePouProgram(self, pou_name):
   239         # Verify that POU hasn't been generated yet
   239         # Verify that POU hasn't been generated yet
   240         if not self.PouComputed.get(pou_name, True):
   240         if not self.PouComputed.get(pou_name, True):
   241             # If not mark POU as computed
   241             # If not mark POU as computed
   242             self.PouComputed[pou_name] = True
   242             self.PouComputed[pou_name] = True
   243             
   243 
   244             # Getting POU model from project
   244             # Getting POU model from project
   245             pou = self.Project.getpou(pou_name)
   245             pou = self.Project.getpou(pou_name)
   246             pou_type = pou.getpouType()
   246             pou_type = pou.getpouType()
   247             # Verify that POU type exists
   247             # Verify that POU type exists
   248             if pouTypeNames.has_key(pou_type):
   248             if pouTypeNames.has_key(pou_type):
   250                 pou_program = PouProgramGenerator(self, pou.getname(), pouTypeNames[pou_type], self.Errors, self.Warnings)
   250                 pou_program = PouProgramGenerator(self, pou.getname(), pouTypeNames[pou_type], self.Errors, self.Warnings)
   251                 program = pou_program.GenerateProgram(pou)
   251                 program = pou_program.GenerateProgram(pou)
   252                 self.Program += program
   252                 self.Program += program
   253             else:
   253             else:
   254                 raise PLCGenException, _("Undefined pou type \"%s\"")%pou_type
   254                 raise PLCGenException, _("Undefined pou type \"%s\"")%pou_type
   255     
   255 
   256     # Generate a POU defined and used in text
   256     # Generate a POU defined and used in text
   257     def GeneratePouProgramInText(self, text):
   257     def GeneratePouProgramInText(self, text):
   258         for pou_name in self.PouComputed.keys():
   258         for pou_name in self.PouComputed.keys():
   259             model = re.compile("(?:^|[^0-9^A-Z])%s(?:$|[^0-9^A-Z])"%pou_name.upper())
   259             model = re.compile("(?:^|[^0-9^A-Z])%s(?:$|[^0-9^A-Z])"%pou_name.upper())
   260             if model.search(text) is not None:
   260             if model.search(text) is not None:
   261                 self.GeneratePouProgram(pou_name)
   261                 self.GeneratePouProgram(pou_name)
   262     
   262 
   263     # Generate a configuration from its model
   263     # Generate a configuration from its model
   264     def GenerateConfiguration(self, configuration):
   264     def GenerateConfiguration(self, configuration):
   265         tagname = self.Controler.ComputeConfigurationName(configuration.getname())
   265         tagname = self.Controler.ComputeConfigurationName(configuration.getname())
   266         config = [("\nCONFIGURATION ", ()),
   266         config = [("\nCONFIGURATION ", ()),
   267                   (configuration.getname(), (tagname, "name")),
   267                   (configuration.getname(), (tagname, "name")),
   268                   ("\n", ())]
   268                   ("\n", ())]
   269         var_number = 0
   269         var_number = 0
   270         
   270 
   271         varlists = [(varlist, varlist.getvariable()[:]) for varlist in configuration.getglobalVars()]
   271         varlists = [(varlist, varlist.getvariable()[:]) for varlist in configuration.getglobalVars()]
   272         
   272 
   273         extra_variables = self.Controler.GetConfigurationExtraVariables()
   273         extra_variables = self.Controler.GetConfigurationExtraVariables()
   274         extra_global_vars = None
   274         extra_global_vars = None
   275         if len(extra_variables) > 0 and len(varlists) == 0:
   275         if len(extra_variables) > 0 and len(varlists) == 0:
   276             extra_global_vars = PLCOpenParser.CreateElement("globalVars", "interface")
   276             extra_global_vars = PLCOpenParser.CreateElement("globalVars", "interface")
   277             configuration.setglobalVars([extra_global_vars])
   277             configuration.setglobalVars([extra_global_vars])
   278             varlists = [(extra_global_vars, [])]
   278             varlists = [(extra_global_vars, [])]
   279             
   279 
   280         for variable in extra_variables:
   280         for variable in extra_variables:
   281             varlists[-1][0].appendvariable(variable)
   281             varlists[-1][0].appendvariable(variable)
   282             varlists[-1][1].append(variable)
   282             varlists[-1][1].append(variable)
   283             
   283 
   284         # Generate any global variable in configuration
   284         # Generate any global variable in configuration
   285         for varlist, varlist_variables in varlists:
   285         for varlist, varlist_variables in varlists:
   286             variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local")
   286             variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local")
   287             # Generate variable block with modifier
   287             # Generate variable block with modifier
   288             config += [("  VAR_GLOBAL", ())]
   288             config += [("  VAR_GLOBAL", ())]
   299                 if vartype_content.getLocalTag() == "derived":
   299                 if vartype_content.getLocalTag() == "derived":
   300                     var_type = vartype_content.getname()
   300                     var_type = vartype_content.getname()
   301                     self.GenerateDataType(var_type)
   301                     self.GenerateDataType(var_type)
   302                 else:
   302                 else:
   303                     var_type = var.gettypeAsText()
   303                     var_type = var.gettypeAsText()
   304                 
   304 
   305                 config += [("    ", ()),
   305                 config += [("    ", ()),
   306                            (var.getname(), (tagname, variable_type, var_number, "name")),
   306                            (var.getname(), (tagname, variable_type, var_number, "name")),
   307                            (" ", ())]
   307                            (" ", ())]
   308                 # Generate variable address if exists
   308                 # Generate variable address if exists
   309                 address = var.getaddress()
   309                 address = var.getaddress()
   319                     config += [(" := ", ()),
   319                     config += [(" := ", ()),
   320                                (self.ComputeValue(initial.getvalue(), var_type), (tagname, variable_type, var_number, "initial value"))]
   320                                (self.ComputeValue(initial.getvalue(), var_type), (tagname, variable_type, var_number, "initial value"))]
   321                 config += [(";\n", ())]
   321                 config += [(";\n", ())]
   322                 var_number += 1
   322                 var_number += 1
   323             config += [("  END_VAR\n", ())]
   323             config += [("  END_VAR\n", ())]
   324         
   324 
   325         if extra_global_vars is not None:
   325         if extra_global_vars is not None:
   326             configuration.remove(extra_global_vars)
   326             configuration.remove(extra_global_vars)
   327         else:
   327         else:
   328             for variable in extra_variables:
   328             for variable in extra_variables:
   329                 varlists[-1][0].remove(variable)
   329                 varlists[-1][0].remove(variable)
   330         
   330 
   331         # Generate any resource in the configuration
   331         # Generate any resource in the configuration
   332         for resource in configuration.getresource():
   332         for resource in configuration.getresource():
   333             config += self.GenerateResource(resource, configuration.getname())
   333             config += self.GenerateResource(resource, configuration.getname())
   334         config += [("END_CONFIGURATION\n", ())]
   334         config += [("END_CONFIGURATION\n", ())]
   335         return config
   335         return config
   336     
   336 
   337     # Generate a resource from its model
   337     # Generate a resource from its model
   338     def GenerateResource(self, resource, config_name):
   338     def GenerateResource(self, resource, config_name):
   339         tagname = self.Controler.ComputeConfigurationResourceName(config_name, resource.getname())
   339         tagname = self.Controler.ComputeConfigurationResourceName(config_name, resource.getname())
   340         resrce = [("\n  RESOURCE ", ()),
   340         resrce = [("\n  RESOURCE ", ()),
   341                   (resource.getname(), (tagname, "name")),
   341                   (resource.getname(), (tagname, "name")),
   359                 if vartype_content.getLocalTag() == "derived":
   359                 if vartype_content.getLocalTag() == "derived":
   360                     var_type = vartype_content.getname()
   360                     var_type = vartype_content.getname()
   361                     self.GenerateDataType(var_type)
   361                     self.GenerateDataType(var_type)
   362                 else:
   362                 else:
   363                     var_type = var.gettypeAsText()
   363                     var_type = var.gettypeAsText()
   364                 
   364 
   365                 resrce += [("      ", ()),
   365                 resrce += [("      ", ()),
   366                            (var.getname(), (tagname, variable_type, var_number, "name")),
   366                            (var.getname(), (tagname, variable_type, var_number, "name")),
   367                            (" ", ())]
   367                            (" ", ())]
   368                 address = var.getaddress()
   368                 address = var.getaddress()
   369                 # Generate variable address if exists
   369                 # Generate variable address if exists
   411 ##                    resrce += [("%ds"%interval.second, (tagname, "task", task_number, "interval", "second"))]
   411 ##                    resrce += [("%ds"%interval.second, (tagname, "task", task_number, "interval", "second"))]
   412 ##                if interval.microsecond != 0:
   412 ##                if interval.microsecond != 0:
   413 ##                    resrce += [("%dms"%(interval.microsecond / 1000), (tagname, "task", task_number, "interval", "millisecond"))]
   413 ##                    resrce += [("%dms"%(interval.microsecond / 1000), (tagname, "task", task_number, "interval", "millisecond"))]
   414 ##                resrce += [(",", ())]
   414 ##                resrce += [(",", ())]
   415             # Priority argument
   415             # Priority argument
   416             resrce += [("PRIORITY := ", ()), 
   416             resrce += [("PRIORITY := ", ()),
   417                        ("%d"%task.getpriority(), (tagname, "task", task_number, "priority")),
   417                        ("%d"%task.getpriority(), (tagname, "task", task_number, "priority")),
   418                        (");\n", ())]
   418                        (");\n", ())]
   419             task_number += 1
   419             task_number += 1
   420         instance_number = 0
   420         instance_number = 0
   421         # Generate any program assign to each task
   421         # Generate any program assign to each task
   437                            (instance.gettypeName(), (tagname, "instance", instance_number, "type")),
   437                            (instance.gettypeName(), (tagname, "instance", instance_number, "type")),
   438                            (";\n", ())]
   438                            (";\n", ())]
   439             instance_number += 1
   439             instance_number += 1
   440         resrce += [("  END_RESOURCE\n", ())]
   440         resrce += [("  END_RESOURCE\n", ())]
   441         return resrce
   441         return resrce
   442     
   442 
   443     # Generate the entire program for current project
   443     # Generate the entire program for current project
   444     def GenerateProgram(self):        
   444     def GenerateProgram(self):
   445         # Find all data types defined
   445         # Find all data types defined
   446         for datatype in self.Project.getdataTypes():
   446         for datatype in self.Project.getdataTypes():
   447             self.DatatypeComputed[datatype.getname()] = False
   447             self.DatatypeComputed[datatype.getname()] = False
   448         # Find all data types defined
   448         # Find all data types defined
   449         for pou in self.Project.getpous():
   449         for pou in self.Project.getpous():
   450             self.PouComputed[pou.getname()] = False
   450             self.PouComputed[pou.getname()] = False
   451         # Generate data type declaration structure if there is at least one data 
   451         # Generate data type declaration structure if there is at least one data
   452         # type defined
   452         # type defined
   453         if len(self.DatatypeComputed) > 0:
   453         if len(self.DatatypeComputed) > 0:
   454             self.Program += [("TYPE\n", ())]
   454             self.Program += [("TYPE\n", ())]
   455             # Generate every data types defined
   455             # Generate every data types defined
   456             for datatype_name in self.DatatypeComputed.keys():
   456             for datatype_name in self.DatatypeComputed.keys():
   460         for pou_name in self.PouComputed.keys():
   460         for pou_name in self.PouComputed.keys():
   461             self.GeneratePouProgram(pou_name)
   461             self.GeneratePouProgram(pou_name)
   462         # Generate every configurations defined
   462         # Generate every configurations defined
   463         for config in self.Project.getconfigurations():
   463         for config in self.Project.getconfigurations():
   464             self.Program += self.GenerateConfiguration(config)
   464             self.Program += self.GenerateConfiguration(config)
   465     
   465 
   466     # Return generated program
   466     # Return generated program
   467     def GetGeneratedProgram(self):
   467     def GetGeneratedProgram(self):
   468         return self.Program
   468         return self.Program
   469 
   469 
   470 
   470 
   479     PLCOpenParser.GetElementClass(instance_name, "fbdObjects")
   479     PLCOpenParser.GetElementClass(instance_name, "fbdObjects")
   480     for instance_name in ["inVariable", "inOutVariable", "outVariable", "block"]]
   480     for instance_name in ["inVariable", "inOutVariable", "outVariable", "block"]]
   481 [ContactClass, CoilClass, LeftPowerRailClass, RightPowerRailClass] = [
   481 [ContactClass, CoilClass, LeftPowerRailClass, RightPowerRailClass] = [
   482     PLCOpenParser.GetElementClass(instance_name, "ldObjects")
   482     PLCOpenParser.GetElementClass(instance_name, "ldObjects")
   483     for instance_name in ["contact", "coil", "leftPowerRail", "rightPowerRail"]]
   483     for instance_name in ["contact", "coil", "leftPowerRail", "rightPowerRail"]]
   484 [StepClass, TransitionClass, JumpStepClass, 
   484 [StepClass, TransitionClass, JumpStepClass,
   485  SelectionConvergenceClass, SelectionDivergenceClass,
   485  SelectionConvergenceClass, SelectionDivergenceClass,
   486  SimultaneousConvergenceClass, SimultaneousDivergenceClass] = [
   486  SimultaneousConvergenceClass, SimultaneousDivergenceClass] = [
   487     PLCOpenParser.GetElementClass(instance_name, "sfcObjects")
   487     PLCOpenParser.GetElementClass(instance_name, "sfcObjects")
   488     for instance_name in ["step", "transition", "jumpStep", 
   488     for instance_name in ["step", "transition", "jumpStep",
   489         "selectionConvergence", "selectionDivergence",
   489         "selectionConvergence", "selectionDivergence",
   490         "simultaneousConvergence", "simultaneousDivergence"]]
   490         "simultaneousConvergence", "simultaneousDivergence"]]
   491 TransitionObjClass = PLCOpenParser.GetElementClass("transition", "transitions")
   491 TransitionObjClass = PLCOpenParser.GetElementClass("transition", "transitions")
   492 ActionObjClass = PLCOpenParser.GetElementClass("action", "actions")
   492 ActionObjClass = PLCOpenParser.GetElementClass("action", "actions")
   493 
   493 
   494 class PouProgramGenerator:
   494 class PouProgramGenerator:
   495     
   495 
   496     # Create a new POU program generator
   496     # Create a new POU program generator
   497     def __init__(self, parent, name, type, errors, warnings):
   497     def __init__(self, parent, name, type, errors, warnings):
   498         # Keep Reference to the parent generator
   498         # Keep Reference to the parent generator
   499         self.ParentGenerator = parent
   499         self.ParentGenerator = parent
   500         self.Name = name
   500         self.Name = name
   512         self.SFCComputedBlocks = []
   512         self.SFCComputedBlocks = []
   513         self.ActionNumber = 0
   513         self.ActionNumber = 0
   514         self.Program = []
   514         self.Program = []
   515         self.Errors = errors
   515         self.Errors = errors
   516         self.Warnings = warnings
   516         self.Warnings = warnings
   517     
   517 
   518     def GetBlockType(self, type, inputs=None):
   518     def GetBlockType(self, type, inputs=None):
   519         return self.ParentGenerator.Controler.GetBlockType(type, inputs)
   519         return self.ParentGenerator.Controler.GetBlockType(type, inputs)
   520     
   520 
   521     def IndentLeft(self):
   521     def IndentLeft(self):
   522         if len(self.CurrentIndent) >= 2:
   522         if len(self.CurrentIndent) >= 2:
   523             self.CurrentIndent = self.CurrentIndent[:-2]
   523             self.CurrentIndent = self.CurrentIndent[:-2]
   524     
   524 
   525     def IndentRight(self):
   525     def IndentRight(self):
   526         self.CurrentIndent += "  "
   526         self.CurrentIndent += "  "
   527     
   527 
   528     # Generator of unique ID for inline actions
   528     # Generator of unique ID for inline actions
   529     def GetActionNumber(self):
   529     def GetActionNumber(self):
   530         self.ActionNumber += 1
   530         self.ActionNumber += 1
   531         return self.ActionNumber
   531         return self.ActionNumber
   532     
   532 
   533     # Test if a variable has already been defined
   533     # Test if a variable has already been defined
   534     def IsAlreadyDefined(self, name):
   534     def IsAlreadyDefined(self, name):
   535         for list_type, option, located, vars in self.Interface:
   535         for list_type, option, located, vars in self.Interface:
   536             for var_type, var_name, var_address, var_initial in vars:
   536             for var_type, var_name, var_address, var_initial in vars:
   537                 if name == var_name:
   537                 if name == var_name:
   538                     return True
   538                     return True
   539         return False
   539         return False
   540     
   540 
   541     # Return the type of a variable defined in interface
   541     # Return the type of a variable defined in interface
   542     def GetVariableType(self, name):
   542     def GetVariableType(self, name):
   543         parts = name.split('.')
   543         parts = name.split('.')
   544         current_type = None
   544         current_type = None
   545         if len(parts) > 0:
   545         if len(parts) > 0:
   567                         for element in infos["elements"]:
   567                         for element in infos["elements"]:
   568                             if element["Name"] == name:
   568                             if element["Name"] == name:
   569                                 current_type = element["Type"]
   569                                 current_type = element["Type"]
   570                                 break
   570                                 break
   571         return current_type
   571         return current_type
   572     
   572 
   573     # Return connectors linked by a connection to the given connector
   573     # Return connectors linked by a connection to the given connector
   574     def GetConnectedConnector(self, connector, body):
   574     def GetConnectedConnector(self, connector, body):
   575         links = connector.getconnections()
   575         links = connector.getconnections()
   576         if links is not None and len(links) == 1:
   576         if links is not None and len(links) == 1:
   577             return self.GetLinkedConnector(links[0], body)
   577             return self.GetLinkedConnector(links[0], body)
   578         return None        
   578         return None
   579 
   579 
   580     def GetLinkedConnector(self, link, body):
   580     def GetLinkedConnector(self, link, body):
   581         parameter = link.getformalParameter()
   581         parameter = link.getformalParameter()
   582         instance = body.getcontentInstance(link.getrefLocalId())
   582         instance = body.getcontentInstance(link.getrefLocalId())
   583         if isinstance(instance, (InVariableClass, InOutVariableClass, 
   583         if isinstance(instance, (InVariableClass, InOutVariableClass,
   584              ContinuationClass, ContactClass, CoilClass)):
   584              ContinuationClass, ContactClass, CoilClass)):
   585             return instance.connectionPointOut
   585             return instance.connectionPointOut
   586         elif isinstance(instance, BlockClass):
   586         elif isinstance(instance, BlockClass):
   587             outputvariables = instance.outputVariables.getvariable()
   587             outputvariables = instance.outputVariables.getvariable()
   588             if len(outputvariables) == 1:
   588             if len(outputvariables) == 1:
   608                     relposition = outputconnection.getrelPositionXY()
   608                     relposition = outputconnection.getrelPositionXY()
   609                     powerrailposition = instance.getposition()
   609                     powerrailposition = instance.getposition()
   610                     if point.x == powerrailposition.x + relposition[0] and point.y == powerrailposition.y + relposition[1]:
   610                     if point.x == powerrailposition.x + relposition[0] and point.y == powerrailposition.y + relposition[1]:
   611                         return outputconnection
   611                         return outputconnection
   612         return None
   612         return None
   613         
   613 
   614     def ExtractRelatedConnections(self, connection):
   614     def ExtractRelatedConnections(self, connection):
   615         for i, related in enumerate(self.RelatedConnections):
   615         for i, related in enumerate(self.RelatedConnections):
   616             if connection in related:
   616             if connection in related:
   617                 return self.RelatedConnections.pop(i)
   617                 return self.RelatedConnections.pop(i)
   618         return [connection]
   618         return [connection]
   619     
   619 
   620     def ComputeInterface(self, pou):
   620     def ComputeInterface(self, pou):
   621         interface = pou.getinterface()
   621         interface = pou.getinterface()
   622         if interface is not None:
   622         if interface is not None:
   623             body = pou.getbody()
   623             body = pou.getbody()
   624             if isinstance(body, ListType):
   624             if isinstance(body, ListType):
   625                 body = body[0]
   625                 body = body[0]
   626             body_content = body.getcontent()
   626             body_content = body.getcontent()
   627             body_type = body_content.getLocalTag()
   627             body_type = body_content.getLocalTag()
   628             if self.Type == "FUNCTION":
   628             if self.Type == "FUNCTION":
   629                 returntype_content = interface.getreturnType().getcontent()
   629                 returntype_content = interface.getreturnType()[0]
   630                 returntype_content_type = returntype_content.getLocalTag()
   630                 returntype_content_type = returntype_content.getLocalTag()
   631                 if returntype_content_type == "derived":
   631                 if returntype_content_type == "derived":
   632                     self.ReturnType = returntype_content.getname()
   632                     self.ReturnType = returntype_content.getname()
   633                 else:
   633                 else:
   634                     self.ReturnType = returntype_content_type.upper()
   634                     self.ReturnType = returntype_content_type.upper()
   678                     option = None
   678                     option = None
   679                 if len(variables) > 0:
   679                 if len(variables) > 0:
   680                     self.Interface.append((varTypeNames[varlist_type], option, False, variables))
   680                     self.Interface.append((varTypeNames[varlist_type], option, False, variables))
   681                 if len(located) > 0:
   681                 if len(located) > 0:
   682                     self.Interface.append((varTypeNames[varlist_type], option, True, located))
   682                     self.Interface.append((varTypeNames[varlist_type], option, True, located))
   683     
   683 
   684     LITERAL_TYPES = {
   684     LITERAL_TYPES = {
   685         "T": "TIME",
   685         "T": "TIME",
   686         "D": "DATE",
   686         "D": "DATE",
   687         "TOD": "TIME_OF_DAY",
   687         "TOD": "TIME_OF_DAY",
   688         "DT": "DATE_AND_TIME",
   688         "DT": "DATE_AND_TIME",
   697         body_content = body.getcontent()
   697         body_content = body.getcontent()
   698         body_type = body_content.getLocalTag()
   698         body_type = body_content.getLocalTag()
   699         if body_type in ["FBD", "LD", "SFC"]:
   699         if body_type in ["FBD", "LD", "SFC"]:
   700             undefined_blocks = []
   700             undefined_blocks = []
   701             for instance in body.getcontentInstances():
   701             for instance in body.getcontentInstances():
   702                 if isinstance(instance, (InVariableClass, OutVariableClass, 
   702                 if isinstance(instance, (InVariableClass, OutVariableClass,
   703                                          InOutVariableClass)):
   703                                          InOutVariableClass)):
   704                     expression = instance.getexpression()
   704                     expression = instance.getexpression()
   705                     var_type = self.GetVariableType(expression)
   705                     var_type = self.GetVariableType(expression)
   706                     if (isinstance(pou, TransitionObjClass) 
   706                     if (isinstance(pou, TransitionObjClass)
   707                         and expression == pou.getname()):
   707                         and expression == pou.getname()):
   708                         var_type = "BOOL"
   708                         var_type = "BOOL"
   709                     elif (not isinstance(pou, (TransitionObjClass, ActionObjClass)) and
   709                     elif (not isinstance(pou, (TransitionObjClass, ActionObjClass)) and
   710                           pou.getpouType() == "function" and expression == pou.getname()):
   710                           pou.getpouType() == "function" and expression == pou.getname()):
   711                         returntype_content = pou.interface.getreturnType().getcontent()
   711                         returntype_content = pou.interface.getreturnType().getcontent()
   716                             var_type = returntype_content_type.upper()
   716                             var_type = returntype_content_type.upper()
   717                     elif var_type is None:
   717                     elif var_type is None:
   718                         parts = expression.split("#")
   718                         parts = expression.split("#")
   719                         if len(parts) > 1:
   719                         if len(parts) > 1:
   720                             literal_prefix = parts[0].upper()
   720                             literal_prefix = parts[0].upper()
   721                             var_type = self.LITERAL_TYPES.get(literal_prefix, 
   721                             var_type = self.LITERAL_TYPES.get(literal_prefix,
   722                                                               literal_prefix)
   722                                                               literal_prefix)
   723                         elif expression.startswith("'"):
   723                         elif expression.startswith("'"):
   724                             var_type = "STRING"
   724                             var_type = "STRING"
   725                         elif expression.startswith('"'):
   725                         elif expression.startswith('"'):
   726                             var_type = "WSTRING"
   726                             var_type = "WSTRING"
   820                     self.ComputeConnectionTypes(action)
   820                     self.ComputeConnectionTypes(action)
   821                 for transition in pou.gettransitionList():
   821                 for transition in pou.gettransitionList():
   822                     self.TagName = self.ParentGenerator.Controler.ComputePouTransitionName(self.Name, transition.getname())
   822                     self.TagName = self.ParentGenerator.Controler.ComputePouTransitionName(self.Name, transition.getname())
   823                     self.ComputeConnectionTypes(transition)
   823                     self.ComputeConnectionTypes(transition)
   824                 self.TagName = previous_tagname
   824                 self.TagName = previous_tagname
   825                 
   825 
   826     def ComputeBlockInputTypes(self, instance, block_infos, body):
   826     def ComputeBlockInputTypes(self, instance, block_infos, body):
   827         undefined = {}
   827         undefined = {}
   828         for variable in instance.outputVariables.getvariable():
   828         for variable in instance.outputVariables.getvariable():
   829             output_name = variable.getformalParameter()
   829             output_name = variable.getformalParameter()
   830             if output_name == "ENO":
   830             if output_name == "ENO":
   881         body_content = body.getcontent()
   881         body_content = body.getcontent()
   882         body_type = body_content.getLocalTag()
   882         body_type = body_content.getLocalTag()
   883         if body_type in ["IL","ST"]:
   883         if body_type in ["IL","ST"]:
   884             text = body_content.getanyText()
   884             text = body_content.getanyText()
   885             self.ParentGenerator.GeneratePouProgramInText(text.upper())
   885             self.ParentGenerator.GeneratePouProgramInText(text.upper())
   886             self.Program = [(ReIndentText(text, len(self.CurrentIndent)), 
   886             self.Program = [(ReIndentText(text, len(self.CurrentIndent)),
   887                             (self.TagName, "body", len(self.CurrentIndent)))]
   887                             (self.TagName, "body", len(self.CurrentIndent)))]
   888         elif body_type == "SFC":
   888         elif body_type == "SFC":
   889             self.IndentRight()
   889             self.IndentRight()
   890             for instance in body.getcontentInstances():
   890             for instance in body.getcontentInstances():
   891                 if isinstance(instance, StepClass):
   891                 if isinstance(instance, StepClass):
   964                         if expression is not None:
   964                         if expression is not None:
   965                             expression = self.ExtractModifier(instance, expression, coil_info)
   965                             expression = self.ExtractModifier(instance, expression, coil_info)
   966                             self.Program += [(self.CurrentIndent, ())]
   966                             self.Program += [(self.CurrentIndent, ())]
   967                             self.Program += [(instance.getvariable(), coil_info + ("reference",))]
   967                             self.Program += [(instance.getvariable(), coil_info + ("reference",))]
   968                             self.Program += [(" := ", ())] + expression + [(";\n", ())]
   968                             self.Program += [(" := ", ())] + expression + [(";\n", ())]
   969                         
   969 
   970     def FactorizePaths(self, paths):
   970     def FactorizePaths(self, paths):
   971         same_paths = {}
   971         same_paths = {}
   972         uncomputed_index = range(len(paths))
   972         uncomputed_index = range(len(paths))
   973         factorized_paths = []
   973         factorized_paths = []
   974         for num, path in enumerate(paths):
   974         for num, path in enumerate(paths):
   982                 uncomputed_index.remove(num)
   982                 uncomputed_index.remove(num)
   983         for same_path, elements in same_paths.items():
   983         for same_path, elements in same_paths.items():
   984             if len(elements) > 1:
   984             if len(elements) > 1:
   985                 elements_paths = self.FactorizePaths([path for path, num in elements])
   985                 elements_paths = self.FactorizePaths([path for path, num in elements])
   986                 if len(elements_paths) > 1:
   986                 if len(elements_paths) > 1:
   987                     factorized_paths.append([tuple(elements_paths)] + eval(same_path))        
   987                     factorized_paths.append([tuple(elements_paths)] + eval(same_path))
   988                 else:
   988                 else:
   989                     factorized_paths.append(elements_paths + eval(same_path))
   989                     factorized_paths.append(elements_paths + eval(same_path))
   990                 for path, num in elements:
   990                 for path, num in elements:
   991                     uncomputed_index.remove(num)
   991                     uncomputed_index.remove(num)
   992         for num in uncomputed_index:
   992         for num in uncomputed_index:
  1011         if block_infos["type"] == "function":
  1011         if block_infos["type"] == "function":
  1012             if not self.ComputedBlocks.get(block, False) and not order:
  1012             if not self.ComputedBlocks.get(block, False) and not order:
  1013                 self.ComputedBlocks[block] = True
  1013                 self.ComputedBlocks[block] = True
  1014                 connected_vars = []
  1014                 connected_vars = []
  1015                 if not block_infos["extensible"]:
  1015                 if not block_infos["extensible"]:
  1016                     input_connected = dict([("EN", None)] + 
  1016                     input_connected = dict([("EN", None)] +
  1017                                            [(input_name, None) for input_name in input_names])
  1017                                            [(input_name, None) for input_name in input_names])
  1018                     for variable in input_variables:
  1018                     for variable in input_variables:
  1019                         parameter = variable.getformalParameter()
  1019                         parameter = variable.getformalParameter()
  1020                         if input_connected.has_key(parameter):
  1020                         if input_connected.has_key(parameter):
  1021                             input_connected[parameter] = variable
  1021                             input_connected[parameter] = variable
  1069                             if variable.connectionPointOut in self.ConnectionTypes:
  1069                             if variable.connectionPointOut in self.ConnectionTypes:
  1070                                 self.Interface[-1][3].append((self.ConnectionTypes[variable.connectionPointOut], variable_name, None, None))
  1070                                 self.Interface[-1][3].append((self.ConnectionTypes[variable.connectionPointOut], variable_name, None, None))
  1071                             else:
  1071                             else:
  1072                                 self.Interface[-1][3].append(("ANY", variable_name, None, None))
  1072                                 self.Interface[-1][3].append(("ANY", variable_name, None, None))
  1073                             if len(output_variables) > 1 and parameter not in ["", "OUT"]:
  1073                             if len(output_variables) > 1 and parameter not in ["", "OUT"]:
  1074                                 vars.append([(parameter, (self.TagName, "block", block.getlocalId(), "output", i)), 
  1074                                 vars.append([(parameter, (self.TagName, "block", block.getlocalId(), "output", i)),
  1075                                              (" => %s"%variable_name, ())])
  1075                                              (" => %s"%variable_name, ())])
  1076                             else:
  1076                             else:
  1077                                 output_info = (self.TagName, "block", block.getlocalId(), "output", i)
  1077                                 output_info = (self.TagName, "block", block.getlocalId(), "output", i)
  1078                                 output_name = variable_name
  1078                                 output_name = variable_name
  1079                     self.Program += [(self.CurrentIndent, ()),
  1079                     self.Program += [(self.CurrentIndent, ()),
  1103                         if connections is not None:
  1103                         if connections is not None:
  1104                             expression = self.ComputeExpression(body, connections, executionOrderId > 0, inout_variables.has_key(parameter))
  1104                             expression = self.ComputeExpression(body, connections, executionOrderId > 0, inout_variables.has_key(parameter))
  1105                             if expression is not None:
  1105                             if expression is not None:
  1106                                 vars.append([(parameter, input_info),
  1106                                 vars.append([(parameter, input_info),
  1107                                              (" := ", ())] + self.ExtractModifier(variable, expression, input_info))
  1107                                              (" := ", ())] + self.ExtractModifier(variable, expression, input_info))
  1108                 self.Program += [(self.CurrentIndent, ()), 
  1108                 self.Program += [(self.CurrentIndent, ()),
  1109                                  (name, (self.TagName, "block", block.getlocalId(), "name")),
  1109                                  (name, (self.TagName, "block", block.getlocalId(), "name")),
  1110                                  ("(", ())]
  1110                                  ("(", ())]
  1111                 self.Program += JoinList([(", ", ())], vars)
  1111                 self.Program += JoinList([(", ", ())], vars)
  1112                 self.Program += [(");\n", ())]
  1112                 self.Program += [(");\n", ())]
  1113         
  1113 
  1114         if link is not None:
  1114         if link is not None:
  1115             connectionPoint = link.getposition()[-1]
  1115             connectionPoint = link.getposition()[-1]
  1116             output_parameter = link.getformalParameter()
  1116             output_parameter = link.getformalParameter()
  1117         else:
  1117         else:
  1118             connectionPoint = None
  1118             connectionPoint = None
  1119             output_parameter = None
  1119             output_parameter = None
  1120         
  1120 
  1121         output_variable = None
  1121         output_variable = None
  1122         output_idx = 0
  1122         output_idx = 0
  1123         if output_parameter is not None:
  1123         if output_parameter is not None:
  1124             if output_parameter in output_names or output_parameter == "ENO":
  1124             if output_parameter in output_names or output_parameter == "ENO":
  1125                 for variable in output_variables:
  1125                 for variable in output_variables:
  1128                         if output_parameter != "ENO":
  1128                         if output_parameter != "ENO":
  1129                             output_idx = output_names.index(output_parameter)
  1129                             output_idx = output_names.index(output_parameter)
  1130         else:
  1130         else:
  1131             for i, variable in enumerate(output_variables):
  1131             for i, variable in enumerate(output_variables):
  1132                 blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
  1132                 blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
  1133                 if (connectionPoint is None or 
  1133                 if (connectionPoint is None or
  1134                     block.getx() + blockPointx == connectionPoint.getx() and 
  1134                     block.getx() + blockPointx == connectionPoint.getx() and
  1135                     block.gety() + blockPointy == connectionPoint.gety()):
  1135                     block.gety() + blockPointy == connectionPoint.gety()):
  1136                     output_variable = variable
  1136                     output_variable = variable
  1137                     output_parameter = variable.getformalParameter()
  1137                     output_parameter = variable.getformalParameter()
  1138                     output_idx = i
  1138                     output_idx = i
  1139         
  1139 
  1140         if output_variable is not None:
  1140         if output_variable is not None:
  1141             if block_infos["type"] == "function":
  1141             if block_infos["type"] == "function":
  1142                 output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx)
  1142                 output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx)
  1143                 if inout_variables.has_key(output_parameter):
  1143                 if inout_variables.has_key(output_parameter):
  1144                     output_value = inout_variables[output_parameter]
  1144                     output_value = inout_variables[output_parameter]
  1147                         output_name = "%s%d"%(type, block.getlocalId())
  1147                         output_name = "%s%d"%(type, block.getlocalId())
  1148                     else:
  1148                     else:
  1149                         output_name = "%s%d_%s"%(type, block.getlocalId(), output_parameter)
  1149                         output_name = "%s%d_%s"%(type, block.getlocalId(), output_parameter)
  1150                     output_value = [(output_name, output_info)]
  1150                     output_value = [(output_name, output_info)]
  1151                 return self.ExtractModifier(output_variable, output_value, output_info)
  1151                 return self.ExtractModifier(output_variable, output_value, output_info)
  1152             
  1152 
  1153             if block_infos["type"] == "functionBlock":
  1153             if block_infos["type"] == "functionBlock":
  1154                 output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx)
  1154                 output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx)
  1155                 output_name = self.ExtractModifier(output_variable, [("%s.%s"%(name, output_parameter), output_info)], output_info)
  1155                 output_name = self.ExtractModifier(output_variable, [("%s.%s"%(name, output_parameter), output_info)], output_info)
  1156                 if to_inout:
  1156                 if to_inout:
  1157                     variable_name = "%s_%s"%(name, output_parameter)
  1157                     variable_name = "%s_%s"%(name, output_parameter)
  1166                         self.Program += [(self.CurrentIndent, ()),
  1166                         self.Program += [(self.CurrentIndent, ()),
  1167                                          ("%s := "%variable_name, ())]
  1167                                          ("%s := "%variable_name, ())]
  1168                         self.Program += output_name
  1168                         self.Program += output_name
  1169                         self.Program += [(";\n", ())]
  1169                         self.Program += [(";\n", ())]
  1170                     return [(variable_name, ())]
  1170                     return [(variable_name, ())]
  1171                 return output_name 
  1171                 return output_name
  1172         if link is not None:
  1172         if link is not None:
  1173             if output_parameter is None:
  1173             if output_parameter is None:
  1174                 output_parameter = ""
  1174                 output_parameter = ""
  1175             if name:
  1175             if name:
  1176                 blockname = "%s(%s)" % (name, type)
  1176                 blockname = "%s(%s)" % (name, type)
  1289             if edge == "rising":
  1289             if edge == "rising":
  1290                 return self.AddTrigger("R_TRIG", expression, var_info + ("rising",))
  1290                 return self.AddTrigger("R_TRIG", expression, var_info + ("rising",))
  1291             elif edge == "falling":
  1291             elif edge == "falling":
  1292                 return self.AddTrigger("F_TRIG", expression, var_info + ("falling",))
  1292                 return self.AddTrigger("F_TRIG", expression, var_info + ("falling",))
  1293         return expression
  1293         return expression
  1294     
  1294 
  1295     def AddTrigger(self, edge, expression, var_info):
  1295     def AddTrigger(self, edge, expression, var_info):
  1296         if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] is not None or self.Interface[-1][2]:
  1296         if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] is not None or self.Interface[-1][2]:
  1297             self.Interface.append(("VAR", None, False, []))
  1297             self.Interface.append(("VAR", None, False, []))
  1298         i = 1
  1298         i = 1
  1299         name = "%s%d"%(edge, i)
  1299         name = "%s%d"%(edge, i)
  1300         while self.IsAlreadyDefined(name):
  1300         while self.IsAlreadyDefined(name):
  1301             i += 1
  1301             i += 1
  1302             name = "%s%d"%(edge, i)
  1302             name = "%s%d"%(edge, i)
  1303         self.Interface[-1][3].append((edge, name, None, None))
  1303         self.Interface[-1][3].append((edge, name, None, None))
  1304         self.Program += [(self.CurrentIndent, ()), (name, var_info), ("(CLK := ", ())] 
  1304         self.Program += [(self.CurrentIndent, ()), (name, var_info), ("(CLK := ", ())]
  1305         self.Program += expression
  1305         self.Program += expression
  1306         self.Program += [(");\n", ())]
  1306         self.Program += [(");\n", ())]
  1307         return [("%s.Q"%name, var_info)]
  1307         return [("%s.Q"%name, var_info)]
  1308     
  1308 
  1309     def ExtractDivergenceInput(self, divergence, pou):
  1309     def ExtractDivergenceInput(self, divergence, pou):
  1310         connectionPointIn = divergence.getconnectionPointIn()
  1310         connectionPointIn = divergence.getconnectionPointIn()
  1311         if connectionPointIn is not None:
  1311         if connectionPointIn is not None:
  1312             connections = connectionPointIn.getconnections()
  1312             connections = connectionPointIn.getconnections()
  1313             if connections is not None and len(connections) == 1:
  1313             if connections is not None and len(connections) == 1:
  1333     def GenerateSFCStep(self, step, pou):
  1333     def GenerateSFCStep(self, step, pou):
  1334         step_name = step.getname()
  1334         step_name = step.getname()
  1335         if step_name not in self.SFCNetworks["Steps"].keys():
  1335         if step_name not in self.SFCNetworks["Steps"].keys():
  1336             if step.getinitialStep():
  1336             if step.getinitialStep():
  1337                 self.InitialSteps.append(step_name)
  1337                 self.InitialSteps.append(step_name)
  1338             step_infos = {"id" : step.getlocalId(), 
  1338             step_infos = {"id" : step.getlocalId(),
  1339                           "initial" : step.getinitialStep(), 
  1339                           "initial" : step.getinitialStep(),
  1340                           "transitions" : [], 
  1340                           "transitions" : [],
  1341                           "actions" : []}
  1341                           "actions" : []}
  1342             self.SFCNetworks["Steps"][step_name] = step_infos
  1342             self.SFCNetworks["Steps"][step_name] = step_infos
  1343             if step.connectionPointIn is not None:
  1343             if step.connectionPointIn is not None:
  1344                 instances = []
  1344                 instances = []
  1345                 connections = step.connectionPointIn.getconnections()
  1345                 connections = step.connectionPointIn.getconnections()
  1363                 for instance in instances:
  1363                 for instance in instances:
  1364                     self.GenerateSFCTransition(instance, pou)
  1364                     self.GenerateSFCTransition(instance, pou)
  1365                     if instance in self.SFCNetworks["Transitions"].keys():
  1365                     if instance in self.SFCNetworks["Transitions"].keys():
  1366                         target_info = (self.TagName, "transition", instance.getlocalId(), "to", step_infos["id"])
  1366                         target_info = (self.TagName, "transition", instance.getlocalId(), "to", step_infos["id"])
  1367                         self.SFCNetworks["Transitions"][instance]["to"].append([(step_name, target_info)])
  1367                         self.SFCNetworks["Transitions"][instance]["to"].append([(step_name, target_info)])
  1368     
  1368 
  1369     def GenerateSFCJump(self, jump, pou):
  1369     def GenerateSFCJump(self, jump, pou):
  1370         jump_target = jump.gettargetName()
  1370         jump_target = jump.gettargetName()
  1371         if jump.connectionPointIn is not None:
  1371         if jump.connectionPointIn is not None:
  1372             instances = []
  1372             instances = []
  1373             connections = jump.connectionPointIn.getconnections()
  1373             connections = jump.connectionPointIn.getconnections()
  1391             for instance in instances:
  1391             for instance in instances:
  1392                 self.GenerateSFCTransition(instance, pou)
  1392                 self.GenerateSFCTransition(instance, pou)
  1393                 if instance in self.SFCNetworks["Transitions"].keys():
  1393                 if instance in self.SFCNetworks["Transitions"].keys():
  1394                     target_info = (self.TagName, "jump", jump.getlocalId(), "target")
  1394                     target_info = (self.TagName, "jump", jump.getlocalId(), "target")
  1395                     self.SFCNetworks["Transitions"][instance]["to"].append([(jump_target, target_info)])
  1395                     self.SFCNetworks["Transitions"][instance]["to"].append([(jump_target, target_info)])
  1396     
  1396 
  1397     def GenerateSFCStepActions(self, actionBlock, pou):
  1397     def GenerateSFCStepActions(self, actionBlock, pou):
  1398         connections = actionBlock.connectionPointIn.getconnections()
  1398         connections = actionBlock.connectionPointIn.getconnections()
  1399         if connections is not None and len(connections) == 1:
  1399         if connections is not None and len(connections) == 1:
  1400             stepLocalId = connections[0].getrefLocalId()
  1400             stepLocalId = connections[0].getrefLocalId()
  1401             body = pou.getbody()
  1401             body = pou.getbody()
  1405             self.GenerateSFCStep(step, pou)
  1405             self.GenerateSFCStep(step, pou)
  1406             step_name = step.getname()
  1406             step_name = step.getname()
  1407             if step_name in self.SFCNetworks["Steps"].keys():
  1407             if step_name in self.SFCNetworks["Steps"].keys():
  1408                 actions = actionBlock.getactions()
  1408                 actions = actionBlock.getactions()
  1409                 for i, action in enumerate(actions):
  1409                 for i, action in enumerate(actions):
  1410                     action_infos = {"id" : actionBlock.getlocalId(), 
  1410                     action_infos = {"id" : actionBlock.getlocalId(),
  1411                                     "qualifier" : action["qualifier"], 
  1411                                     "qualifier" : action["qualifier"],
  1412                                     "content" : action["value"],
  1412                                     "content" : action["value"],
  1413                                     "num" : i}
  1413                                     "num" : i}
  1414                     if "duration" in action:
  1414                     if "duration" in action:
  1415                         action_infos["duration"] = action["duration"]
  1415                         action_infos["duration"] = action["duration"]
  1416                     if "indicator" in action:
  1416                     if "indicator" in action:
  1417                         action_infos["indicator"] = action["indicator"]
  1417                         action_infos["indicator"] = action["indicator"]
  1418                     if action["type"] == "reference":
  1418                     if action["type"] == "reference":
  1419                         self.GenerateSFCAction(action["value"], pou)
  1419                         self.GenerateSFCAction(action["value"], pou)
  1420                     else:
  1420                     else:
  1421                         action_name = "%s_INLINE%d"%(step_name.upper(), self.GetActionNumber())
  1421                         action_name = "%s_INLINE%d"%(step_name.upper(), self.GetActionNumber())
  1422                         self.SFCNetworks["Actions"][action_name] = ([(self.CurrentIndent, ()), 
  1422                         self.SFCNetworks["Actions"][action_name] = ([(self.CurrentIndent, ()),
  1423                             (action["value"], (self.TagName, "action_block", action_infos["id"], "action", i, "inline")),
  1423                             (action["value"], (self.TagName, "action_block", action_infos["id"], "action", i, "inline")),
  1424                             ("\n", ())], ())
  1424                             ("\n", ())], ())
  1425                         action_infos["content"] = action_name
  1425                         action_infos["content"] = action_name
  1426                     self.SFCNetworks["Steps"][step_name]["actions"].append(action_infos)
  1426                     self.SFCNetworks["Steps"][step_name]["actions"].append(action_infos)
  1427     
  1427 
  1428     def GenerateSFCAction(self, action_name, pou):
  1428     def GenerateSFCAction(self, action_name, pou):
  1429         if action_name not in self.SFCNetworks["Actions"].keys():
  1429         if action_name not in self.SFCNetworks["Actions"].keys():
  1430             actionContent = pou.getaction(action_name)
  1430             actionContent = pou.getaction(action_name)
  1431             if actionContent is not None:
  1431             if actionContent is not None:
  1432                 previous_tagname = self.TagName
  1432                 previous_tagname = self.TagName
  1433                 self.TagName = self.ParentGenerator.Controler.ComputePouActionName(self.Name, action_name)
  1433                 self.TagName = self.ParentGenerator.Controler.ComputePouActionName(self.Name, action_name)
  1434                 self.ComputeProgram(actionContent)
  1434                 self.ComputeProgram(actionContent)
  1435                 self.SFCNetworks["Actions"][action_name] = (self.Program, (self.TagName, "name"))
  1435                 self.SFCNetworks["Actions"][action_name] = (self.Program, (self.TagName, "name"))
  1436                 self.Program = []
  1436                 self.Program = []
  1437                 self.TagName = previous_tagname
  1437                 self.TagName = previous_tagname
  1438     
  1438 
  1439     def GenerateSFCTransition(self, transition, pou):
  1439     def GenerateSFCTransition(self, transition, pou):
  1440         if transition not in self.SFCNetworks["Transitions"].keys():
  1440         if transition not in self.SFCNetworks["Transitions"].keys():
  1441             steps = []
  1441             steps = []
  1442             connections = transition.connectionPointIn.getconnections()
  1442             connections = transition.connectionPointIn.getconnections()
  1443             if connections is not None and len(connections) == 1:
  1443             if connections is not None and len(connections) == 1:
  1455                             steps.append(step)
  1455                             steps.append(step)
  1456                         elif isinstance(step, SimultaneousConvergenceClass):
  1456                         elif isinstance(step, SimultaneousConvergenceClass):
  1457                             steps.extend(self.ExtractConvergenceInputs(step, pou))
  1457                             steps.extend(self.ExtractConvergenceInputs(step, pou))
  1458                 elif isinstance(instance, SimultaneousConvergenceClass):
  1458                 elif isinstance(instance, SimultaneousConvergenceClass):
  1459                     steps.extend(self.ExtractConvergenceInputs(instance, pou))
  1459                     steps.extend(self.ExtractConvergenceInputs(instance, pou))
  1460             transition_infos = {"id" : transition.getlocalId(), 
  1460             transition_infos = {"id" : transition.getlocalId(),
  1461                                 "priority": transition.getpriority(), 
  1461                                 "priority": transition.getpriority(),
  1462                                 "from": [], 
  1462                                 "from": [],
  1463                                 "to" : [],
  1463                                 "to" : [],
  1464                                 "content": []}
  1464                                 "content": []}
  1465             self.SFCNetworks["Transitions"][transition] = transition_infos
  1465             self.SFCNetworks["Transitions"][transition] = transition_infos
  1466             transitionValues = transition.getconditionContent()
  1466             transitionValues = transition.getconditionContent()
  1467             if transitionValues["type"] == "inline":
  1467             if transitionValues["type"] == "inline":
  1544             self.Program += [("%sEND_STEP\n\n"%self.CurrentIndent, ())]
  1544             self.Program += [("%sEND_STEP\n\n"%self.CurrentIndent, ())]
  1545             for action in actions:
  1545             for action in actions:
  1546                 self.ComputeSFCAction(action)
  1546                 self.ComputeSFCAction(action)
  1547             for transition in step_infos["transitions"]:
  1547             for transition in step_infos["transitions"]:
  1548                 self.ComputeSFCTransition(transition)
  1548                 self.ComputeSFCTransition(transition)
  1549                 
  1549 
  1550     def ComputeSFCAction(self, action_name):
  1550     def ComputeSFCAction(self, action_name):
  1551         if action_name in self.SFCNetworks["Actions"].keys():
  1551         if action_name in self.SFCNetworks["Actions"].keys():
  1552             action_content, action_info = self.SFCNetworks["Actions"].pop(action_name)
  1552             action_content, action_info = self.SFCNetworks["Actions"].pop(action_name)
  1553             self.Program += [("%sACTION "%self.CurrentIndent, ()),
  1553             self.Program += [("%sACTION "%self.CurrentIndent, ()),
  1554                              (action_name, action_info),
  1554                              (action_name, action_info),
  1555                              (":\n", ())]
  1555                              (":\n", ())]
  1556             self.Program += action_content
  1556             self.Program += action_content
  1557             self.Program += [("%sEND_ACTION\n\n"%self.CurrentIndent, ())]
  1557             self.Program += [("%sEND_ACTION\n\n"%self.CurrentIndent, ())]
  1558     
  1558 
  1559     def ComputeSFCTransition(self, transition):
  1559     def ComputeSFCTransition(self, transition):
  1560         if transition in self.SFCNetworks["Transitions"].keys():
  1560         if transition in self.SFCNetworks["Transitions"].keys():
  1561             transition_infos = self.SFCNetworks["Transitions"].pop(transition)
  1561             transition_infos = self.SFCNetworks["Transitions"].pop(transition)
  1562             self.Program += [("%sTRANSITION"%self.CurrentIndent, ())]
  1562             self.Program += [("%sTRANSITION"%self.CurrentIndent, ())]
  1563             if transition_infos["priority"] != None:
  1563             if transition_infos["priority"] != None:
  1584                 raise PLCGenException, _("Transition with content \"%s\" not connected to a next step in \"%s\" POU")%(transition_infos["content"], self.Name)
  1584                 raise PLCGenException, _("Transition with content \"%s\" not connected to a next step in \"%s\" POU")%(transition_infos["content"], self.Name)
  1585             self.Program += transition_infos["content"]
  1585             self.Program += transition_infos["content"]
  1586             self.Program += [("%sEND_TRANSITION\n\n"%self.CurrentIndent, ())]
  1586             self.Program += [("%sEND_TRANSITION\n\n"%self.CurrentIndent, ())]
  1587             for [(step_name, step_infos)] in transition_infos["to"]:
  1587             for [(step_name, step_infos)] in transition_infos["to"]:
  1588                 self.ComputeSFCStep(step_name)
  1588                 self.ComputeSFCStep(step_name)
  1589     
  1589 
  1590     def GenerateProgram(self, pou):
  1590     def GenerateProgram(self, pou):
  1591         self.ComputeInterface(pou)
  1591         self.ComputeInterface(pou)
  1592         self.ComputeConnectionTypes(pou)
  1592         self.ComputeConnectionTypes(pou)
  1593         self.ComputeProgram(pou)
  1593         self.ComputeProgram(pou)
  1594         
  1594 
  1595         program = [("%s "%self.Type, ()),
  1595         program = [("%s "%self.Type, ()),
  1596                    (self.Name, (self.TagName, "name"))]
  1596                    (self.Name, (self.TagName, "name"))]
  1597         if self.ReturnType is not None:
  1597         if self.ReturnType is not None:
  1598             program += [(" : ", ()),
  1598             program += [(" : ", ()),
  1599                         (self.ReturnType, (self.TagName, "return"))]
  1599                         (self.ReturnType, (self.TagName, "return"))]