PLCGenerator.py
changeset 269 34eff05909b0
parent 261 6fe3ee00f9a0
child 273 5b18d98aa4f9
equal deleted inserted replaced
268:5508af39d1f7 269:34eff05909b0
    59                     compute += "%s%s\n"%(indent, line)
    59                     compute += "%s%s\n"%(indent, line)
    60                 else:
    60                 else:
    61                     compute += "\n"
    61                     compute += "\n"
    62     return compute
    62     return compute
    63 
    63 
       
    64 def SortInstances(a, b):
       
    65     ax, ay = int(a.getx()), int(a.gety())
       
    66     bx, by = int(b.getx()), int(b.gety())
       
    67     if abs(ax - ay) < 10:
       
    68         return ax.__cmp__(bx)
       
    69     else:
       
    70         return ay.__cmp__(by)
    64 
    71 
    65 #-------------------------------------------------------------------------------
    72 #-------------------------------------------------------------------------------
    66 #                  Specific exception for PLC generating errors
    73 #                  Specific exception for PLC generating errors
    67 #-------------------------------------------------------------------------------
    74 #-------------------------------------------------------------------------------
    68 
    75 
   564                         elif returntype_content["name"] in ["string", "wstring"]:
   571                         elif returntype_content["name"] in ["string", "wstring"]:
   565                             var_type = returntype_content["name"].upper()
   572                             var_type = returntype_content["name"].upper()
   566                         else:
   573                         else:
   567                             var_type = returntype_content["name"]
   574                             var_type = returntype_content["name"]
   568                     elif var_type is None:
   575                     elif var_type is None:
   569                         var_type = expression.split("#")[0]
   576                         parts = expression.split("#")
   570                     if isinstance(instance, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_inOutVariable)):
   577                         if len(parts) > 1:
   571                         for connection in self.ExtractRelatedConnections(instance.connectionPointOut):
   578                             var_type = parts[0]
   572                             self.ConnectionTypes[connection] = var_type
   579                     if var_type is not None:
   573                     if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   580                         if isinstance(instance, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_inOutVariable)):
   574                         self.ConnectionTypes[instance.connectionPointIn] = var_type
   581                             for connection in self.ExtractRelatedConnections(instance.connectionPointOut):
   575                         connected = self.GetConnectedConnector(instance.connectionPointIn, body)
       
   576                         if connected and connected not in self.ConnectionTypes:
       
   577                             for connection in self.ExtractRelatedConnections(connected):
       
   578                                 self.ConnectionTypes[connection] = var_type
   582                                 self.ConnectionTypes[connection] = var_type
       
   583                         if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
       
   584                             self.ConnectionTypes[instance.connectionPointIn] = var_type
       
   585                             connected = self.GetConnectedConnector(instance.connectionPointIn, body)
       
   586                             if connected and connected not in self.ConnectionTypes:
       
   587                                 for connection in self.ExtractRelatedConnections(connected):
       
   588                                     self.ConnectionTypes[connection] = var_type
   579                 elif isinstance(instance, (plcopen.ldObjects_contact, plcopen.ldObjects_coil)):
   589                 elif isinstance(instance, (plcopen.ldObjects_contact, plcopen.ldObjects_coil)):
   580                     for connection in self.ExtractRelatedConnections(instance.connectionPointOut):
   590                     for connection in self.ExtractRelatedConnections(instance.connectionPointOut):
   581                         self.ConnectionTypes[connection] = "BOOL"
   591                         self.ConnectionTypes[connection] = "BOOL"
   582                     self.ConnectionTypes[instance.connectionPointIn] = "BOOL"
   592                     self.ConnectionTypes[instance.connectionPointIn] = "BOOL"
   583                     connected = self.GetConnectedConnector(instance.connectionPointIn, body)
   593                     connected = self.GetConnectedConnector(instance.connectionPointIn, body)
   605                 elif isinstance(instance, plcopen.fbdObjects_block):
   615                 elif isinstance(instance, plcopen.fbdObjects_block):
   606                     block_infos = self.GetBlockType(instance.gettypeName())
   616                     block_infos = self.GetBlockType(instance.gettypeName())
   607                     undefined = {}
   617                     undefined = {}
   608                     for variable in instance.outputVariables.getvariable():
   618                     for variable in instance.outputVariables.getvariable():
   609                         output_name = variable.getformalParameter()
   619                         output_name = variable.getformalParameter()
   610                         for oname, otype, oqualifier in block_infos["outputs"]:
   620                         if output_name == "ENO":
   611                             if output_name == oname and variable.connectionPointOut not in self.ConnectionTypes:
   621                             for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
   612                                 if otype.startswith("ANY"):
   622                                 self.ConnectionTypes[connection] = "BOOL"
   613                                     if otype not in undefined:
   623                         else:
   614                                         undefined[otype] = []
   624                             for oname, otype, oqualifier in block_infos["outputs"]:
   615                                     undefined[otype].append(variable.connectionPointOut)
   625                                 if output_name == oname and variable.connectionPointOut not in self.ConnectionTypes:
   616                                 else:
   626                                     if otype.startswith("ANY"):
   617                                     for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
   627                                         if otype not in undefined:
   618                                         self.ConnectionTypes[connection] = otype
   628                                             undefined[otype] = []
       
   629                                         undefined[otype].append(variable.connectionPointOut)
       
   630                                     else:
       
   631                                         for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
       
   632                                             self.ConnectionTypes[connection] = otype
   619                     for variable in instance.inputVariables.getvariable():
   633                     for variable in instance.inputVariables.getvariable():
   620                         input_name = variable.getformalParameter()
   634                         input_name = variable.getformalParameter()
       
   635                         if input_name == "EN":
       
   636                             for connection in self.ExtractRelatedConnections(variable.connectionPointIn):
       
   637                                 self.ConnectionTypes[connection] = "BOOL"
   621                         for iname, itype, iqualifier in block_infos["inputs"]:
   638                         for iname, itype, iqualifier in block_infos["inputs"]:
   622                             if input_name == iname:
   639                             if input_name == iname:
   623                                 connected = self.GetConnectedConnector(variable.connectionPointIn, body)
   640                                 connected = self.GetConnectedConnector(variable.connectionPointIn, body)
   624                                 if itype.startswith("ANY"):
   641                                 if itype.startswith("ANY"):
   625                                     if itype not in undefined:
   642                                     if itype not in undefined:
   671                 self.Program = []
   688                 self.Program = []
   672             self.IndentLeft()
   689             self.IndentLeft()
   673             for initialstep in self.InitialSteps:
   690             for initialstep in self.InitialSteps:
   674                 self.ComputeSFCStep(initialstep)
   691                 self.ComputeSFCStep(initialstep)
   675         else:
   692         else:
       
   693             otherInstances = {"outVariables&coils" : [], "blocks" : [], "connectors" : []}
   676             orderedInstances = []
   694             orderedInstances = []
   677             otherInstances = {"outVariables" : [], "block" : [], "connector" : [], "coil" : []}
       
   678             for instance in body.getcontentInstances():
   695             for instance in body.getcontentInstances():
   679                 if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable, plcopen.fbdObjects_block)):
   696                 if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable, plcopen.fbdObjects_block)):
   680                     executionOrderId = instance.getexecutionOrderId()
   697                     executionOrderId = instance.getexecutionOrderId()
   681                     if executionOrderId > 0:
   698                     if executionOrderId > 0:
   682                         orderedInstances.append((executionOrderId, instance))
   699                         orderedInstances.append((executionOrderId, instance))
   683                     elif isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   700                     elif isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   684                         otherInstances["outVariables"].append(instance)
   701                         otherInstances["outVariables&coils"].append(instance)
   685                     elif isinstance(instance, plcopen.fbdObjects_block):
   702                     elif isinstance(instance, plcopen.fbdObjects_block):
   686                         otherInstances["block"].append(instance)
   703                         otherInstances["blocks"].append(instance)
   687                 elif isinstance(instance, plcopen.commonObjects_connector):
   704                 elif isinstance(instance, plcopen.commonObjects_connector):
   688                     otherInstances["connector"].append(instance)
   705                     otherInstances["connectors"].append(instance)
   689                 elif isinstance(instance, plcopen.ldObjects_coil):
   706                 elif isinstance(instance, plcopen.ldObjects_coil):
   690                     otherInstances["coil"].append(instance)
   707                     otherInstances["outVariables&coils"].append(instance)
   691             orderedInstances.sort()
   708             orderedInstances.sort()
       
   709             otherInstances["outVariables&coils"].sort(SortInstances)
   692             instances = [instance for (executionOrderId, instance) in orderedInstances]
   710             instances = [instance for (executionOrderId, instance) in orderedInstances]
   693             instances.extend(otherInstances["connector"] + otherInstances["outVariables"] + otherInstances["coil"] + otherInstances["block"])
   711             instances.extend(otherInstances["connectors"] + otherInstances["outVariables&coils"] + otherInstances["blocks"])
   694             for instance in instances:
   712             for instance in instances:
   695                 if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   713                 if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   696                     connections = instance.connectionPointIn.getconnections()
   714                     connections = instance.connectionPointIn.getconnections()
   697                     if connections is not None:
   715                     if connections is not None:
   698                         expression = self.ComputeExpression(body, connections)
   716                         expression = self.ComputeExpression(body, connections)
   712                         continue 
   730                         continue 
   713                     self.ComputedConnectors[connector] = self.ComputeExpression(body, instance.connectionPointIn.getconnections())
   731                     self.ComputedConnectors[connector] = self.ComputeExpression(body, instance.connectionPointIn.getconnections())
   714                 elif isinstance(instance, plcopen.ldObjects_coil):
   732                 elif isinstance(instance, plcopen.ldObjects_coil):
   715                     connections = instance.connectionPointIn.getconnections()
   733                     connections = instance.connectionPointIn.getconnections()
   716                     if connections is not None:
   734                     if connections is not None:
   717                         expression = self.ComputeExpression(body, connections)
       
   718                         coil_info = (self.TagName, "coil", instance.getlocalId())
   735                         coil_info = (self.TagName, "coil", instance.getlocalId())
   719                         variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info)
   736                         expression = self.ExtractModifier(instance, self.ComputeExpression(body, connections), coil_info)
   720                         self.Program += [(self.CurrentIndent, ())] + variable
   737                         self.Program += [(self.CurrentIndent, ())]
       
   738                         self.Program += [(instance.getvariable(), coil_info + ("reference",))]
   721                         self.Program += [(" := ", ())] + expression + [(";\n", ())]
   739                         self.Program += [(" := ", ())] + expression + [(";\n", ())]
   722             
   740                         
   723     def FactorizePaths(self, paths):
   741     def FactorizePaths(self, paths):
   724         same_paths = {}
   742         same_paths = {}
   725         uncomputed_index = range(len(paths))
   743         uncomputed_index = range(len(paths))
   726         factorized_paths = []
   744         factorized_paths = []
   727         for num, path in enumerate(paths):
   745         for num, path in enumerate(paths):
   827 
   845 
   828     def ExtractModifier(self, variable, expression, var_info):
   846     def ExtractModifier(self, variable, expression, var_info):
   829         if variable.getnegated():
   847         if variable.getnegated():
   830             return [("NOT(", var_info + ("negated",))] + expression + [(")", ())]
   848             return [("NOT(", var_info + ("negated",))] + expression + [(")", ())]
   831         else:
   849         else:
       
   850             storage = variable.getstorage()
       
   851             if storage in ["set", "reset"]:
       
   852                 self.Program += [(self.CurrentIndent + "IF ", var_info + (storage,))] + expression
       
   853                 self.Program += [(" THEN\n  ", ())]
       
   854                 if storage == "set":
       
   855                     return [("TRUE;\n" + self.CurrentIndent + "END_IF", ())]
       
   856                 else:
       
   857                     return [("FALSE;\n" + self.CurrentIndent + "END_IF", ())]
   832             edge = variable.getedge()
   858             edge = variable.getedge()
   833             if edge == "rising":
   859             if edge == "rising":
   834                 return self.AddTrigger("R_TRIG", expression, var_info + ("rising",))
   860                 return self.AddTrigger("R_TRIG", expression, var_info + ("rising",))
   835             elif edge == "falling":
   861             elif edge == "falling":
   836                 return self.AddTrigger("F_TRIG", expression, var_info + ("falling",))
   862                 return self.AddTrigger("F_TRIG", expression, var_info + ("falling",))