PLCControler.py
changeset 236 9f594b90bb1a
parent 233 de7ddb376150
child 249 d8425712acef
equal deleted inserted replaced
235:7b58a3b5b6ec 236:9f594b90bb1a
    47 
    47 
    48 ITEMS_UNEDITABLE=[ITEM_DATATYPES,
    48 ITEMS_UNEDITABLE=[ITEM_DATATYPES,
    49                   ITEM_FUNCTION,
    49                   ITEM_FUNCTION,
    50                   ITEM_FUNCTIONBLOCK,
    50                   ITEM_FUNCTIONBLOCK,
    51                   ITEM_PROGRAM,
    51                   ITEM_PROGRAM,
       
    52                   ITEM_VAR_LOCAL,
       
    53                   ITEM_VAR_GLOBAL,
       
    54                   ITEM_VAR_EXTERNAL,
       
    55                   ITEM_VAR_TEMP,
       
    56                   ITEM_VAR_INPUT,
       
    57                   ITEM_VAR_OUTPUT,
       
    58                   ITEM_VAR_INOUT,
    52                   ITEM_TRANSITIONS,
    59                   ITEM_TRANSITIONS,
    53                   ITEM_ACTIONS,
    60                   ITEM_ACTIONS,
    54                   ITEM_CONFIGURATIONS,
    61                   ITEM_CONFIGURATIONS,
    55                   ITEM_RESOURCES,
    62                   ITEM_RESOURCES,
    56                   ITEM_PROPERTIES,
    63                   ITEM_PROPERTIES,
    57                   ]=range(9,18)
    64                   ]=range(9,25)
       
    65 
       
    66 VAR_CLASS_INFOS = {"Local" :    (plcopen.interface_localVars,    ITEM_VAR_LOCAL),
       
    67                    "Global" :   (plcopen.interface_globalVars,   ITEM_VAR_GLOBAL),
       
    68                    "External" : (plcopen.interface_externalVars, ITEM_VAR_EXTERNAL),
       
    69                    "Temp" :     (plcopen.interface_tempVars,     ITEM_VAR_TEMP),
       
    70                    "Input" :    (plcopen.interface_inputVars,    ITEM_VAR_INPUT),
       
    71                    "Output" :   (plcopen.interface_outputVars,   ITEM_VAR_OUTPUT),
       
    72                    "InOut" :    (plcopen.interface_inOutVars,    ITEM_VAR_INOUT)
       
    73                   }
    58 
    74 
    59 ScriptDirectory = os.path.split(os.path.realpath(__file__))[0]
    75 ScriptDirectory = os.path.split(os.path.realpath(__file__))[0]
    60 
    76 
    61 #-------------------------------------------------------------------------------
    77 #-------------------------------------------------------------------------------
    62 #                         Undo Buffer for PLCOpenEditor
    78 #                         Undo Buffer for PLCOpenEditor
   264         return properties
   280         return properties
   265     
   281     
   266     # Return project informations
   282     # Return project informations
   267     def GetProjectInfos(self):
   283     def GetProjectInfos(self):
   268         if self.Project:
   284         if self.Project:
   269             infos = {"name": self.Project.getname(), "type": ITEM_PROJECT, "tagname": ""}
   285             infos = {"name": self.Project.getname(), "type": ITEM_PROJECT}
   270             datatypes = {"name": "Data Types", "type": ITEM_DATATYPES, "tagname": "", "values":[]}
   286             datatypes = {"name": "Data Types", "type": ITEM_DATATYPES, "values":[]}
   271             for datatype in self.Project.getdataTypes():
   287             for datatype in self.Project.getdataTypes():
   272                 datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, 
   288                 datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, 
   273                     "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []})
   289                     "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []})
   274             pou_types = {"function": {"name": "Functions", "type": ITEM_FUNCTION, "tagname": "", "values":[]},
   290             pou_types = {"function": {"name": "Functions", "type": ITEM_FUNCTION, "values":[]},
   275                          "functionBlock": {"name": "Function Blocks", "type": ITEM_FUNCTIONBLOCK, "tagname": "", "values":[]},
   291                          "functionBlock": {"name": "Function Blocks", "type": ITEM_FUNCTIONBLOCK, "values":[]},
   276                          "program": {"name": "Programs", "type": ITEM_PROGRAM, "tagname": "", "values":[]}}
   292                          "program": {"name": "Programs", "type": ITEM_PROGRAM, "values":[]}}
   277             for pou in self.Project.getpous():
   293             for pou in self.Project.getpous():
   278                 pou_type = pou.getpouType()
   294                 pou_type = pou.getpouType()
   279                 pou_infos = {"name": pou.getname(), "type": ITEM_POU,
   295                 pou_infos = {"name": pou.getname(), "type": ITEM_POU,
   280                              "tagname": self.ComputePouName(pou.getname())}
   296                              "tagname": self.ComputePouName(pou.getname())}
   281                 pou_values = []
   297                 pou_values = []
   283                     transitions = []
   299                     transitions = []
   284                     for transition in pou.gettransitionList():
   300                     for transition in pou.gettransitionList():
   285                         transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION, 
   301                         transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION, 
   286                             "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()), 
   302                             "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()), 
   287                             "values": []})
   303                             "values": []})
   288                     pou_values.append({"name": "Transitions", "type": ITEM_TRANSITIONS, 
   304                     pou_values.append({"name": "Transitions", "type": ITEM_TRANSITIONS, "values": transitions})
   289                                        "tagname": "", "values": transitions})
       
   290                     actions = []
   305                     actions = []
   291                     for action in pou.getactionList():
   306                     for action in pou.getactionList():
   292                         actions.append({"name": action.getname(), "type": ITEM_ACTION, 
   307                         actions.append({"name": action.getname(), "type": ITEM_ACTION, 
   293                             "tagname": self.ComputePouActionName(pou.getname(), action.getname()), 
   308                             "tagname": self.ComputePouActionName(pou.getname(), action.getname()), 
   294                             "values": []})
   309                             "values": []})
   295                     pou_values.append({"name": "Actions", "type": ITEM_ACTIONS, 
   310                     pou_values.append({"name": "Actions", "type": ITEM_ACTIONS, "values": actions})
   296                                        "tagname": "", "values": actions})
       
   297                 if pou_type in pou_types:
   311                 if pou_type in pou_types:
   298                     pou_infos["values"] = pou_values
   312                     pou_infos["values"] = pou_values
   299                     pou_types[pou_type]["values"].append(pou_infos)
   313                     pou_types[pou_type]["values"].append(pou_infos)
   300             configurations = {"name": "Configurations", "type": ITEM_CONFIGURATIONS, 
   314             configurations = {"name": "Configurations", "type": ITEM_CONFIGURATIONS, "values": []}
   301                               "tagname": "", "values": []}
       
   302             for config in self.Project.getconfigurations():
   315             for config in self.Project.getconfigurations():
   303                 config_name = config.getname()
   316                 config_name = config.getname()
   304                 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, 
   317                 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, 
   305                     "tagname": self.ComputeConfigurationName(config.getname()), 
   318                     "tagname": self.ComputeConfigurationName(config.getname()), 
   306                     "values": []}
   319                     "values": []}
   307                 resources = {"name": "Resources", "type": ITEM_RESOURCES, "tagname": "", "values": []}
   320                 resources = {"name": "Resources", "type": ITEM_RESOURCES, "values": []}
   308                 for resource in config.getresource():
   321                 for resource in config.getresource():
   309                     resource_name = resource.getname()
   322                     resource_name = resource.getname()
   310                     resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, 
   323                     resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, 
   311                         "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()), 
   324                         "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()), 
   312                         "values": []}
   325                         "values": []}
   313                     resources["values"].append(resource_infos)
   326                     resources["values"].append(resource_infos)
   314                 config_infos["values"] = [resources]
   327                 config_infos["values"] = [resources]
   315                 configurations["values"].append(config_infos)
   328                 configurations["values"].append(config_infos)
   316             infos["values"] = [{"name": "Properties", "type": ITEM_PROPERTIES, "tagname": "", "values": []},
   329             infos["values"] = [{"name": "Properties", "type": ITEM_PROPERTIES, "values": []},
   317                                datatypes, pou_types["function"], pou_types["functionBlock"], 
   330                                datatypes, pou_types["function"], pou_types["functionBlock"], 
   318                                pou_types["program"], configurations]
   331                                pou_types["program"], configurations]
   319             return infos
   332             return infos
   320         return None
   333         return None
   321 
   334 
   338                             resource_infos["values"].append(instance_infos)
   351                             resource_infos["values"].append(instance_infos)
   339                     for varlist in resource.getglobalVars():
   352                     for varlist in resource.getglobalVars():
   340                         for variable in varlist.getvariable():
   353                         for variable in varlist.getvariable():
   341                             vartype_content = variable.gettype().getcontent()
   354                             vartype_content = variable.gettype().getcontent()
   342                             if vartype_content["name"] == "derived":
   355                             if vartype_content["name"] == "derived":
   343                                 var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname())
   356                                 var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True)
   344                                 if var_infos is not None:
   357                                 if var_infos is not None:
   345                                     resource_infos["values"].append(var_infos)
   358                                     resource_infos["values"].append(var_infos)
   346                             elif vartype_content["name"] in ["string", "wstring"]:
   359                             elif vartype_content["name"] in ["string", "wstring"]:
   347                                 resource_infos["values"].append({"name" : "%s(%s)"%(variable.getname(), vartype_content["name"].upper()), 
   360                                 resource_infos["values"].append({"name" : variable.getname(), 
   348                                                                  "type" : ITEM_VARIABLE, "values" : []})
   361                                                                  "elmt_type" : vartype_content["name"].upper(),
       
   362                                                                  "type" : ITEM_VAR_GLOBAL, "values" : []})
   349                             else:
   363                             else:
   350                                 resource_infos["values"].append({"name" : "%s(%s)"%(variable.getname(), vartype_content["name"]), 
   364                                 resource_infos["values"].append({"name" : variable.getname(), 
   351                                                                  "type" : ITEM_VARIABLE, "values" : []})
   365                                                                  "elmt_type" : vartype_content["name"], 
       
   366                                                                  "type" : ITEM_VAR_GLOBAL, "values" : []})
   352                     config_infos["values"].append(resource_infos)
   367                     config_infos["values"].append(resource_infos)
   353                 for varlist in config.getglobalVars():
   368                 for varlist in config.getglobalVars():
   354                     for variable in varlist.getvariable():
   369                     for variable in varlist.getvariable():
   355                         vartype_content = variable.gettype().getcontent()
   370                         vartype_content = variable.gettype().getcontent()
   356                         if vartype_content["name"] == "derived":
   371                         if vartype_content["name"] == "derived":
   357                             var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname())
   372                             var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True)
   358                             if var_infos is not None:
   373                             if var_infos is not None:
   359                                 config_infos["values"].append(var_infos)
   374                                 config_infos["values"].append(var_infos)
   360                         elif vartype_content["name"] in ["string", "wstring"]:
   375                         elif vartype_content["name"] in ["string", "wstring"]:
   361                             config_infos["values"].append({"name" : "%s(%s)"%(variable.getname(), vartype_content["name"].upper()), 
   376                             config_infos["values"].append({"name" : variable.getname(), 
   362                                                            "type" : ITEM_VARIABLE, "values" : []})
   377                                                            "elmt_type" : vartype_content["name"].upper(), 
       
   378                                                            "type" : ITEM_VAR_GLOBAL, "values" : []})
   363                         else:
   379                         else:
   364                             config_infos["values"].append({"name" : "%s(%s)"%(variable.getname(), vartype_content["name"]), 
   380                             config_infos["values"].append({"name" : variable.getname(),
   365                                                            "type" : ITEM_VARIABLE, "values" : []})
   381                                                            "elmt_type" : vartype_content["name"], 
       
   382                                                            "type" : ITEM_VAR_GLOBAL, "values" : []})
   366                 infos["values"].append(config_infos)
   383                 infos["values"].append(config_infos)
   367             return infos
   384             return infos
   368         return None
   385         return None
   369     
   386     
   370     # Return pou topology informations
   387     # Return pou topology informations
   371     def GetPouTopology(self, name, type):
   388     def GetPouTopology(self, name, type, global_var=False):
   372         if self.Project:
   389         if self.Project:
   373             pou = self.Project.getpou(type)
   390             pou = self.Project.getpou(type)
   374             if pou is not None:
   391             if pou is not None:
   375                 pou_infos = {"name" : "%s(%s)"%(name, type), "type" : ITEM_POU, "values" : []}
   392                 pou_type = pou.getpouType()
       
   393                 if pou_type == "function":
       
   394                     return None
       
   395                 elif pou_type == "program":
       
   396                     pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, "values" : []}
       
   397                 else:
       
   398                     pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_FUNCTIONBLOCK, "values" : []}
   376                 if pou.interface:
   399                 if pou.interface:
   377                     # Extract variables from every varLists
   400                     # Extract variables from every varLists
   378                     for type, varlist in pou.getvars():
   401                     for type, varlist in pou.getvars():
       
   402                         infos = VAR_CLASS_INFOS.get(type, None)
       
   403                         if infos is not None:
       
   404                             current_var_class = infos[1]
       
   405                         else:
       
   406                             current_var_class = ITEM_VAR_LOCAL
   379                         for variable in varlist.getvariable():
   407                         for variable in varlist.getvariable():
   380                             vartype_content = variable.gettype().getcontent()
   408                             vartype_content = variable.gettype().getcontent()
   381                             if vartype_content["name"] == "derived":
   409                             if vartype_content["name"] == "derived":
   382                                 var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname())
   410                                 var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname())
   383                                 if var_infos is not None:
   411                                 if var_infos is not None:
   384                                     pou_infos["values"].append(var_infos)
   412                                     pou_infos["values"].append(var_infos)
   385                             elif vartype_content["name"] in ["string", "wstring"]:
   413                             elif vartype_content["name"] in ["string", "wstring"]:
   386                                 pou_infos["values"].append({"name" : "%s(%s)"%(variable.getname(), vartype_content["name"].upper()), 
   414                                 pou_infos["values"].append({"name" : variable.getname(), 
   387                                                                "type" : ITEM_VARIABLE, "values" : []})
   415                                                             "elmt_type" : vartype_content["name"].upper(), 
       
   416                                                             "type" : current_var_class, "values" : []})
   388                             else:
   417                             else:
   389                                 pou_infos["values"].append({"name" : "%s(%s)"%(variable.getname(), vartype_content["name"]), 
   418                                 pou_infos["values"].append({"name" : variable.getname(), 
   390                                                                "type" : ITEM_VARIABLE, "values" : []})
   419                                                             "elmt_type" : vartype_content["name"], 
       
   420                                                             "type" : current_var_class, "values" : []})
   391                 return pou_infos
   421                 return pou_infos
   392             block_infos = self.GetBlockType(type)
   422             block_infos = self.GetBlockType(type)
   393             if block_infos is not None and block_infos["type"] != "function":
   423             if block_infos is not None:
   394                 pou_infos = {"name" : "%s(%s)"%(name, type), "type" : ITEM_POU, "values" : []}
   424                 if block_infos["type"] == "function":
       
   425                     return None
       
   426                 elif block_infos["type"] == "program":
       
   427                     pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, "values" : []}
       
   428                 else:
       
   429                     pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_FUNCTIONBLOCK, "values" : []}
   395                 for varname, vartype, varmodifier in block_infos["inputs"]:
   430                 for varname, vartype, varmodifier in block_infos["inputs"]:
   396                     pou_infos["values"].append({"name" : "%s(%s)"%(varname, vartype), "type" : ITEM_VARIABLE, "values" : []})
   431                     pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_INPUT, "values" : []})
   397                 for varname, vartype, varmodifier in block_infos["outputs"]:
   432                 for varname, vartype, varmodifier in block_infos["outputs"]:
   398                     pou_infos["values"].append({"name" : "%s(%s)"%(varname, vartype), "type" : ITEM_VARIABLE, "values" : []})
   433                     pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_INPUT, "values" : []})
   399                 return pou_infos
   434                 return pou_infos
   400             
   435             
   401             if type in TypeHierarchy:
   436             if type in self.GetDataTypes():
   402                 return {"name" : "%s(%s)"%(name, type), "type" : ITEM_VARIABLE, "values" : []}
   437                 if global_var:
   403                 
   438                     return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_GLOBAL, "values" : []}
       
   439                 else:
       
   440                     return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_LOCAL, "values" : []}
   404         return None
   441         return None
   405 
   442 
   406     # Return if data type given by name is used by another data type or pou
   443     # Return if data type given by name is used by another data type or pou
   407     def DataTypeIsUsed(self, name):
   444     def DataTypeIsUsed(self, name):
   408         return self.Project.ElementIsUsed(name) or self.Project.DataTypeIsDerived(name)
   445         return self.Project.ElementIsUsed(name) or self.Project.DataTypeIsDerived(name)
   436             lines = chunk.split("\n")
   473             lines = chunk.split("\n")
   437             if len(lines) > 1:
   474             if len(lines) > 1:
   438                 next_row = row + len(lines) - 1
   475                 next_row = row + len(lines) - 1
   439                 next_col = len(lines[-1]) + 1
   476                 next_col = len(lines[-1]) + 1
   440             else:
   477             else:
       
   478                 next_row = row
   441                 next_col = col + len(chunk)
   479                 next_col = col + len(chunk)
   442             if (next_row > from_location[0] or next_row == from_location[0] and next_col >= from_location[1]) and len(chunk_infos) > 0:
   480             if (next_row > from_location[0] or next_row == from_location[0] and next_col >= from_location[1]) and len(chunk_infos) > 0:
   443                 infos.append((chunk_infos, (row, col)))
   481                 infos.append((chunk_infos, (row, col)))
   444             if next_row == to_location[0] and next_col > to_location[1] or next_row > to_location[0]:
   482             if next_row == to_location[0] and next_col > to_location[1] or next_row > to_location[0]:
   445                 return infos
   483                 return infos
   651                                     # and not located variables are 
   689                                     # and not located variables are 
   652                                     # in the same declaration block
   690                                     # in the same declaration block
   653                                     var["Class"] == "Global")
   691                                     var["Class"] == "Global")
   654             if current_type != next_type:
   692             if current_type != next_type:
   655                 current_type = next_type
   693                 current_type = next_type
   656                 if var["Class"] == "Local":
   694                 infos = VAR_CLASS_INFOS.get(var["Class"], None)
   657                     current_varlist = plcopen.interface_localVars()
   695                 if infos is not None:
   658                 elif var["Class"] == "Global":
   696                     current_varlist = infos[0]()
   659                     current_varlist = plcopen.interface_globalVars()
       
   660                 elif var["Class"] == "External":
       
   661                     current_varlist = plcopen.interface_externalVars()
       
   662                 elif var["Class"] == "Temp":
       
   663                     current_varlist = plcopen.interface_tempVars()
       
   664                 elif var["Class"] == "Input":
       
   665                     current_varlist = plcopen.interface_inputVars()
       
   666                 elif var["Class"] == "Output":
       
   667                     current_varlist = plcopen.interface_outputVars()
       
   668                 elif var["Class"] == "InOut":
       
   669                     current_varlist = plcopen.interface_inOutVars()
       
   670                 else:
   697                 else:
   671                     current_varlist = plcopen.varList()
   698                     current_varlist = plcopen.varList()
   672                 varlist_list.append((var["Class"], current_varlist))
   699                 varlist_list.append((var["Class"], current_varlist))
   673                 if var["Retain"] == "Yes":
   700                 if var["Retain"] == "Yes":
   674                     current_varlist.setretain(True)
   701                     current_varlist.setretain(True)
  1689                 return 
  1716                 return 
  1690             old_name = block.getinstanceName()
  1717             old_name = block.getinstanceName()
  1691             old_type = block.gettypeName()
  1718             old_type = block.gettypeName()
  1692             new_name = infos.get("name", old_name)
  1719             new_name = infos.get("name", old_name)
  1693             new_type = infos.get("type", old_type)
  1720             new_type = infos.get("type", old_type)
  1694             old_typeinfos = self.GetBlockType(old_type)
  1721             if new_type != old_type:
  1695             new_typeinfos = self.GetBlockType(new_type)
  1722                 old_typeinfos = self.GetBlockType(old_type)
  1696             if new_type != old_type and new_typeinfos["type"] != old_typeinfos["type"]:
  1723                 new_typeinfos = self.GetBlockType(new_type)
  1697                 if new_typeinfos["type"] == "function":
  1724                 if old_typeinfos is None or new_typeinfos is None:
  1698                     self.RemoveEditedElementPouVar(tagname, old_type, old_name)
  1725                     self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name)
  1699                 else:
  1726                 elif new_typeinfos["type"] != old_typeinfos["type"]:
  1700                     self.AddEditedElementPouVar(tagname, new_type, new_name)
  1727                     if new_typeinfos["type"] == "function":
  1701             elif old_name != new_name and new_typeinfos["type"] != "function":
  1728                         self.RemoveEditedElementPouVar(tagname, old_type, old_name)
       
  1729                     else:
       
  1730                         self.AddEditedElementPouVar(tagname, new_type, new_name)
       
  1731                 elif new_typeinfos["type"] != "function" and old_name != new_name:
       
  1732                     self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name)
       
  1733             elif new_name != old_name:
  1702                 self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name)
  1734                 self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name)
  1703             for param, value in infos.items():
  1735             for param, value in infos.items():
  1704                 if param == "name":
  1736                 if param == "name":
  1705                     block.setinstanceName(value)
  1737                     block.setinstanceName(value)
  1706                 elif param == "type":
  1738                 elif param == "type":