PLCControler.py
changeset 1957 2d1cc4f5e4ef
parent 1954 b113d7de4899
child 1959 ce1bfd04b3f6
--- a/PLCControler.py	Tue Feb 20 15:09:01 2018 +0100
+++ b/PLCControler.py	Fri Feb 23 11:16:25 2018 +0100
@@ -31,9 +31,6 @@
 import re
 import datetime
 from time import localtime
-from collections import OrderedDict, namedtuple
-
-from lxml import etree
 
 import util.paths as paths
 from plcopen import *
@@ -42,6 +39,7 @@
 from plcopen.InstancesPathCollector import InstancesPathCollector
 from plcopen.POUVariablesCollector import POUVariablesCollector
 from plcopen.InstanceTagnameCollector import InstanceTagnameCollector
+from plcopen.BlockInstanceCollector import BlockInstanceCollector
 from plcopen.VariableInfoCollector import VariableInfoCollector
 from graphics.GraphicCommons import *
 from PLCGenerator import *
@@ -50,162 +48,6 @@
 
 ScriptDirectory = paths.AbsDir(__file__)
 
-# -------------------------------------------------------------------------------
-#           Helpers object for generating pou block instances list
-# -------------------------------------------------------------------------------
-
-
-_Point = namedtuple("Point", ["x", "y"])
-
-_BlockInstanceInfos = namedtuple(
-    "BlockInstanceInfos",
-    ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"])
-
-_BlockSpecificValues = (
-    namedtuple("BlockSpecificValues",
-               ["name", "execution_order"]),
-    [_StringValue, int])
-_VariableSpecificValues = (
-    namedtuple("VariableSpecificValues",
-               ["name", "value_type", "execution_order"]),
-    [_StringValue, _StringValue, int])
-_ConnectionSpecificValues = (
-    namedtuple("ConnectionSpecificValues", ["name"]),
-    [_StringValue])
-
-_PowerRailSpecificValues = (
-    namedtuple("PowerRailSpecificValues", ["connectors"]),
-    [int])
-
-_LDElementSpecificValues = (
-    namedtuple("LDElementSpecificValues",
-               ["name", "negated", "edge", "storage", "execution_order"]),
-    [_StringValue, _BoolValue, _StringValue, _StringValue, int])
-
-_DivergenceSpecificValues = (
-    namedtuple("DivergenceSpecificValues", ["connectors"]),
-    [int])
-
-_SpecificValuesTuples = {
-    "comment": (
-        namedtuple("CommentSpecificValues", ["content"]),
-        [_StringValue]),
-    "input": _VariableSpecificValues,
-    "output": _VariableSpecificValues,
-    "inout": _VariableSpecificValues,
-    "connector": _ConnectionSpecificValues,
-    "continuation": _ConnectionSpecificValues,
-    "leftPowerRail": _PowerRailSpecificValues,
-    "rightPowerRail": _PowerRailSpecificValues,
-    "contact": _LDElementSpecificValues,
-    "coil": _LDElementSpecificValues,
-    "step": (
-        namedtuple("StepSpecificValues", ["name", "initial", "action"]),
-        [_StringValue, _BoolValue, lambda x: x]),
-    "transition": (
-        namedtuple("TransitionSpecificValues",
-                   ["priority", "condition_type", "condition", "connection"]),
-        [int, _StringValue, _StringValue, lambda x: x]),
-    "selectionDivergence": _DivergenceSpecificValues,
-    "selectionConvergence": _DivergenceSpecificValues,
-    "simultaneousDivergence": _DivergenceSpecificValues,
-    "simultaneousConvergence": _DivergenceSpecificValues,
-    "jump": (
-        namedtuple("JumpSpecificValues", ["target"]),
-        [_StringValue]),
-    "actionBlock": (
-        namedtuple("ActionBlockSpecificValues", ["actions"]),
-        [lambda x: x]),
-}
-
-_InstanceConnectionInfos = namedtuple(
-    "InstanceConnectionInfos",
-    ["name", "negated", "edge", "position", "links"])
-
-_ConnectionLinkInfos = namedtuple(
-    "ConnectionLinkInfos",
-    ["refLocalId", "formalParameter", "points"])
-
-
-class _ActionInfos(object):
-    __slots__ = ["qualifier", "type", "value", "duration", "indicator"]
-
-    def __init__(self, *args):
-        for attr, value in zip(self.__slots__, args):
-            setattr(self, attr, value if value is not None else "")
-
-    def copy(self):
-        return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__])
-
-
-class BlockInstanceFactory(object):
-
-    def __init__(self, block_instances):
-        self.BlockInstances = block_instances
-        self.CurrentInstance = None
-        self.SpecificValues = None
-        self.CurrentConnection = None
-        self.CurrentLink = None
-
-    def SetSpecificValues(self, context, *args):
-        self.SpecificValues = list(args)
-        self.CurrentInstance = None
-        self.CurrentConnection = None
-        self.CurrentLink = None
-
-    def AddBlockInstance(self, context, *args):
-        specific_values_tuple, specific_values_translation = \
-            _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues)
-
-        if args[0][0] == "step" and len(self.SpecificValues) < 3 or \
-           args[0][0] == "transition" and len(self.SpecificValues) < 4:
-            self.SpecificValues.append([None])
-        elif args[0][0] == "actionBlock" and len(self.SpecificValues) < 1:
-            self.SpecificValues.append([[]])
-        specific_values = specific_values_tuple(*_translate_args(
-            specific_values_translation, self.SpecificValues))
-        self.SpecificValues = None
-
-        self.CurrentInstance = _BlockInstanceInfos(
-            *(_translate_args([_StringValue, int] + [float] * 4, args) +
-              [specific_values, [], []]))
-
-        self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance
-
-    def AddInstanceConnection(self, context, *args):
-        connection_args = _translate_args(
-            [_StringValue] * 2 + [_BoolValue, _StringValue] + [float] * 2, args)
-
-        self.CurrentConnection = _InstanceConnectionInfos(
-            *(connection_args[1:4] + [
-                _Point(*connection_args[4:6]), []]))
-
-        if self.CurrentInstance is not None:
-            if connection_args[0] == "input":
-                self.CurrentInstance.inputs.append(self.CurrentConnection)
-            else:
-                self.CurrentInstance.outputs.append(self.CurrentConnection)
-        else:
-            self.SpecificValues.append([self.CurrentConnection])
-
-    def AddConnectionLink(self, context, *args):
-        self.CurrentLink = _ConnectionLinkInfos(
-            *(_translate_args([int, _StringValue], args) + [[]]))
-        self.CurrentConnection.links.append(self.CurrentLink)
-
-    def AddLinkPoint(self, context, *args):
-        self.CurrentLink.points.append(_Point(
-            *_translate_args([float] * 2, args)))
-
-    def AddAction(self, context, *args):
-        if len(self.SpecificValues) == 0:
-            self.SpecificValues.append([[]])
-        translated_args = _translate_args([_StringValue] * 5, args)
-        self.SpecificValues[0][0].append(_ActionInfos(*translated_args))
-
-
-pou_block_instances_xslt = etree.parse(
-    os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt"))
 
 
 # Length of the buffer
@@ -308,6 +150,7 @@
         self.InstancesPathCollector = InstancesPathCollector(self)
         self.POUVariablesCollector = POUVariablesCollector(self)
         self.InstanceTagnameCollector = InstanceTagnameCollector(self)
+        self.BlockInstanceCollector = BlockInstanceCollector(self)
         self.VariableInfoCollector = VariableInfoCollector(self)
 
     # Reset PLCControler internal variables
@@ -2112,21 +1955,10 @@
             return new_id, connections
 
     def GetEditedElementInstancesInfos(self, tagname, debug=False):
-        element_instances = OrderedDict()
         element = self.GetEditedElement(tagname, debug)
         if element is not None:
-            factory = BlockInstanceFactory(element_instances)
-
-            pou_block_instances_xslt_tree = etree.XSLT(
-                pou_block_instances_xslt,
-                extensions={
-                    ("pou_block_instances_ns", name): getattr(factory, name)
-                    for name in ["AddBlockInstance", "SetSpecificValues",
-                                 "AddInstanceConnection", "AddConnectionLink",
-                                 "AddLinkPoint", "AddAction"]})
-
-            pou_block_instances_xslt_tree(element)
-        return element_instances
+            return self.BlockInstanceCollector.Collect(element, debug)
+        return {}
 
     def ClearEditedElementExecutionOrder(self, tagname):
         element = self.GetEditedElement(tagname)