plcopen/BlockInstanceCollector.py
author Andrey Skvortsov <andrej.skvortzov@gmail.com>
Wed, 13 Mar 2019 11:47:03 +0300
changeset 2537 eb4a4cc41914
parent 1973 cc7a46953471
child 3750 f62625418bff
permissions -rw-r--r--
Fix various pylint and pep8 errors

Check basic code-style problems for PEP-8
pep8 version: 2.4.0
./connectors/PYRO/__init__.py:57:43: E261 at least two spaces before inline comment
./connectors/SchemeEditor.py:29:21: E128 continuation line under-indented for visual indent
./controls/IDBrowser.py:101:23: E127 continuation line over-indented for visual indent
./controls/IDBrowser.py:102:23: E127 continuation line over-indented for visual indent

Check for problems using pylint ...
No config file found, using default configuration
pylint 1.9.4,
astroid 1.6.5
Python 2.7.16rc1 (default, Feb 18 2019, 11:05:09)
[GCC 8.2.0]
Use multiple threads for pylint
Using config file /home/developer/WorkData/PLC/beremiz/beremiz/.pylint
************* Module connectors.PYRO_dialog
connectors/PYRO_dialog.py:9: [W0611(unused-import), ] Unused import wx
************* Module connectors
connectors/__init__.py:32: [W1652(deprecated-types-field), ] Accessing a deprecated fields on the types module
connectors/__init__.py:32: [C0411(wrong-import-order), ] standard import "from types import ClassType" should be placed before "from connectors.ConnectorBase import ConnectorBase"
************* Module connectors.PYRO.PSK_Adapter
connectors/PYRO/PSK_Adapter.py:7: [C0411(wrong-import-order), ] standard import "import ssl" should be placed before "import sslpsk"
************* Module connectors.SchemeEditor
connectors/SchemeEditor.py:29: [C0330(bad-continuation), ] Wrong continued indentation (add 1 space).
wx.ALIGN_CENTER_VERTICAL),
^|
connectors/SchemeEditor.py:42: [W0631(undefined-loop-variable), SchemeEditor.__init__] Using possibly undefined loop variable 'tag'
************* Module runtime.WampClient
runtime/WampClient.py:138: [W1612(unicode-builtin), WampSession.onJoin] unicode built-in referenced
runtime/WampClient.py:154: [W1612(unicode-builtin), WampSession.publishWithOwnID] unicode built-in referenced
runtime/WampClient.py:346: [W1612(unicode-builtin), PublishEvent] unicode built-in referenced
runtime/WampClient.py:351: [W1612(unicode-builtin), PublishEventWithOwnID] unicode built-in referenced
runtime/WampClient.py:31: [W0611(unused-import), ] Unused str imported from builtins as text
************* Module runtime.PLCObject
runtime/PLCObject.py:35: [W1648(bad-python3-import), ] Module moved in Python 3
runtime/PLCObject.py:35: [C0411(wrong-import-order), ] standard import "import md5" should be placed before "from six.moves import xrange"
runtime/PLCObject.py:36: [C0411(wrong-import-order), ] standard import "from tempfile import mkstemp" should be placed before "from six.moves import xrange"
runtime/PLCObject.py:37: [C0411(wrong-import-order), ] standard import "import shutil" should be placed before "from six.moves import xrange"
runtime/PLCObject.py:38: [C0411(wrong-import-order), ] standard import "from functools import wraps, partial" should be placed before "from six.moves import xrange"
************* Module runtime.Worker
runtime/Worker.py:12: [W1648(bad-python3-import), ] Module moved in Python 3
************* Module runtime.spawn_subprocess
runtime/spawn_subprocess.py:125: [C0325(superfluous-parens), ] Unnecessary parens after 'print' keyword
runtime/spawn_subprocess.py:130: [C0325(superfluous-parens), ] Unnecessary parens after 'print' keyword
runtime/spawn_subprocess.py:125: [E1601(print-statement), ] print statement used
runtime/spawn_subprocess.py:130: [E1601(print-statement), ] print statement used
************* Module controls.IDBrowser
controls/IDBrowser.py:101: [C0330(bad-continuation), ] Wrong continued indentation (remove 5 spaces).
if self.isManager
| ^
controls/IDBrowser.py:102: [C0330(bad-continuation), ] Wrong continued indentation (remove 5 spaces).
else dv.DATAVIEW_CELL_INERT),
| ^
************* Module Beremiz_service
Beremiz_service.py:34: [W0611(unused-import), ] Unused import __builtin__
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of Beremiz.
# See COPYING file for copyrights details.

from __future__ import absolute_import
from collections import OrderedDict, namedtuple
from plcopen.XSLTModelQuery import XSLTModelQuery, _StringValue, _BoolValue, _translate_args

# -------------------------------------------------------------------------------
#           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))


class BlockInstanceCollector(XSLTModelQuery):
    """ object for collecting instances path list"""
    def __init__(self, controller):
        XSLTModelQuery.__init__(self,
                                controller,
                                "pou_block_instances.xslt",
                                [(name, self.FactoryCaller(name))
                                 for name in ["AddBlockInstance",
                                              "SetSpecificValues",
                                              "AddInstanceConnection",
                                              "AddConnectionLink",
                                              "AddLinkPoint",
                                              "AddAction"]])

    def FactoryCaller(self, funcname):
        def CallFactory(*args):
            return getattr(self.factory, funcname)(*args)
        return CallFactory

    def Collect(self, root, debug):
        element_instances = OrderedDict()
        self.factory = BlockInstanceFactory(element_instances)
        self._process_xslt(root, debug)
        self.factory = None
        return element_instances