PLCControler.py
changeset 1338 c1e6c712cc35
parent 1337 204ef2daa33c
child 1339 6adf05c4508d
equal deleted inserted replaced
1337:204ef2daa33c 1338:c1e6c712cc35
    27 from lxml import etree
    27 from lxml import etree
    28 from copy import deepcopy
    28 from copy import deepcopy
    29 import os,sys,re
    29 import os,sys,re
    30 import datetime
    30 import datetime
    31 from time import localtime
    31 from time import localtime
       
    32 from collections import OrderedDict, namedtuple
    32 
    33 
    33 from plcopen import *
    34 from plcopen import *
    34 from graphics.GraphicCommons import *
    35 from graphics.GraphicCommons import *
    35 from PLCGenerator import *
    36 from PLCGenerator import *
    36 
    37 
   306     def execute(self, context, self_node, input_node, output_parent):
   307     def execute(self, context, self_node, input_node, output_parent):
   307         tagname_infos = etree.Element('infos')
   308         tagname_infos = etree.Element('infos')
   308         self.process_children(context, tagname_infos)
   309         self.process_children(context, tagname_infos)
   309         tagname = etree.Element('tagname')
   310         tagname = etree.Element('tagname')
   310         tagname.text = self.GetTagName(tagname_infos)
   311         tagname.text = self.GetTagName(tagname_infos)
   311         print etree.tostring(tagname)
       
   312         try:
   312         try:
   313             output_parent.append(tagname)
   313             output_parent.append(tagname)
   314         except:
   314         except:
   315             pass
   315             pass
   316 
   316 
   342         return self.Controller.ComputePouTransitionName(
   342         return self.Controller.ComputePouTransitionName(
   343             infos.get("pou_name"), infos.get("name"))
   343             infos.get("pou_name"), infos.get("name"))
   344 
   344 
   345 instance_tagname_xslt = etree.parse(
   345 instance_tagname_xslt = etree.parse(
   346     os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"))
   346     os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"))
       
   347 
       
   348 #-------------------------------------------------------------------------------
       
   349 #           Helpers object for generating pou block instances list
       
   350 #-------------------------------------------------------------------------------
       
   351 
       
   352 _BoolValue = lambda x: x in ["true", "0"]
       
   353 
       
   354 _Point = namedtuple("Point", ["x", "y"])
       
   355 
       
   356 _BlockInstanceInfos = namedtuple("BlockInstanceInfos", 
       
   357     ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"])
       
   358 
       
   359 _BlockSpecificValues = (
       
   360     namedtuple("BlockSpecificValues", 
       
   361                ["name", "execution_order"]),
       
   362     [str, int])
       
   363 _VariableSpecificValues = (
       
   364     namedtuple("VariableSpecificValues", 
       
   365                ["name", "value_type", "execution_order"]),
       
   366     [str, str, int])
       
   367 _ConnectionSpecificValues = (
       
   368     namedtuple("ConnectionSpecificValues", ["name"]),
       
   369     [str])
       
   370 
       
   371 _PowerRailSpecificValues = (
       
   372     namedtuple("PowerRailSpecificValues", ["connectors"]),
       
   373     [int])
       
   374 
       
   375 _LDElementSpecificValues = (
       
   376     namedtuple("LDElementSpecificValues", 
       
   377                ["name", "negated", "edge", "storage", "execution_order"]),
       
   378     [str, _BoolValue, str, str, int])
       
   379 
       
   380 _DivergenceSpecificValues = (
       
   381     namedtuple("DivergenceSpecificValues", ["connectors"]),
       
   382     [int])
       
   383 
       
   384 _SpecificValuesTuples = {
       
   385     "comment": (
       
   386         namedtuple("CommentSpecificValues", ["content"]),
       
   387         [str]),
       
   388     "input": _VariableSpecificValues,
       
   389     "output": _VariableSpecificValues,
       
   390     "inout": _VariableSpecificValues,
       
   391     "connector": _ConnectionSpecificValues,
       
   392     "continuation": _ConnectionSpecificValues,
       
   393     "leftPowerRail": _PowerRailSpecificValues,
       
   394     "rightPowerRail": _PowerRailSpecificValues,
       
   395     "contact": _LDElementSpecificValues,
       
   396     "coil": _LDElementSpecificValues,
       
   397     "step": (
       
   398         namedtuple("StepSpecificValues", ["name", "initial", "action"]),
       
   399         [str, _BoolValue, lambda x: x]),
       
   400     "transition": (
       
   401         namedtuple("TransitionSpecificValues", 
       
   402                    ["priority", "condition_type", "condition", "connection"]),
       
   403         [int, str, str, lambda x: x]),
       
   404     "selectionDivergence": _DivergenceSpecificValues,
       
   405     "selectionConvergence": _DivergenceSpecificValues,
       
   406     "simultaneousDivergence": _DivergenceSpecificValues,
       
   407     "simultaneousConvergence": _DivergenceSpecificValues,
       
   408     "jump": (
       
   409         namedtuple("JumpSpecificValues", ["target"]),
       
   410         [str]),
       
   411     "actionBlock": (
       
   412         namedtuple("ActionBlockSpecificValues", ["actions"]),
       
   413         [lambda x: x]),
       
   414 }
       
   415 
       
   416 _InstanceConnectionInfos = namedtuple("InstanceConnectionInfos",
       
   417     ["name", "negated", "edge", "position", "links"])
       
   418 
       
   419 _ConnectionLinkInfos = namedtuple("ConnectionLinkInfos",
       
   420     ["refLocalId", "formalParameter", "points"])
       
   421 
       
   422 _ActionInfos = namedtuple("ActionInfos",
       
   423     ["qualifier", "type", "value", "duration", "indicator"])
       
   424 
       
   425 def _translate_args(translations, args):
       
   426     return [translate(arg[0]) if len(arg) > 0 else None 
       
   427             for translate, arg in
       
   428             zip(translations, args)]
       
   429 
       
   430 class BlockInstanceFactory:
       
   431     
       
   432     def __init__(self, block_instances):
       
   433         self.BlockInstances = block_instances
       
   434         self.CurrentInstance = None
       
   435         self.SpecificValues = None
       
   436         self.CurrentConnection = None
       
   437         self.CurrentLink = None
       
   438     
       
   439     def SetSpecificValues(self, context, *args):
       
   440         self.SpecificValues = list(args)
       
   441         self.CurrentInstance = None
       
   442         self.CurrentConnection = None
       
   443         self.CurrentLink = None
       
   444     
       
   445     def AddBlockInstance(self, context, *args):
       
   446         specific_values_tuple, specific_values_translation = \
       
   447             _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues)
       
   448         
       
   449         if (args[0][0] == "step" and len(self.SpecificValues) < 3 or
       
   450             args[0][0] == "transition" and len(self.SpecificValues) < 4):
       
   451             self.SpecificValues.append([None])
       
   452         elif args[0][0] == "actionBlock" and len(self.SpecificValues) < 1:
       
   453             self.SpecificValues.append([[]])
       
   454         specific_values = specific_values_tuple(*_translate_args(
       
   455             specific_values_translation, self.SpecificValues))
       
   456         self.SpecificValues = None
       
   457         
       
   458         self.CurrentInstance = _BlockInstanceInfos(
       
   459             *(_translate_args([str] + [int] * 5, args) + 
       
   460               [specific_values, [], []]))
       
   461         
       
   462         self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance
       
   463         
       
   464     def AddInstanceConnection(self, context, *args):
       
   465         connection_args = _translate_args(
       
   466             [str, str, _BoolValue, str, int, int], args)
       
   467         
       
   468         self.CurrentConnection = _InstanceConnectionInfos(
       
   469             *(connection_args[1:4] + [
       
   470                 _Point(*connection_args[4:6]), []]))
       
   471         
       
   472         if self.CurrentInstance is not None:
       
   473             if connection_args[0] == "input":
       
   474                 self.CurrentInstance.inputs.append(self.CurrentConnection)
       
   475             else:
       
   476                 self.CurrentInstance.outputs.append(self.CurrentConnection)
       
   477         else:
       
   478             self.SpecificValues.append([self.CurrentConnection])
       
   479     
       
   480     def AddConnectionLink(self, context, *args):
       
   481         self.CurrentLink = _ConnectionLinkInfos(
       
   482             *(_translate_args([int, str], args) + [[]]))
       
   483         self.CurrentConnection.links.append(self.CurrentLink)
       
   484     
       
   485     def AddLinkPoint(self, context, *args):
       
   486         self.CurrentLink.points.append(_Point(
       
   487             *_translate_args([int, int], args)))
       
   488     
       
   489     def AddAction(self, context, *args):
       
   490         if len(self.SpecificValues) == 0:
       
   491             self.SpecificValues.append([[]])
       
   492         translated_args = _translate_args([str] * 5, args)
       
   493         if translated_args[0] is None:
       
   494             translated_args[0] = ""
       
   495         self.SpecificValues[0][0].append(_ActionInfos(*translated_args))
       
   496     
       
   497 pou_block_instances_xslt = etree.parse(
       
   498     os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt"))
   347 
   499 
   348 #-------------------------------------------------------------------------------
   500 #-------------------------------------------------------------------------------
   349 #                         Undo Buffer for PLCOpenEditor
   501 #                         Undo Buffer for PLCOpenEditor
   350 #-------------------------------------------------------------------------------
   502 #-------------------------------------------------------------------------------
   351 
   503 
   634                                pou_types["program"], configurations]
   786                                pou_types["program"], configurations]
   635             return infos
   787             return infos
   636         return None
   788         return None
   637 
   789 
   638     def GetPouVariables(self, tagname, debug = False):
   790     def GetPouVariables(self, tagname, debug = False):
   639         vars = []
       
   640         pou_type = None
   791         pou_type = None
   641         project = self.GetProject(debug)
   792         project = self.GetProject(debug)
   642         if project is not None:
   793         if project is not None:
   643             pou_variable_xslt_tree = etree.XSLT(
   794             pou_variable_xslt_tree = etree.XSLT(
   644                 pou_variables_xslt, extensions = {
   795                 pou_variables_xslt, extensions = {
  1614         if basetype_content_type in ["array", "subrangeSigned", "subrangeUnsigned"]:
  1765         if basetype_content_type in ["array", "subrangeSigned", "subrangeUnsigned"]:
  1615             basetype = basetype_content.baseType.getcontent()
  1766             basetype = basetype_content.baseType.getcontent()
  1616             basetype_type = basetype.getLocalTag()
  1767             basetype_type = basetype.getLocalTag()
  1617             return (basetype.getname() if basetype_type == "derived"
  1768             return (basetype.getname() if basetype_type == "derived"
  1618                     else basetype_type.upper())
  1769                     else basetype_type.upper())
  1619         elif basetype_content_type == "derived":
  1770         return (basetype_content.getname() if basetype_content_type == "derived"
  1620             return basetype_content_type.getname()
  1771                 else basetype_content_type.upper())
  1621         return None
  1772         return None
  1622 
  1773 
  1623     # Return Base Type of given possible derived type
  1774     # Return Base Type of given possible derived type
  1624     def GetBaseType(self, typename, debug = False):
  1775     def GetBaseType(self, typename, debug = False):
  1625         if TypeHierarchy.has_key(typename):
  1776         if TypeHierarchy.has_key(typename):
  2287                     instance.setexecutionOrderId(0)
  2438                     instance.setexecutionOrderId(0)
  2288                 instance.translate(*diff)
  2439                 instance.translate(*diff)
  2289             
  2440             
  2290             return new_id, connections
  2441             return new_id, connections
  2291     
  2442     
  2292     # Return the current pou editing instances idx
  2443     def GetEditedElementInstancesInfos(self, tagname, debug = False):
  2293     def GetEditedElementInstancesIds(self, tagname, debug = False):
  2444         element_instances = OrderedDict()
  2294         element = self.GetEditedElement(tagname, debug)
  2445         element = self.GetEditedElement(tagname, debug)
  2295         if element is not None:
  2446         if element is not None:
  2296             return element.getinstancesIds()
  2447             factory = BlockInstanceFactory(element_instances)
  2297         return []
  2448             
  2298     
  2449             pou_block_instances_xslt_tree = etree.XSLT(
  2299     # Return the current pou editing informations
  2450                 pou_block_instances_xslt, 
  2300     def GetEditedElementInstanceInfos(self, tagname, id, debug = False):
  2451                 extensions = {
  2301         element = self.GetEditedElement(tagname, debug)
  2452                     ("pou_block_instances_ns", name): getattr(factory, name)
  2302         if element is not None:
  2453                     for name in ["AddBlockInstance", "SetSpecificValues",
  2303             instance = element.getinstance(id)
  2454                                  "AddInstanceConnection", "AddConnectionLink",
  2304             if instance is not None:
  2455                                  "AddLinkPoint", "AddAction"]})
  2305                 infos = instance.getinfos()
  2456         
  2306                 if infos["type"] in ["input", "output", "inout"]:
  2457             pou_block_instances_xslt_tree(element)
  2307                     var_type = self.GetEditedElementVarValueType(tagname, infos["specific_values"]["name"], debug)
  2458         return element_instances
  2308                     infos["specific_values"]["value_type"] = var_type
       
  2309                 return infos
       
  2310         return None
       
  2311     
  2459     
  2312     def ClearEditedElementExecutionOrder(self, tagname):
  2460     def ClearEditedElementExecutionOrder(self, tagname):
  2313         element = self.GetEditedElement(tagname)
  2461         element = self.GetEditedElement(tagname)
  2314         if element is not None:
  2462         if element is not None:
  2315             element.resetexecutionOrder()
  2463             element.resetexecutionOrder()
  2316     
  2464     
  2317     def ResetEditedElementExecutionOrder(self, tagname):
  2465     def ResetEditedElementExecutionOrder(self, tagname):
  2318         element = self.GetEditedElement(tagname)
  2466         element = self.GetEditedElement(tagname)
  2319         if element is not None:
  2467         if element is not None:
  2320             element.compileexecutionOrder()
  2468             element.compileexecutionOrder()
  2321     
       
  2322     # Return the variable type of the given pou
       
  2323     def GetEditedElementVarValueType(self, tagname, varname, debug = False):
       
  2324         project = self.GetProject(debug)
       
  2325         if project is not None:
       
  2326             words = tagname.split("::")
       
  2327             if words[0] in ["P","T","A"]:
       
  2328                 pou = self.Project.getpou(words[1])
       
  2329                 if pou is not None:
       
  2330                     if words[0] == "T" and varname == words[2]:
       
  2331                         return "BOOL"
       
  2332                     if words[1] == varname:
       
  2333                         return self.GetPouInterfaceReturnType(pou)[0]
       
  2334                     for type, varlist in pou.getvars():
       
  2335                         for var in varlist.getvariable():
       
  2336                             if var.getname() == varname:
       
  2337                                 vartype_content = var.gettype().getcontent()
       
  2338                                 vartype_content_type = vartype_content.getLocalTag()
       
  2339                                 if vartype_content_type == "derived":
       
  2340                                     return vartype_content.getname()
       
  2341                                 else:
       
  2342                                     return vartype_content_type.upper()
       
  2343         return None
       
  2344     
  2469     
  2345     def SetConnectionWires(self, connection, connector):
  2470     def SetConnectionWires(self, connection, connector):
  2346         wires = connector.GetWires()
  2471         wires = connector.GetWires()
  2347         idx = 0
  2472         idx = 0
  2348         for wire, handle in wires:
  2473         for wire, handle in wires: