plcopen/structures.py
changeset 230 45d70748e45a
parent 210 17ce08b81775
child 242 5b3e1c4569e6
equal deleted inserted replaced
229:a5087e346baa 230:45d70748e45a
    31                      "B" : ["SINT", "USINT", "BYTE", "STRING"],
    31                      "B" : ["SINT", "USINT", "BYTE", "STRING"],
    32                      "W" : ["INT", "UINT", "WORD", "WSTRING"],
    32                      "W" : ["INT", "UINT", "WORD", "WSTRING"],
    33                      "D" : ["DINT", "UDINT", "REAL", "DWORD"],
    33                      "D" : ["DINT", "UDINT", "REAL", "DWORD"],
    34                      "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} 
    34                      "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} 
    35 
    35 
       
    36 # Helper for emulate join on element list
       
    37 def JoinList(separator, list):
       
    38     return reduce(lambda x, y: x + separator + y, list)
       
    39 
    36 def generate_block(generator, block, body, link, order=False):
    40 def generate_block(generator, block, body, link, order=False):
    37     body_type = body.getcontent()["name"]
    41     body_type = body.getcontent()["name"]
    38     name = block.getinstanceName()
    42     name = block.getinstanceName()
    39     type = block.gettypeName()
    43     type = block.gettypeName()
    40     executionOrderId = block.getexecutionOrderId()
    44     executionOrderId = block.getexecutionOrderId()
    41     block_infos = GetBlockType(type)
    45     block_infos = generator.GetBlockType(type)
    42     if block_infos["type"] == "function":
    46     if block_infos["type"] == "function":
    43         output_variable = block.outputVariables.getvariable()[0]
    47         output_variable = block.outputVariables.getvariable()[0]
    44         output_name = "%s%d_OUT"%(type, block.getlocalId())
    48         output_name = "%s%d_OUT"%(type, block.getlocalId())
       
    49         output_info = (generator.TagName, "block", block.getlocalId(), "output", 0)
    45         if not generator.ComputedBlocks.get(block, False) and not order:
    50         if not generator.ComputedBlocks.get(block, False) and not order:
    46             generator.ComputedBlocks[block] = True
    51             generator.ComputedBlocks[block] = True
    47             if generator.Interface[-1][0] != "VAR" or generator.Interface[-1][1] or generator.Interface[-1][2] or generator.Interface[-1][3]:
    52             if generator.Interface[-1][0] != "VAR" or generator.Interface[-1][1] or generator.Interface[-1][2] or generator.Interface[-1][3]:
    48                 generator.Interface.append(("VAR", False, False, False, []))
    53                 generator.Interface.append(("VAR", False, False, False, []))
    49             if output_variable.connectionPointOut in generator.ConnectionTypes:
    54             if output_variable.connectionPointOut in generator.ConnectionTypes:
    50                 generator.Interface[-1][4].append((generator.ConnectionTypes[output_variable.connectionPointOut], output_name, None, None))
    55                 generator.Interface[-1][4].append((generator.ConnectionTypes[output_variable.connectionPointOut], output_name, None, None))
    51             else:
    56             else:
    52                 generator.Interface[-1][4].append(("ANY", output_name, None, None))
    57                 generator.Interface[-1][4].append(("ANY", output_name, None, None))
    53             vars = []
    58             vars = []
    54             for variable in block.inputVariables.getvariable():
    59             for i, variable in enumerate(block.inputVariables.getvariable()):
       
    60                 input_info = (generator.TagName, "block", block.getlocalId(), "input", i)
    55                 connections = variable.connectionPointIn.getconnections()
    61                 connections = variable.connectionPointIn.getconnections()
    56                 if connections and len(connections) == 1:
    62                 if connections and len(connections) == 1:
    57                     if body_type == "FBD" or body_type == "SFC":
    63                     if body_type == "FBD" or body_type == "SFC":
    58                         value = generator.ComputeFBDExpression(body, connections[0], executionOrderId > 0)
    64                         value = generator.ComputeFBDExpression(body, connections[0], executionOrderId > 0)
    59                     elif body_type == "LD":
    65                     elif body_type == "LD":
    61                         if len(paths) > 0:
    67                         if len(paths) > 0:
    62                             paths = tuple(paths)
    68                             paths = tuple(paths)
    63                         else:
    69                         else:
    64                             paths = paths[0] 
    70                             paths = paths[0] 
    65                         value = generator.ComputeLDExpression(paths, True)
    71                         value = generator.ComputeLDExpression(paths, True)
    66                     vars.append(generator.ExtractModifier(variable, value))
    72                     vars.append(generator.ExtractModifier(variable, value, input_info))
    67             generator.Program += "  %s := %s(%s);\n"%(output_name, type, ", ".join(vars))
    73             generator.Program += [(generator.CurrentIndent, ()),
    68         return generator.ExtractModifier(output_variable, output_name)
    74                                   (output_name, output_info),
       
    75                                   (" := ", ()),
       
    76                                   (type, (generator.TagName, "block", block.getlocalId(), "type")),
       
    77                                   ("(", ())]
       
    78             generator.Program += JoinList([(", ", ())], vars)
       
    79             generator.Program += [(");\n", ())]
       
    80         return generator.ExtractModifier(output_variable, [(output_name, output_info)], output_info)
    69     elif block_infos["type"] == "functionBlock":
    81     elif block_infos["type"] == "functionBlock":
    70         if not generator.ComputedBlocks.get(block, False) and not order:
    82         if not generator.ComputedBlocks.get(block, False) and not order:
    71             generator.ComputedBlocks[block] = True
    83             generator.ComputedBlocks[block] = True
    72             vars = []
    84             vars = []
    73             for variable in block.inputVariables.getvariable():
    85             for i, variable in enumerate(block.inputVariables.getvariable()):
       
    86                 input_info = (generator.TagName, "block", block.getlocalId(), "input", i)
    74                 connections = variable.connectionPointIn.getconnections()
    87                 connections = variable.connectionPointIn.getconnections()
    75                 if connections and len(connections) == 1:
    88                 if connections and len(connections) == 1:
    76                     parameter = variable.getformalParameter()
    89                     parameter = variable.getformalParameter()
    77                     if body_type == "FBD" or body_type == "SFC":
    90                     if body_type == "FBD" or body_type == "SFC":
    78                         value = generator.ComputeFBDExpression(body, connections[0], executionOrderId > 0)
    91                         value = generator.ComputeFBDExpression(body, connections[0], executionOrderId > 0)
    81                         if len(paths) > 0:
    94                         if len(paths) > 0:
    82                             paths = tuple(paths)
    95                             paths = tuple(paths)
    83                         else:
    96                         else:
    84                             paths = paths[0] 
    97                             paths = paths[0] 
    85                         value = generator.ComputeLDExpression(paths, True)
    98                         value = generator.ComputeLDExpression(paths, True)
    86                     vars.append("%s := %s"%(parameter, generator.ExtractModifier(variable, value)))
    99                     vars.append([(parameter, input_info),
    87             generator.Program += "  %s(%s);\n"%(name, ", ".join(vars))
   100                                  (" := ", ())] + generator.ExtractModifier(variable, value, input_info))
       
   101             generator.Program += [(generator.CurrentIndent, ()), 
       
   102                                   (name, (generator.TagName, "block", block.getlocalId(), "name")),
       
   103                                   ("(", ())]
       
   104             generator.Program += JoinList([(", ", ())], vars)
       
   105             generator.Program += [(");\n", ())]
    88         if link:
   106         if link:
    89             connectionPoint = link.getposition()[-1]
   107             connectionPoint = link.getposition()[-1]
    90         else:
   108         else:
    91             connectionPoint = None
   109             connectionPoint = None
    92         for variable in block.outputVariables.getvariable():
   110         for i, variable in enumerate(block.outputVariables.getvariable()):
    93             blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
   111             blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
       
   112             output_info = (generator.TagName, "block", block.getlocalId(), "output", i)
    94             if not connectionPoint or block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety():
   113             if not connectionPoint or block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety():
    95                 return generator.ExtractModifier(variable, "%s.%s"%(name, variable.getformalParameter()))
   114                 return generator.ExtractModifier(variable, [("%s.%s"%(name, variable.getformalParameter()), output_info)], output_info)
    96         raise ValueError, "No output variable found"
   115         raise ValueError, "No output variable found"
    97 
   116 
    98 def initialise_block(type, name, block = None):
   117 def initialise_block(type, name, block = None):
    99     return [(type, name, None, None)]
   118     return [(type, name, None, None)]
   100 
   119 
   210                     "outputs" : [("ALARM","BOOL","none"),("TOTAL_ERR","BOOL","none")],
   229                     "outputs" : [("ALARM","BOOL","none"),("TOTAL_ERR","BOOL","none")],
   211                     "comment" : "Ratio monitor\nThe ratio_monitor function block checks that one process value PV1 is always a given ratio (defined by input RATIO) of a second process value PV2.",
   230                     "comment" : "Ratio monitor\nThe ratio_monitor function block checks that one process value PV1 is always a given ratio (defined by input RATIO) of a second process value PV2.",
   212                     "generate" : generate_block, "initialise" : initialise_block}
   231                     "generate" : generate_block, "initialise" : initialise_block}
   213                 ]},
   232                 ]},
   214              ]
   233              ]
   215              
   234 
   216 PluginTypes = []
       
   217 
       
   218 """
       
   219 Function that returns the block definition associated to the block type given
       
   220 """
       
   221 
       
   222 def GetBlockType(type, inputs = None):
       
   223     for category in BlockTypes + PluginTypes:
       
   224         for blocktype in category["list"]:
       
   225             if inputs:
       
   226                 block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
       
   227                 same_inputs = inputs == block_inputs
       
   228             else:
       
   229                 same_inputs = True
       
   230             if blocktype["name"] == type and same_inputs:
       
   231                 return blocktype
       
   232     return None
       
   233 
       
   234 """
       
   235 Function that add a new plugin to the plugin list
       
   236 """
       
   237 
       
   238 def AddPluginBlockList(blocklist):
       
   239     PluginTypes.extend(blocklist)
       
   240     
       
   241 def ClearPluginTypes():
       
   242     for i in xrange(len(PluginTypes)):
       
   243         PluginTypes.pop(0)
       
   244 
   235 
   245 #-------------------------------------------------------------------------------
   236 #-------------------------------------------------------------------------------
   246 #                           Data Types definitions
   237 #                           Data Types definitions
   247 #-------------------------------------------------------------------------------
   238 #-------------------------------------------------------------------------------
   248 
   239 
   263     ("ANY_NUM", "ANY_MAGNITUDE"),
   254     ("ANY_NUM", "ANY_MAGNITUDE"),
   264     ("ANY_REAL", "ANY_NUM"),
   255     ("ANY_REAL", "ANY_NUM"),
   265     ("ANY_INT", "ANY_NUM"),
   256     ("ANY_INT", "ANY_NUM"),
   266     ("ANY_SINT", "ANY_INT"),
   257     ("ANY_SINT", "ANY_INT"),
   267     ("ANY_UINT", "ANY_INT"),
   258     ("ANY_UINT", "ANY_INT"),
   268 	("BOOL", "ANY_BIT"),
   259     ("BOOL", "ANY_BIT"),
   269     ("SINT", "ANY_SINT"),
   260     ("SINT", "ANY_SINT"),
   270     ("INT", "ANY_SINT"),
   261     ("INT", "ANY_SINT"),
   271     ("DINT", "ANY_SINT"),
   262     ("DINT", "ANY_SINT"),
   272     ("LINT", "ANY_SINT"),
   263     ("LINT", "ANY_SINT"),
   273     ("USINT", "ANY_UINT"),
   264     ("USINT", "ANY_UINT"),
   288     #("WSTRING", "ANY_STRING") # TODO
   279     #("WSTRING", "ANY_STRING") # TODO
   289 ]
   280 ]
   290 
   281 
   291 TypeHierarchy = dict(TypeHierarchy_list)
   282 TypeHierarchy = dict(TypeHierarchy_list)
   292 
   283 
   293 def ResetTypeHierarchy():
   284 """
   294     TypeHierarchy = dict(TypeHierarchy_list)
   285 returns true if the given data type is the same that "reference" meta-type or one of its types.
   295     
   286 """
   296 def AddDataTypeHierarchy(name, reference):
   287 def IsOfType(type, reference):
   297     TypeHierarchy[name] = reference
   288     if reference is None:
       
   289         return True
       
   290     elif type == reference:
       
   291         return True
       
   292     else:
       
   293         parent_type = TypeHierarchy[type]
       
   294         if parent_type is not None:
       
   295             return IsOfType(parent_type, reference)
       
   296     return False
       
   297 
       
   298 """
       
   299 returns list of all types that correspont to the ANY* meta type
       
   300 """
       
   301 def GetSubTypes(type):
       
   302     return [typename for typename, parenttype in TypeHierarchy.items() if not typename.startswith("ANY") and IsOfType(typename, type)]
       
   303 
   298 
   304 
   299 DataTypeRange_list = [
   305 DataTypeRange_list = [
   300     ("SINT", (-2**7, 2**7 - 1)),
   306     ("SINT", (-2**7, 2**7 - 1)),
   301     ("INT", (-2**15, 2**15 - 1)),
   307     ("INT", (-2**15, 2**15 - 1)),
   302     ("DINT", (-2**31, 2**31 - 1)),
   308     ("DINT", (-2**31, 2**31 - 1)),
   307     ("ULINT", (0, 2**31 - 1))
   313     ("ULINT", (0, 2**31 - 1))
   308 ]
   314 ]
   309 
   315 
   310 DataTypeRange = dict(DataTypeRange_list)
   316 DataTypeRange = dict(DataTypeRange_list)
   311 
   317 
   312 def ResetDataTypeRange():
   318 
   313     DataTypeRange = dict(DataTypeRange_list)
       
   314     
       
   315 def AddDataTypeRange(name, range):
       
   316     DataTypeRange[name] = range
       
   317 
       
   318 """
       
   319 returns true if the given data type is the same that "reference" meta-type or one of its types.
       
   320 """
       
   321 
       
   322 def IsOfType(test, reference):
       
   323     if reference is None:
       
   324         return True
       
   325     while test is not None:
       
   326         if test == reference:
       
   327             return True
       
   328         test = TypeHierarchy[test]
       
   329     return False
       
   330 
       
   331 def IsEndType(reference):
       
   332     if reference is not None:
       
   333         return not reference.startswith("ANY")
       
   334     else:
       
   335         return True
       
   336 
       
   337 def GetBaseType(type):
       
   338     parent_type = TypeHierarchy[type]
       
   339     if parent_type.startswith("ANY"):
       
   340         return type
       
   341     else:
       
   342         return GetBaseType(parent_type)
       
   343 
       
   344 def GetDataTypeRange(reference):
       
   345     while reference is not None:
       
   346         if reference in DataTypeRange:
       
   347             return DataTypeRange[reference]
       
   348         else:
       
   349             reference = TypeHierarchy[reference]
       
   350     return None
       
   351 
       
   352 """
       
   353 returns list of all types that correspont to the ANY* meta type
       
   354 """
       
   355 def GetSubTypes(reference):
       
   356     return [typename for typename, parenttype in TypeHierarchy.items() if not typename.startswith("ANY") and IsOfType(typename, reference)]
       
   357 
       
   358 
       
   359 EnumeratedDataValues = []
       
   360 
       
   361 def ResetEnumeratedDataValues():
       
   362     EnumeratedDataValues = []
       
   363     
       
   364 def AddEnumeratedDataValues(values):
       
   365     EnumeratedDataValues.extend(values)
       
   366 
   319 
   367 #-------------------------------------------------------------------------------
   320 #-------------------------------------------------------------------------------
   368 #                             Test identifier
   321 #                             Test identifier
   369 #-------------------------------------------------------------------------------
   322 #-------------------------------------------------------------------------------
   370 
   323