PLCGenerator.py
changeset 566 6014ef82a98a
parent 558 01e2c3d58a27
child 597 7b17e3c8dbed
equal deleted inserted replaced
565:94c11207aa6f 566:6014ef82a98a
    37 
    37 
    38 # Dictionary associating PLCOpen POU categories to the corresponding 
    38 # Dictionary associating PLCOpen POU categories to the corresponding 
    39 # IEC 61131-3 POU categories
    39 # IEC 61131-3 POU categories
    40 pouTypeNames = {"function" : "FUNCTION", "functionBlock" : "FUNCTION_BLOCK", "program" : "PROGRAM"}
    40 pouTypeNames = {"function" : "FUNCTION", "functionBlock" : "FUNCTION_BLOCK", "program" : "PROGRAM"}
    41 
    41 
       
    42 
       
    43 errorVarTypes = {
       
    44     "VAR_INPUT": "var_input",
       
    45     "VAR_OUTPUT": "var_output",
       
    46     "VAR_INOUT": "var_inout",
       
    47 }
    42 
    48 
    43 # Helper function for reindenting text
    49 # Helper function for reindenting text
    44 def ReIndentText(text, nb_spaces):
    50 def ReIndentText(text, nb_spaces):
    45     compute = ""
    51     compute = ""
    46     lines = text.splitlines()
    52     lines = text.splitlines()
   245                   (configuration.getname(), (tagname, "name")),
   251                   (configuration.getname(), (tagname, "name")),
   246                   ("\n", ())]
   252                   ("\n", ())]
   247         var_number = 0
   253         var_number = 0
   248         # Generate any global variable in configuration
   254         # Generate any global variable in configuration
   249         for varlist in configuration.getglobalVars():
   255         for varlist in configuration.getglobalVars():
       
   256             variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local")
   250             # Generate variable block with modifier
   257             # Generate variable block with modifier
   251             config += [("  VAR_GLOBAL", ())]
   258             config += [("  VAR_GLOBAL", ())]
   252             if varlist.getconstant():
   259             if varlist.getconstant():
   253                 config += [(" CONSTANT", (tagname, "variable", (var_number, var_number + len(varlist.getvariable())), "constant"))]
   260                 config += [(" CONSTANT", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "constant"))]
   254             elif varlist.getretain():
   261             elif varlist.getretain():
   255                 config += [(" RETAIN", (tagname, "variable", (var_number, var_number + len(varlist.getvariable())), "retain"))]
   262                 config += [(" RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "retain"))]
   256             elif varlist.getnonretain():
   263             elif varlist.getnonretain():
   257                 config += [(" NON_RETAIN", (tagname, "variable", (var_number, var_number + len(varlist.getvariable())), "non_retain"))]
   264                 config += [(" NON_RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "non_retain"))]
   258             config += [("\n", ())]
   265             config += [("\n", ())]
   259             # Generate any variable of this block
   266             # Generate any variable of this block
   260             for var in varlist.getvariable():
   267             for var in varlist.getvariable():
   261                 vartype_content = var.gettype().getcontent()
   268                 vartype_content = var.gettype().getcontent()
   262                 # Variable type is a user data type
       
   263                 if vartype_content["name"] == "derived":
   269                 if vartype_content["name"] == "derived":
   264                     var_type = vartype_content["value"].getname()
   270                     var_type = vartype_content["value"].getname()
   265                 # Variable type is a string type
   271                     self.GenerateDataType(var_type)
   266                 elif vartype_content["name"] in ["string", "wstring"]:
   272                 
   267                     var_type = vartype_content["name"].upper()
       
   268                 # Variable type is an array
       
   269                 elif vartype_content["name"] == "array":
       
   270                     base_type = vartype_content["value"].baseType.getcontent()
       
   271                     # Array derived directly from a user defined type 
       
   272                     if base_type["name"] == "derived":
       
   273                         basetype_name = base_type["value"].getname()
       
   274                         self.GenerateDataType(basetype_name)
       
   275                     # Array derived directly from a string type 
       
   276                     elif base_type["name"] in ["string", "wstring"]:
       
   277                         basetype_name = base_type["name"].upper()
       
   278                     # Array derived directly from an elementary type 
       
   279                     else:
       
   280                         basetype_name = base_type["name"]
       
   281                     var_type = "ARRAY [%s] OF %s" % (",".join(map(lambda x : "%s..%s" % (x.getlower(), x.getupper()), vartype_content["value"].getdimension())), basetype_name)
       
   282                 # Variable type is an elementary type
       
   283                 else:
       
   284                     var_type = vartype_content["name"]
       
   285                 config += [("    ", ()),
   273                 config += [("    ", ()),
   286                            (var.getname(), (tagname, "variable", var_number, "name")),
   274                            (var.getname(), (tagname, variable_type, var_number, "name")),
   287                            (" ", ())]
   275                            (" ", ())]
   288                 # Generate variable address if exists
   276                 # Generate variable address if exists
   289                 address = var.getaddress()
   277                 address = var.getaddress()
   290                 if address:
   278                 if address:
   291                     config += [("AT ", ()),
   279                     config += [("AT ", ()),
   292                                (address, (tagname, "variable", var_number, "address")),
   280                                (address, (tagname, variable_type, var_number, "address")),
   293                                (" ", ())]
   281                                (" ", ())]
   294                 config += [(": ", ()),
   282                 config += [(": ", ()),
   295                            (var_type, (tagname, "variable", var_number, "type"))]
   283                            (var.gettypeAsText(), (tagname, variable_type, var_number, "type"))]
   296                 # Generate variable initial value if exists
   284                 # Generate variable initial value if exists
   297                 initial = var.getinitialValue()
   285                 initial = var.getinitialValue()
   298                 if initial:
   286                 if initial:
   299                     config += [(" := ", ()),
   287                     config += [(" := ", ()),
   300                                (self.ComputeValue(initial.getvalue(), var_type), (tagname, "variable", var_number, "initial"))]
   288                                (self.ComputeValue(initial.getvalue(), var_type), (tagname, variable_type, var_number, "initial"))]
   301                 config += [(";\n", ())]
   289                 config += [(";\n", ())]
   302                 var_number += 1
   290                 var_number += 1
   303             config += [("  END_VAR\n", ())]
   291             config += [("  END_VAR\n", ())]
   304         # Generate any resource in the configuration
   292         # Generate any resource in the configuration
   305         for resource in configuration.getresource():
   293         for resource in configuration.getresource():
   314                   (resource.getname(), (tagname, "name")),
   302                   (resource.getname(), (tagname, "name")),
   315                   (" ON PLC\n", ())]
   303                   (" ON PLC\n", ())]
   316         var_number = 0
   304         var_number = 0
   317         # Generate any global variable in configuration
   305         # Generate any global variable in configuration
   318         for varlist in resource.getglobalVars():
   306         for varlist in resource.getglobalVars():
       
   307             variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local")
   319             # Generate variable block with modifier
   308             # Generate variable block with modifier
   320             resrce += [("    VAR_GLOBAL", ())]
   309             resrce += [("    VAR_GLOBAL", ())]
   321             if varlist.getconstant():
   310             if varlist.getconstant():
   322                 resrce += [(" CONSTANT", (tagname, "variable", (var_number, var_number + len(varlist.getvariable())), "constant"))]
   311                 resrce += [(" CONSTANT", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "constant"))]
   323             elif varlist.getretain():
   312             elif varlist.getretain():
   324                 resrce += [(" RETAIN", (tagname, "variable", (var_number, var_number + len(varlist.getvariable())), "retain"))]
   313                 resrce += [(" RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "retain"))]
   325             elif varlist.getnonretain():
   314             elif varlist.getnonretain():
   326                 resrce += [(" NON_RETAIN", (tagname, "variable", (var_number, var_number + len(varlist.getvariable())), "non_retain"))]
   315                 resrce += [(" NON_RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "non_retain"))]
   327             resrce += [("\n", ())]
   316             resrce += [("\n", ())]
   328             # Generate any variable of this block
   317             # Generate any variable of this block
   329             for var in varlist.getvariable():
   318             for var in varlist.getvariable():
   330                 vartype_content = var.gettype().getcontent()
   319                 vartype_content = var.gettype().getcontent()
   331                 # Variable type is a user data type
       
   332                 if vartype_content["name"] == "derived":
   320                 if vartype_content["name"] == "derived":
   333                     var_type = vartype_content["value"].getname()
   321                     var_type = vartype_content["value"].getname()
   334                 # Variable type is a string type
   322                     self.GenerateDataType(var_type)
   335                 elif vartype_content["name"] in ["string", "wstring"]:
   323                 
   336                     var_type = vartype_content["name"].upper()
       
   337                 # Variable type is an array
       
   338                 elif vartype_content["name"] == "array":
       
   339                     base_type = vartype_content["value"].baseType.getcontent()
       
   340                     # Array derived directly from a user defined type 
       
   341                     if base_type["name"] == "derived":
       
   342                         basetype_name = base_type["value"].getname()
       
   343                         self.GenerateDataType(basetype_name)
       
   344                     # Array derived directly from a string type 
       
   345                     elif base_type["name"] in ["string", "wstring"]:
       
   346                         basetype_name = base_type["name"].upper()
       
   347                     # Array derived directly from an elementary type 
       
   348                     else:
       
   349                         basetype_name = base_type["name"]
       
   350                     var_type = "ARRAY [%s] OF %s" % (",".join(map(lambda x : "%s..%s" % (x.getlower(), x.getupper()), vartype_content["value"].getdimension())), basetype_name)
       
   351                 # Variable type is an elementary type
       
   352                 else:
       
   353                     var_type = vartype_content["name"]
       
   354                 resrce += [("      ", ()),
   324                 resrce += [("      ", ()),
   355                            (var.getname(), (tagname, "variable", var_number, "name")),
   325                            (var.getname(), (tagname, variable_type, var_number, "name")),
   356                            (" ", ())]
   326                            (" ", ())]
   357                 address = var.getaddress()
   327                 address = var.getaddress()
   358                 # Generate variable address if exists
   328                 # Generate variable address if exists
   359                 if address:
   329                 if address:
   360                     resrce += [("AT ", ()),
   330                     resrce += [("AT ", ()),
   361                                (address, (tagname, "variable", var_number, "address")),
   331                                (address, (tagname, variable_type, var_number, "address")),
   362                                (" ", ())]
   332                                (" ", ())]
   363                 resrce += [(": ", ()),
   333                 resrce += [(": ", ()),
   364                            (var_type, (tagname, "variable", var_number, "type"))]
   334                            (var.gettypeAsText(), (tagname, variable_type, var_number, "type"))]
   365                 # Generate variable initial value if exists
   335                 # Generate variable initial value if exists
   366                 initial = var.getinitialValue()
   336                 initial = var.getinitialValue()
   367                 if initial:
   337                 if initial:
   368                     resrce += [(" := ", ()),
   338                     resrce += [(" := ", ()),
   369                                (self.ComputeValue(initial.getvalue(), var_type), (tagname, "variable", var_number, "initial"))]
   339                                (self.ComputeValue(initial.getvalue(), var_type), (tagname, variable_type, var_number, "initial"))]
   370                 resrce += [(";\n", ())]
   340                 resrce += [(";\n", ())]
   371                 var_number += 1
   341                 var_number += 1
   372             resrce += [("    END_VAR\n", ())]
   342             resrce += [("    END_VAR\n", ())]
   373         # Generate any task in the resource
   343         # Generate any task in the resource
   374         tasks = resource.gettask()
   344         tasks = resource.gettask()
   596                                 if variable[2] is not None:
   566                                 if variable[2] is not None:
   597                                     located.append(variable)
   567                                     located.append(variable)
   598                                 else:
   568                                 else:
   599                                     variables.append(variable)
   569                                     variables.append(variable)
   600                         else:
   570                         else:
       
   571                             self.ParentGenerator.GenerateDataType(var_type)
   601                             initial = var.getinitialValue()
   572                             initial = var.getinitialValue()
   602                             if initial:
   573                             if initial:
   603                                 initial_value = initial.getvalue()
   574                                 initial_value = initial.getvalue()
   604                             else:
   575                             else:
   605                                 initial_value = None
   576                                 initial_value = None
   607                             if address is not None:
   578                             if address is not None:
   608                                 located.append((vartype_content["value"].getname(), var.getname(), address, initial_value))
   579                                 located.append((vartype_content["value"].getname(), var.getname(), address, initial_value))
   609                             else:
   580                             else:
   610                                 variables.append((vartype_content["value"].getname(), var.getname(), None, initial_value))
   581                                 variables.append((vartype_content["value"].getname(), var.getname(), None, initial_value))
   611                     else:
   582                     else:
       
   583                         var_type = var.gettypeAsText()
   612                         initial = var.getinitialValue()
   584                         initial = var.getinitialValue()
   613                         if initial:
   585                         if initial:
   614                             initial_value = initial.getvalue()
   586                             initial_value = initial.getvalue()
   615                         else:
   587                         else:
   616                             initial_value = None
   588                             initial_value = None
   617                         address = var.getaddress()
   589                         address = var.getaddress()
   618                         if vartype_content["name"] in ["string", "wstring"]:
       
   619                             var_type = vartype_content["name"].upper()
       
   620                         # Variable type is an array
       
   621                         elif vartype_content["name"] == "array":
       
   622                             base_type = vartype_content["value"].baseType.getcontent()
       
   623                             # Array derived directly from a user defined type 
       
   624                             if base_type["name"] == "derived":
       
   625                                 basetype_name = base_type["value"].getname()
       
   626                                 self.ParentGenerator.GenerateDataType(basetype_name)
       
   627                             # Array derived directly from a string type 
       
   628                             elif base_type["name"] in ["string", "wstring"]:
       
   629                                 basetype_name = base_type["name"].upper()
       
   630                             # Array derived directly from an elementary type 
       
   631                             else:
       
   632                                 basetype_name = base_type["name"]
       
   633                             var_type = "ARRAY [%s] OF %s" % (",".join(map(lambda x : "%s..%s" % (x.getlower(), x.getupper()), vartype_content["value"].getdimension())), basetype_name)
       
   634                         else:
       
   635                             var_type = vartype_content["name"]
       
   636                         if address is not None:
   590                         if address is not None:
   637                             located.append((var_type, var.getname(), address, initial_value))
   591                             located.append((var_type, var.getname(), address, initial_value))
   638                         else:
   592                         else:
   639                             variables.append((var_type, var.getname(), None, initial_value))
   593                             variables.append((var_type, var.getname(), None, initial_value))
   640                 if varlist["value"].getconstant():
   594                 if varlist["value"].getconstant():
   877                         self.Program += [(";\n", ())]
   831                         self.Program += [(";\n", ())]
   878                 elif isinstance(instance, plcopen.fbdObjects_block):
   832                 elif isinstance(instance, plcopen.fbdObjects_block):
   879                     block_type = instance.gettypeName()
   833                     block_type = instance.gettypeName()
   880                     self.ParentGenerator.GeneratePouProgram(block_type)
   834                     self.ParentGenerator.GeneratePouProgram(block_type)
   881                     block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in instance.inputVariables.getvariable() if variable.getformalParameter() != "EN"]))
   835                     block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in instance.inputVariables.getvariable() if variable.getformalParameter() != "EN"]))
       
   836                     if block_infos is None:
       
   837                         block_infos = self.GetBlockType(block_type)
       
   838                     if block_infos is None:
       
   839                         raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name)
   882                     block_infos["generate"](self, instance, block_infos, body, None)
   840                     block_infos["generate"](self, instance, block_infos, body, None)
   883                 elif isinstance(instance, plcopen.commonObjects_connector):
   841                 elif isinstance(instance, plcopen.commonObjects_connector):
   884                     connector = instance.getname()
   842                     connector = instance.getname()
   885                     if self.ComputedConnectors.get(connector, None):
   843                     if self.ComputedConnectors.get(connector, None):
   886                         continue 
   844                         continue 
   932                 paths.append(str([(next.getexpression(), (self.TagName, "io_variable", localId, "expression"))]))
   890                 paths.append(str([(next.getexpression(), (self.TagName, "io_variable", localId, "expression"))]))
   933             elif isinstance(next, plcopen.fbdObjects_block):
   891             elif isinstance(next, plcopen.fbdObjects_block):
   934                 block_type = next.gettypeName()
   892                 block_type = next.gettypeName()
   935                 self.ParentGenerator.GeneratePouProgram(block_type)
   893                 self.ParentGenerator.GeneratePouProgram(block_type)
   936                 block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in next.inputVariables.getvariable() if variable.getformalParameter() != "EN"]))
   894                 block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in next.inputVariables.getvariable() if variable.getformalParameter() != "EN"]))
       
   895                 if block_infos is None:
       
   896                     block_infos = self.GetBlockType(block_type)
       
   897                 if block_infos is None:
       
   898                     raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name)
   937                 paths.append(str(block_infos["generate"](self, next, block_infos, body, connection, order)))
   899                 paths.append(str(block_infos["generate"](self, next, block_infos, body, connection, order)))
   938             elif isinstance(next, plcopen.commonObjects_continuation):
   900             elif isinstance(next, plcopen.commonObjects_continuation):
   939                 name = next.getname()
   901                 name = next.getname()
   940                 computed_value = self.ComputedConnectors.get(name, None)
   902                 computed_value = self.ComputedConnectors.get(name, None)
   941                 if computed_value != None:
   903                 if computed_value != None:
  1329             raise PLCGenException, _("No variable defined in \"%s\" POU")%self.Name
  1291             raise PLCGenException, _("No variable defined in \"%s\" POU")%self.Name
  1330         if len(self.Program) == 0 :
  1292         if len(self.Program) == 0 :
  1331             raise PLCGenException, _("No body defined in \"%s\" POU")%self.Name
  1293             raise PLCGenException, _("No body defined in \"%s\" POU")%self.Name
  1332         var_number = 0
  1294         var_number = 0
  1333         for list_type, option, located, variables in self.Interface:
  1295         for list_type, option, located, variables in self.Interface:
       
  1296             variable_type = errorVarTypes.get(list_type, "var_local")
  1334             program += [("  %s"%list_type, ())]
  1297             program += [("  %s"%list_type, ())]
  1335             if option is not None:
  1298             if option is not None:
  1336                 program += [(" %s"%option, (self.TagName, "variable", (var_number, var_number + len(variables)), option.lower()))]
  1299                 program += [(" %s"%option, (self.TagName, variable_type, (var_number, var_number + len(variables)), option.lower()))]
  1337             program += [("\n", ())]
  1300             program += [("\n", ())]
  1338             for var_type, var_name, var_address, var_initial in variables:
  1301             for var_type, var_name, var_address, var_initial in variables:
  1339                 program += [("    ", ())]
  1302                 program += [("    ", ())]
  1340                 if var_name:
  1303                 if var_name:
  1341                     program += [(var_name, (self.TagName, "variable", var_number, "name")),
  1304                     program += [(var_name, (self.TagName, variable_type, var_number, "name")),
  1342                                 (" ", ())]
  1305                                 (" ", ())]
  1343                 if var_address != None:
  1306                 if var_address != None:
  1344                     program += [("AT ", ()),
  1307                     program += [("AT ", ()),
  1345                                 (var_address, (self.TagName, "variable", var_number, "address")),
  1308                                 (var_address, (self.TagName, variable_type, var_number, "address")),
  1346                                 (" ", ())]
  1309                                 (" ", ())]
  1347                 program += [(": ", ()),
  1310                 program += [(": ", ()),
  1348                             (var_type, (self.TagName, "variable", var_number, "type"))]
  1311                             (var_type, (self.TagName, variable_type, var_number, "type"))]
  1349                 if var_initial != None:
  1312                 if var_initial != None:
  1350                     program += [(" := ", ()),
  1313                     program += [(" := ", ()),
  1351                                 (self.ParentGenerator.ComputeValue(var_initial, var_type), (self.TagName, "variable", var_number, "initial"))]
  1314                                 (self.ParentGenerator.ComputeValue(var_initial, var_type), (self.TagName, variable_type, var_number, "initial"))]
  1352                 program += [(";\n", ())]
  1315                 program += [(";\n", ())]
  1353                 var_number += 1
  1316                 var_number += 1
  1354             program += [("  END_VAR\n", ())]
  1317             program += [("  END_VAR\n", ())]
  1355         program += [("\n", ())]
  1318         program += [("\n", ())]
  1356         program += self.Program
  1319         program += self.Program