PLCGenerator.py
changeset 389 6a72016d721a
parent 370 23af12b5a9fb
child 391 07447ee3538e
equal deleted inserted replaced
388:7ea1f5094df3 389:6a72016d721a
   141                     basetype_name = base_type["name"]
   141                     basetype_name = base_type["name"]
   142                 min_value = basetype_content["value"].range.getlower()
   142                 min_value = basetype_content["value"].range.getlower()
   143                 max_value = basetype_content["value"].range.getupper()
   143                 max_value = basetype_content["value"].range.getupper()
   144                 datatype_def += [(basetype_name, (tagname, "base")),
   144                 datatype_def += [(basetype_name, (tagname, "base")),
   145                                  (" (", ()),
   145                                  (" (", ()),
   146                                  ("%d"%min_value, (tagname, "lower")),
   146                                  ("%s"%min_value, (tagname, "lower")),
   147                                  ("..", ()),
   147                                  ("..", ()),
   148                                  ("%d"%max_value, (tagname, "upper")),
   148                                  ("%s"%max_value, (tagname, "upper")),
   149                                  (")",())]
   149                                  (")",())]
   150             # Data type is an enumerated type
   150             # Data type is an enumerated type
   151             elif basetype_content["name"] == "enum":
   151             elif basetype_content["name"] == "enum":
   152                 values = [[(value.getname(), (tagname, "value", i))]
   152                 values = [[(value.getname(), (tagname, "value", i))]
   153                           for i, value in enumerate(basetype_content["value"].values.getvalue())]
   153                           for i, value in enumerate(basetype_content["value"].values.getvalue())]
   165                 elif base_type["name"] in ["string", "wstring"]:
   165                 elif base_type["name"] in ["string", "wstring"]:
   166                     basetype_name = base_type["name"].upper()
   166                     basetype_name = base_type["name"].upper()
   167                 # Array derived directly from an elementary type 
   167                 # Array derived directly from an elementary type 
   168                 else:
   168                 else:
   169                     basetype_name = base_type["name"]
   169                     basetype_name = base_type["name"]
   170                 dimensions = [[("%d"%dimension.getlower(), (tagname, "range", i, "lower")),
   170                 dimensions = [[("%s"%dimension.getlower(), (tagname, "range", i, "lower")),
   171                                ("..", ()),
   171                                ("..", ()),
   172                                ("%d"%dimension.getupper(), (tagname, "range", i, "upper"))] 
   172                                ("%s"%dimension.getupper(), (tagname, "range", i, "upper"))] 
   173                               for i, dimension in enumerate(basetype_content["value"].getdimension())]
   173                               for i, dimension in enumerate(basetype_content["value"].getdimension())]
   174                 datatype_def += [("ARRAY [", ())]
   174                 datatype_def += [("ARRAY [", ())]
   175                 datatype_def += JoinList([(",", ())], dimensions)
   175                 datatype_def += JoinList([(",", ())], dimensions)
   176                 datatype_def += [("] OF " , ()),
   176                 datatype_def += [("] OF " , ()),
   177                                  (basetype_name, (tagname, "base"))]
   177                                  (basetype_name, (tagname, "base"))]
   354                            (single, (tagname, "task", task_number, "single")),
   354                            (single, (tagname, "task", task_number, "single")),
   355                            (",", ())]
   355                            (",", ())]
   356             # Interval argument if exists
   356             # Interval argument if exists
   357             interval = task.getinterval()
   357             interval = task.getinterval()
   358             if interval:
   358             if interval:
   359                 resrce += [("INTERVAL := t#", ())]
   359                 resrce += [("INTERVAL := ", ()),
   360                 if interval.hour != 0:
   360                            (interval, (tagname, "task", task_number, "interval")),
   361                     resrce += [("%dh"%interval.hour, (tagname, "task", task_number, "interval", "hour"))]
   361                            (",", ())]
   362                 if interval.minute != 0:
   362 ##                resrce += [("INTERVAL := t#", ())]
   363                     resrce += [("%dm"%interval.minute, (tagname, "task", task_number, "interval", "minute"))]
   363 ##                if interval.hour != 0:
   364                 if interval.second != 0:
   364 ##                    resrce += [("%dh"%interval.hour, (tagname, "task", task_number, "interval", "hour"))]
   365                     resrce += [("%ds"%interval.second, (tagname, "task", task_number, "interval", "second"))]
   365 ##                if interval.minute != 0:
   366                 if interval.microsecond != 0:
   366 ##                    resrce += [("%dm"%interval.minute, (tagname, "task", task_number, "interval", "minute"))]
   367                     resrce += [("%dms"%(interval.microsecond / 1000), (tagname, "task", task_number, "interval", "millisecond"))]
   367 ##                if interval.second != 0:
   368                 resrce += [(",", ())]
   368 ##                    resrce += [("%ds"%interval.second, (tagname, "task", task_number, "interval", "second"))]
       
   369 ##                if interval.microsecond != 0:
       
   370 ##                    resrce += [("%dms"%(interval.microsecond / 1000), (tagname, "task", task_number, "interval", "millisecond"))]
       
   371 ##                resrce += [(",", ())]
   369             # Priority argument
   372             # Priority argument
   370             resrce += [("PRIORITY := ", ()), 
   373             resrce += [("PRIORITY := ", ()), 
   371                        ("%d"%task.getpriority(), (tagname, "task", task_number, "priority")),
   374                        ("%d"%task.getpriority(), (tagname, "task", task_number, "priority")),
   372                        (");\n", ())]
   375                        (");\n", ())]
   373             task_number += 1
   376             task_number += 1
   378                 resrce += [("    PROGRAM ", ()),
   381                 resrce += [("    PROGRAM ", ()),
   379                            (instance.getname(), (tagname, "instance", instance_number, "name")),
   382                            (instance.getname(), (tagname, "instance", instance_number, "name")),
   380                            (" WITH ", ()),
   383                            (" WITH ", ()),
   381                            (task.getname(), (tagname, "instance", instance_number, "task")),
   384                            (task.getname(), (tagname, "instance", instance_number, "task")),
   382                            (" : ", ()),
   385                            (" : ", ()),
   383                            (instance.gettype(), (tagname, "instance", instance_number, "type")),
   386                            (instance.gettypeName(), (tagname, "instance", instance_number, "type")),
   384                            (";\n", ())]
   387                            (";\n", ())]
   385                 instance_number += 1
   388                 instance_number += 1
   386         # Generate any program assign to no task
   389         # Generate any program assign to no task
   387         for instance in resource.getpouInstance():
   390         for instance in resource.getpouInstance():
   388             resrce += [("    PROGRAM ", ()),
   391             resrce += [("    PROGRAM ", ()),
   389                            (instance.getname(), (tagname, "instance", instance_number, "name")),
   392                            (instance.getname(), (tagname, "instance", instance_number, "name")),
   390                            (" : ", ()),
   393                            (" : ", ()),
   391                            (instance.gettype(), (tagname, "instance", instance_number, "type")),
   394                            (instance.gettypeName(), (tagname, "instance", instance_number, "type")),
   392                            (";\n", ())]
   395                            (";\n", ())]
   393             instance_number += 1
   396             instance_number += 1
   394         resrce += [("  END_RESOURCE\n", ())]
   397         resrce += [("  END_RESOURCE\n", ())]
   395         return resrce
   398         return resrce
   396     
   399     
   530     
   533     
   531     def ComputeInterface(self, pou):
   534     def ComputeInterface(self, pou):
   532         interface = pou.getinterface()
   535         interface = pou.getinterface()
   533         if interface is not None:
   536         if interface is not None:
   534             body = pou.getbody()
   537             body = pou.getbody()
       
   538             if isinstance(body, ListType):
       
   539                 body = body[0]
   535             body_content = body.getcontent()
   540             body_content = body.getcontent()
   536             if self.Type == "FUNCTION":
   541             if self.Type == "FUNCTION":
   537                 returntype_content = interface.getreturnType().getcontent()
   542                 returntype_content = interface.getreturnType().getcontent()
   538                 if returntype_content["name"] == "derived":
   543                 if returntype_content["name"] == "derived":
   539                     self.ReturnType = returntype_content["value"].getname()
   544                     self.ReturnType = returntype_content["value"].getname()
   594                     self.Interface.append((varTypeNames[varlist["name"]], varlist["value"].getretain(), 
   599                     self.Interface.append((varTypeNames[varlist["name"]], varlist["value"].getretain(), 
   595                                 varlist["value"].getconstant(), True, located))
   600                                 varlist["value"].getconstant(), True, located))
   596         
   601         
   597     def ComputeConnectionTypes(self, pou):
   602     def ComputeConnectionTypes(self, pou):
   598         body = pou.getbody()
   603         body = pou.getbody()
       
   604         if isinstance(body, ListType):
       
   605             body = body[0]
   599         body_content = body.getcontent()
   606         body_content = body.getcontent()
   600         body_type = body_content["name"]
   607         body_type = body_content["name"]
   601         if body_type in ["FBD", "LD", "SFC"]:
   608         if body_type in ["FBD", "LD", "SFC"]:
   602             for instance in body.getcontentInstances():
   609             for instance in body.getcontentInstances():
   603                 if isinstance(instance, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   610                 if isinstance(instance, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   682                                 self.ConnectionTypes[connection] = var_type
   689                                 self.ConnectionTypes[connection] = var_type
   683                     else:
   690                     else:
   684                         raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name)
   691                         raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name)
   685                 elif isinstance(instance, plcopen.fbdObjects_block):
   692                 elif isinstance(instance, plcopen.fbdObjects_block):
   686                     block_infos = self.GetBlockType(instance.gettypeName())
   693                     block_infos = self.GetBlockType(instance.gettypeName())
   687                     undefined = {}
   694                     if block_infos is not None:
   688                     for variable in instance.outputVariables.getvariable():
   695                         undefined = {}
   689                         output_name = variable.getformalParameter()
   696                         for variable in instance.outputVariables.getvariable():
   690                         if output_name == "ENO":
   697                             output_name = variable.getformalParameter()
   691                             for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
   698                             if output_name == "ENO":
   692                                 self.ConnectionTypes[connection] = "BOOL"
   699                                 for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
   693                         else:
   700                                     self.ConnectionTypes[connection] = "BOOL"
   694                             for oname, otype, oqualifier in block_infos["outputs"]:
   701                             else:
   695                                 if output_name == oname:
   702                                 for oname, otype, oqualifier in block_infos["outputs"]:
   696                                     if otype.startswith("ANY"):
   703                                     if output_name == oname:
   697                                         if not undefined.has_key(otype):
   704                                         if otype.startswith("ANY"):
   698                                             undefined[otype] = []
   705                                             if not undefined.has_key(otype):
   699                                         undefined[otype].append(variable.connectionPointOut)
   706                                                 undefined[otype] = []
   700                                     elif not self.ConnectionTypes.has_key(variable.connectionPointOut):
   707                                             undefined[otype].append(variable.connectionPointOut)
   701                                         for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
   708                                         elif not self.ConnectionTypes.has_key(variable.connectionPointOut):
   702                                             self.ConnectionTypes[connection] = otype
   709                                             for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
   703                     for variable in instance.inputVariables.getvariable():
   710                                                 self.ConnectionTypes[connection] = otype
   704                         input_name = variable.getformalParameter()
   711                         for variable in instance.inputVariables.getvariable():
   705                         if input_name == "EN":
   712                             input_name = variable.getformalParameter()
   706                             for connection in self.ExtractRelatedConnections(variable.connectionPointIn):
   713                             if input_name == "EN":
   707                                 self.ConnectionTypes[connection] = "BOOL"
   714                                 for connection in self.ExtractRelatedConnections(variable.connectionPointIn):
   708                         for iname, itype, iqualifier in block_infos["inputs"]:
   715                                     self.ConnectionTypes[connection] = "BOOL"
   709                             if input_name == iname:
   716                             for iname, itype, iqualifier in block_infos["inputs"]:
   710                                 connected = self.GetConnectedConnector(variable.connectionPointIn, body)
   717                                 if input_name == iname:
   711                                 if itype.startswith("ANY"):
   718                                     connected = self.GetConnectedConnector(variable.connectionPointIn, body)
   712                                     if not undefined.has_key(itype):
   719                                     if itype.startswith("ANY"):
   713                                         undefined[itype] = []
   720                                         if not undefined.has_key(itype):
   714                                     undefined[itype].append(variable.connectionPointIn)
   721                                             undefined[itype] = []
   715                                     if connected:
   722                                         undefined[itype].append(variable.connectionPointIn)
   716                                         undefined[itype].append(connected)
   723                                         if connected:
       
   724                                             undefined[itype].append(connected)
       
   725                                     else:
       
   726                                         self.ConnectionTypes[variable.connectionPointIn] = itype
       
   727                                         if connected and not self.ConnectionTypes.has_key(connected):
       
   728                                             for connection in self.ExtractRelatedConnections(connected):
       
   729                                                 self.ConnectionTypes[connection] = itype
       
   730                         for var_type, connections in undefined.items():
       
   731                             related = []
       
   732                             for connection in connections:
       
   733                                 if self.ConnectionTypes.has_key(connection):
       
   734                                     var_type = self.ConnectionTypes[connection]
   717                                 else:
   735                                 else:
   718                                     self.ConnectionTypes[variable.connectionPointIn] = itype
   736                                     related.extend(self.ExtractRelatedConnections(connection))
   719                                     if connected and not self.ConnectionTypes.has_key(connected):
   737                             if var_type.startswith("ANY") and len(related) > 0:
   720                                         for connection in self.ExtractRelatedConnections(connected):
   738                                 self.RelatedConnections.append(related)
   721                                             self.ConnectionTypes[connection] = itype
       
   722                     for var_type, connections in undefined.items():
       
   723                         related = []
       
   724                         for connection in connections:
       
   725                             if self.ConnectionTypes.has_key(connection):
       
   726                                 var_type = self.ConnectionTypes[connection]
       
   727                             else:
   739                             else:
   728                                 related.extend(self.ExtractRelatedConnections(connection))
   740                                 for connection in related:
   729                         if var_type.startswith("ANY") and len(related) > 0:
   741                                     self.ConnectionTypes[connection] = var_type
   730                             self.RelatedConnections.append(related)
   742                     else:
   731                         else:
   743                         raise PLCGenException, _("No informations found for \"%s\" block")%(instance.gettypeName())
   732                             for connection in related:
   744 
   733                                 self.ConnectionTypes[connection] = var_type
       
   734     
       
   735     def ComputeProgram(self, pou):
   745     def ComputeProgram(self, pou):
   736         body = pou.getbody()
   746         body = pou.getbody()
       
   747         if isinstance(body, ListType):
       
   748             body = body[0]
   737         body_content = body.getcontent()
   749         body_content = body.getcontent()
   738         body_type = body_content["name"]
   750         body_type = body_content["name"]
   739         if body_type in ["IL","ST"]:
   751         if body_type in ["IL","ST"]:
   740             text = body_content["value"].gettext()
   752             text = body_content["value"].gettext()
   741             self.ParentGenerator.GeneratePouProgramInText(text.upper())
   753             self.ParentGenerator.GeneratePouProgramInText(text.upper())
   956         connectionPointIn = divergence.getconnectionPointIn()
   968         connectionPointIn = divergence.getconnectionPointIn()
   957         if connectionPointIn:
   969         if connectionPointIn:
   958             connections = connectionPointIn.getconnections()
   970             connections = connectionPointIn.getconnections()
   959             if connections is not None and len(connections) == 1:
   971             if connections is not None and len(connections) == 1:
   960                 instanceLocalId = connections[0].getrefLocalId()
   972                 instanceLocalId = connections[0].getrefLocalId()
   961                 return pou.body.getcontentInstance(instanceLocalId)
   973                 body = pou.getbody()
       
   974                 if isinstance(body, ListType):
       
   975                     body = body[0]
       
   976                 return body.getcontentInstance(instanceLocalId)
   962         return None
   977         return None
   963 
   978 
   964     def ExtractConvergenceInputs(self, convergence, pou):
   979     def ExtractConvergenceInputs(self, convergence, pou):
   965         instances = []
   980         instances = []
   966         for connectionPointIn in convergence.getconnectionPointIn():
   981         for connectionPointIn in convergence.getconnectionPointIn():
   967             connections = connectionPointIn.getconnections()
   982             connections = connectionPointIn.getconnections()
   968             if len(connections) == 1:
   983             if len(connections) == 1:
   969                 instanceLocalId = connections[0].getrefLocalId()
   984                 instanceLocalId = connections[0].getrefLocalId()
   970                 instances.append(pou.body.getcontentInstance(instanceLocalId))
   985                 body = pou.getbody()
       
   986                 if isinstance(body, ListType):
       
   987                     body = body[0]
       
   988                 instances.append(body.getcontentInstance(instanceLocalId))
   971         return instances
   989         return instances
   972 
   990 
   973     def GenerateSFCStep(self, step, pou):
   991     def GenerateSFCStep(self, step, pou):
   974         step_name = step.getname()
   992         step_name = step.getname()
   975         if step_name not in self.SFCNetworks["Steps"].keys():
   993         if step_name not in self.SFCNetworks["Steps"].keys():
   982             if step.connectionPointIn:
  1000             if step.connectionPointIn:
   983                 instances = []
  1001                 instances = []
   984                 connections = step.connectionPointIn.getconnections()
  1002                 connections = step.connectionPointIn.getconnections()
   985                 if len(connections) == 1:
  1003                 if len(connections) == 1:
   986                     instanceLocalId = connections[0].getrefLocalId()
  1004                     instanceLocalId = connections[0].getrefLocalId()
   987                     instance = pou.body.getcontentInstance(instanceLocalId)
  1005                     body = pou.getbody()
       
  1006                     if isinstance(body, ListType):
       
  1007                         body = body[0]
       
  1008                     instance = body.getcontentInstance(instanceLocalId)
   988                     if isinstance(instance, plcopen.sfcObjects_transition):
  1009                     if isinstance(instance, plcopen.sfcObjects_transition):
   989                         instances.append(instance)
  1010                         instances.append(instance)
   990                     elif isinstance(instance, plcopen.sfcObjects_selectionConvergence):
  1011                     elif isinstance(instance, plcopen.sfcObjects_selectionConvergence):
   991                         instances.extend(self.ExtractConvergenceInputs(instance, pou))
  1012                         instances.extend(self.ExtractConvergenceInputs(instance, pou))
   992                     elif isinstance(instance, plcopen.sfcObjects_simultaneousDivergence):
  1013                     elif isinstance(instance, plcopen.sfcObjects_simultaneousDivergence):
  1008         if jump.connectionPointIn:
  1029         if jump.connectionPointIn:
  1009             instances = []
  1030             instances = []
  1010             connections = jump.connectionPointIn.getconnections()
  1031             connections = jump.connectionPointIn.getconnections()
  1011             if len(connections) == 1:
  1032             if len(connections) == 1:
  1012                 instanceLocalId = connections[0].getrefLocalId()
  1033                 instanceLocalId = connections[0].getrefLocalId()
  1013                 instance = pou.body.getcontentInstance(instanceLocalId)
  1034                 body = pou.getbody()
       
  1035                 if isinstance(body, ListType):
       
  1036                     body = body[0]
       
  1037                 instance = body.getcontentInstance(instanceLocalId)
  1014                 if isinstance(instance, plcopen.sfcObjects_transition):
  1038                 if isinstance(instance, plcopen.sfcObjects_transition):
  1015                     instances.append(instance)
  1039                     instances.append(instance)
  1016                 elif isinstance(instance, plcopen.sfcObjects_selectionConvergence):
  1040                 elif isinstance(instance, plcopen.sfcObjects_selectionConvergence):
  1017                     instances.extend(self.ExtractConvergenceInputs(instance, pou))
  1041                     instances.extend(self.ExtractConvergenceInputs(instance, pou))
  1018                 elif isinstance(instance, plcopen.sfcObjects_simultaneousDivergence):
  1042                 elif isinstance(instance, plcopen.sfcObjects_simultaneousDivergence):
  1030     
  1054     
  1031     def GenerateSFCStepActions(self, actionBlock, pou):
  1055     def GenerateSFCStepActions(self, actionBlock, pou):
  1032         connections = actionBlock.connectionPointIn.getconnections()
  1056         connections = actionBlock.connectionPointIn.getconnections()
  1033         if connections is not None and len(connections) == 1:
  1057         if connections is not None and len(connections) == 1:
  1034             stepLocalId = connections[0].getrefLocalId()
  1058             stepLocalId = connections[0].getrefLocalId()
  1035             step = pou.body.getcontentInstance(stepLocalId)
  1059             body = pou.getbody()
       
  1060             if isinstance(body, ListType):
       
  1061                 body = body[0]
       
  1062             step = body.getcontentInstance(stepLocalId)
  1036             self.GenerateSFCStep(step, pou)
  1063             self.GenerateSFCStep(step, pou)
  1037             step_name = step.getname()
  1064             step_name = step.getname()
  1038             if step_name in self.SFCNetworks["Steps"].keys():
  1065             if step_name in self.SFCNetworks["Steps"].keys():
  1039                 actions = actionBlock.getactions()
  1066                 actions = actionBlock.getactions()
  1040                 for i, action in enumerate(actions):
  1067                 for i, action in enumerate(actions):
  1071         if transition not in self.SFCNetworks["Transitions"].keys():
  1098         if transition not in self.SFCNetworks["Transitions"].keys():
  1072             steps = []
  1099             steps = []
  1073             connections = transition.connectionPointIn.getconnections()
  1100             connections = transition.connectionPointIn.getconnections()
  1074             if connections is not None and len(connections) == 1:
  1101             if connections is not None and len(connections) == 1:
  1075                 instanceLocalId = connections[0].getrefLocalId()
  1102                 instanceLocalId = connections[0].getrefLocalId()
  1076                 instance = pou.body.getcontentInstance(instanceLocalId)
  1103                 body = pou.getbody()
       
  1104                 if isinstance(body, ListType):
       
  1105                     body = body[0]
       
  1106                 instance = body.getcontentInstance(instanceLocalId)
  1077                 if isinstance(instance, plcopen.sfcObjects_step):
  1107                 if isinstance(instance, plcopen.sfcObjects_step):
  1078                     steps.append(instance)
  1108                     steps.append(instance)
  1079                 elif isinstance(instance, plcopen.sfcObjects_selectionDivergence):
  1109                 elif isinstance(instance, plcopen.sfcObjects_selectionDivergence):
  1080                     step = self.ExtractDivergenceInput(instance, pou)
  1110                     step = self.ExtractDivergenceInput(instance, pou)
  1081                     if step:
  1111                     if step:
  1117                                 self.SFCComputedBlocks += self.Program
  1147                                 self.SFCComputedBlocks += self.Program
  1118                                 self.Program = []
  1148                                 self.Program = []
  1119                 self.TagName = previous_tagname
  1149                 self.TagName = previous_tagname
  1120             elif transitionValues["type"] == "connection":
  1150             elif transitionValues["type"] == "connection":
  1121                 body = pou.getbody()
  1151                 body = pou.getbody()
       
  1152                 if isinstance(body, ListType):
       
  1153                     body = body[0]
  1122                 connections = transition.getconnections()
  1154                 connections = transition.getconnections()
  1123                 if connections is not None:
  1155                 if connections is not None:
  1124                     expression = self.ComputeExpression(body, connections)
  1156                     expression = self.ComputeExpression(body, connections)
  1125                     transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]
  1157                     transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]
  1126                     self.SFCComputedBlocks += self.Program
  1158                     self.SFCComputedBlocks += self.Program