svghmi/svghmi.py
author Edouard Tisserant
Fri, 12 Mar 2021 15:12:38 +0100
branchsvghmi
changeset 3187 ba8ff21fd82b
parent 3180 c059026d8626
child 3193 8006bb60a4dd
permissions -rw-r--r--
SVGHMI: change default values for JsonTable, leading to scrollbar initialized at annoying non-zero position
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     1
#!/usr/bin/env python
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     2
# -*- coding: utf-8 -*-
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     3
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     4
# This file is part of Beremiz
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     5
# Copyright (C) 2019: Edouard TISSERANT
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     6
#
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     7
# See COPYING file for copyrights details.
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     8
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     9
from __future__ import absolute_import
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    10
import os
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    11
import shutil
2763
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
    12
from itertools import izip, imap
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
    13
from pprint import pformat
2789
ba0dd2ec6dc4 SVGHMI: now built.
Edouard Tisserant
parents: 2788
diff changeset
    14
import hashlib
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    15
import weakref
2823
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
    16
import shlex
3156
76c0c0a524c9 SVGHMI: display progress in IDE console while building
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3140
diff changeset
    17
import time
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    18
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    19
import wx
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    20
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    21
from lxml import etree
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    22
from lxml.etree import XSLTApplyError
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    23
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    24
import util.paths as paths
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    25
from POULibrary import POULibrary
2756
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
    26
from docutil import open_svg, get_inkscape_path
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    27
2756
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
    28
from util.ProcessLogger import ProcessLogger
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
    29
from runtime.typemapping import DebugTypesSize
2767
302347f48193 svghmi.c : deduplicated variable access code borrowed from plc_debug.c. Added targets/var_access.c.
Edouard Tisserant
parents: 2765
diff changeset
    30
import targets
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    31
from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    32
from XSLTransform import XSLTransform
3114
fb1e320836e8 SVGHMI: i18n: better warning messages, more explicit.
Edouard Tisserant
parents: 3113
diff changeset
    33
from svghmi.i18n import EtreeToMessages, SaveCatalog, ReadTranslations, MatchTranslations, TranslationToEtree, open_pofile
2756
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
    34
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    35
HMI_TYPES_DESC = {
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
    36
    "HMI_NODE":{},
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    37
    "HMI_STRING":{},
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    38
    "HMI_INT":{},
3068
81758c94f3df SVGHMI: Fix HMI_REAL support, and add a HMI_REAL use case in tests/svghmi.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3052
diff changeset
    39
    "HMI_BOOL":{},
81758c94f3df SVGHMI: Fix HMI_REAL support, and add a HMI_REAL use case in tests/svghmi.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3052
diff changeset
    40
    "HMI_REAL":{}
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    41
}
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    42
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    43
HMI_TYPES = HMI_TYPES_DESC.keys()
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    44
2753
9a7e12e96399 SVGHMI: Added XSLT transformation, Makefile to get XSLT from ysl2 (copy of plcopen/Makefile) and a minimal stylesheet to start with.
Edouard Tisserant
parents: 2750
diff changeset
    45
9a7e12e96399 SVGHMI: Added XSLT transformation, Makefile to get XSLT from ysl2 (copy of plcopen/Makefile) and a minimal stylesheet to start with.
Edouard Tisserant
parents: 2750
diff changeset
    46
ScriptDirectory = paths.AbsDir(__file__)
9a7e12e96399 SVGHMI: Added XSLT transformation, Makefile to get XSLT from ysl2 (copy of plcopen/Makefile) and a minimal stylesheet to start with.
Edouard Tisserant
parents: 2750
diff changeset
    47
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    48
class HMITreeNode(object):
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
    49
    def __init__(self, path, name, nodetype, iectype = None, vartype = None, cpath = None, hmiclass = None):
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    50
        self.path = path
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    51
        self.name = name
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    52
        self.nodetype = nodetype
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
    53
        self.hmiclass = hmiclass
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
    54
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
    55
        if iectype is not None:
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
    56
            self.iectype = iectype
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
    57
            self.vartype = vartype
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
    58
            self.cpath = cpath
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
    59
2890
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
    60
        if nodetype in ["HMI_NODE"]:
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    61
            self.children = []
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    62
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    63
    def pprint(self, indent = 0):
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    64
        res = ">"*indent + pformat(self.__dict__, indent = indent, depth = 1) + "\n"
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
    65
        if hasattr(self, "children"):
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    66
            res += "\n".join([child.pprint(indent = indent + 1)
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    67
                              for child in self.children])
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    68
            res += "\n"
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
    69
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    70
        return res
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    71
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    72
    def place_node(self, node):
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    73
        best_child = None
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    74
        known_best_match = 0
2965
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
    75
        potential_siblings = {}
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
    76
        for child in self.children:
2762
282500e03dbc Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents: 2758
diff changeset
    77
            if child.path is not None:
282500e03dbc Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents: 2758
diff changeset
    78
                in_common = 0
282500e03dbc Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents: 2758
diff changeset
    79
                for child_path_item, node_path_item in izip(child.path, node.path):
282500e03dbc Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents: 2758
diff changeset
    80
                    if child_path_item == node_path_item:
282500e03dbc Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents: 2758
diff changeset
    81
                        in_common +=1
282500e03dbc Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents: 2758
diff changeset
    82
                    else:
282500e03dbc Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents: 2758
diff changeset
    83
                        break
2945
69f395c01c09 SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents: 2890
diff changeset
    84
                # Match can only be HMI_NODE, and the whole path of node
69f395c01c09 SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents: 2890
diff changeset
    85
                # must match candidate node (except for name part)
69f395c01c09 SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents: 2890
diff changeset
    86
                # since candidate would become child of that node
69f395c01c09 SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents: 2890
diff changeset
    87
                if in_common > known_best_match and \
69f395c01c09 SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents: 2890
diff changeset
    88
                   child.nodetype == "HMI_NODE" and \
69f395c01c09 SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents: 2890
diff changeset
    89
                   in_common == len(child.path) - 1:
2762
282500e03dbc Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents: 2758
diff changeset
    90
                    known_best_match = in_common
282500e03dbc Add special nodes at HMI Tree root, fix code to handle special node (no path).
Edouard Tisserant
parents: 2758
diff changeset
    91
                    best_child = child
2965
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
    92
                else:
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
    93
                    potential_siblings[child.path[
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
    94
                        -2 if child.nodetype == "HMI_NODE" else -1]] = child
2945
69f395c01c09 SVGHMI: Fix flawed logic to place nodes in the HMI tree, leading to wrecked tree in some cases.
Edouard Tisserant
parents: 2890
diff changeset
    95
        if best_child is not None:
2965
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
    96
            if node.nodetype == "HMI_NODE" and best_child.path[:-1] == node.path[:-1]:
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
    97
                return "Duplicate_HMI_NODE", best_child
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
    98
            return best_child.place_node(node)
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    99
        else:
2965
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   100
            candidate_name = node.path[-2 if node.nodetype == "HMI_NODE" else -1]
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   101
            if candidate_name in potential_siblings:
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   102
                return "Non_Unique", potential_siblings[candidate_name]
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   103
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   104
            if node.nodetype == "HMI_NODE" and len(self.children) > 0:
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   105
                prev = self.children[-1]
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   106
                if prev.path[:-1] == node.path[:-1]:
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   107
                    return "Late_HMI_NODE",prev
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   108
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   109
            self.children.append(node)
2965
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   110
            return None
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   111
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   112
    def etree(self, add_hash=False):
2763
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   113
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   114
        attribs = dict(name=self.name)
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   115
        if self.path is not None:
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   116
            attribs["path"] = ".".join(self.path)
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   117
2815
77b2a3757e66 SVGHMI: add a class attribute to HMI Tree nodes, set when using HMI_NODE
Edouard Tisserant
parents: 2814
diff changeset
   118
        if self.hmiclass is not None:
77b2a3757e66 SVGHMI: add a class attribute to HMI Tree nodes, set when using HMI_NODE
Edouard Tisserant
parents: 2814
diff changeset
   119
            attribs["class"] = self.hmiclass
77b2a3757e66 SVGHMI: add a class attribute to HMI Tree nodes, set when using HMI_NODE
Edouard Tisserant
parents: 2814
diff changeset
   120
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   121
        if add_hash:
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   122
            attribs["hash"] = ",".join(map(str,self.hash()))
2763
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   123
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   124
        res = etree.Element(self.nodetype, **attribs)
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   125
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   126
        if hasattr(self, "children"):
2763
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   127
            for child_etree in imap(lambda c:c.etree(), self.children):
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   128
                res.append(child_etree)
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   129
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   130
        return res
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   131
3176
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   132
    @classmethod
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   133
    def from_etree(cls, enode):
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   134
        """
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   135
        alternative constructor, restoring HMI Tree from XML backup
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   136
        note: all C-related information is gone, 
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   137
              this restore is only for tree display and widget picking
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   138
        """
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   139
        nodetype = enode.tag
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   140
        attributes = enode.attrib
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   141
        name = attributes["name"]
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   142
        path = attributes["path"].split('.') if "path" in attributes else None 
3177
5a8abd549aa8 SVGHMI: Lighter display of HMI Tree, no more icons and use buttons. Auto expand root. Fix loading of HMI tree XML backup (hmiclass attribute wasn't kept).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3176
diff changeset
   143
        hmiclass = attributes.get("class", None)
3176
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   144
        # hash is computed on demand
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   145
        node = cls(path, name, nodetype, hmiclass=hmiclass)
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   146
        for child in enode.iterchildren():
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   147
            node.children.append(cls.from_etree(child))
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   148
        return node
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   149
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   150
    def traverse(self):
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   151
        yield self
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   152
        if hasattr(self, "children"):
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   153
            for c in self.children:
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   154
                for yoodl in c.traverse():
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   155
                    yield yoodl
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   156
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   157
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   158
    def hash(self):
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   159
        """ Produce a hash, any change in HMI tree structure change that hash """
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   160
        s = hashlib.new('md5')
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   161
        self._hash(s)
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   162
        # limit size to HMI_HASH_SIZE as in svghmi.c
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   163
        return map(ord,s.digest())[:8]
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   164
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   165
    def _hash(self, s):
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   166
        s.update(str((self.name,self.nodetype)))
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   167
        if hasattr(self, "children"):
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   168
            for c in self.children:
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   169
                c._hash(s)
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   170
2763
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   171
# module scope for HMITree root
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   172
# so that CTN can use HMITree deduced in Library
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   173
# note: this only works because library's Generate_C is
2763
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   174
#       systematicaly invoked before CTN's CTNGenerate_C
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   175
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   176
hmi_tree_root = None
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   177
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   178
on_hmitree_update = None
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   179
2890
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   180
SPECIAL_NODES = [("HMI_ROOT", "HMI_NODE"),
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   181
                 ("heartbeat", "HMI_INT")]
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   182
                 # ("current_page", "HMI_STRING")])
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   183
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   184
class SVGHMILibrary(POULibrary):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   185
    def GetLibraryPath(self):
2750
2694170cd88e intermediate commit, work in progress
Edouard Tisserant
parents: 2749
diff changeset
   186
         return paths.AbsNeighbourFile(__file__, "pous.xml")
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   187
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   188
    def Generate_C(self, buildpath, varlist, IECCFLAGS):
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   189
        global hmi_tree_root, on_hmitree_update
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   190
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   191
        """
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   192
        PLC Instance Tree:
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   193
          prog0
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   194
           +->v1 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   195
           +->v2 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   196
           +->fb0 (type mhoo)
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   197
           |   +->va HMI_NODE
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   198
           |   +->v3 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   199
           |   +->v4 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   200
           |
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   201
           +->fb1 (type mhoo)
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   202
           |   +->va HMI_NODE
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   203
           |   +->v3 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   204
           |   +->v4 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   205
           |
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   206
           +->fb2
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   207
               +->v5 HMI_IN
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   208
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   209
        HMI tree:
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   210
          hmi0
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   211
           +->v1
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   212
           +->v2
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   213
           +->fb0 class:va
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   214
           |   +-> v3
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   215
           |   +-> v4
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   216
           |
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   217
           +->fb1 class:va
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   218
           |   +-> v3
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   219
           |   +-> v4
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   220
           |
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   221
           +->v5
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   222
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   223
        """
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   224
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   225
        # Filter known HMI types
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   226
        hmi_types_instances = [v for v in varlist if v["derived"] in HMI_TYPES]
2758
5f79b194fa63 SVGHMI: filter out temporary variables created while generating ST code out of FBD.
Edouard Tisserant
parents: 2757
diff changeset
   227
2890
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   228
        hmi_tree_root = None
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   229
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   230
        # take first HMI_NODE (placed as special node), make it root
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   231
        for i,v in enumerate(hmi_types_instances):
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   232
            path = v["IEC_path"].split(".")
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   233
            derived = v["derived"]
2965
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   234
            if derived == "HMI_NODE":
2890
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   235
                hmi_tree_root = HMITreeNode(path, "", derived, v["type"], v["vartype"], v["C_path"])
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   236
                hmi_types_instances.pop(i)
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   237
                break
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2866
diff changeset
   238
3051
44dd48070e41 SVGHMI: nicer error message
Edouard Tisserant
parents: 3032
diff changeset
   239
        if hmi_tree_root is None:
44dd48070e41 SVGHMI: nicer error message
Edouard Tisserant
parents: 3032
diff changeset
   240
            self.FatalError("SVGHMI : Library is selected but not used. Please either deselect it in project config or add a SVGHMI node to project.")
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   241
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   242
        # deduce HMI tree from PLC HMI_* instances
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   243
        for v in hmi_types_instances:
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   244
            path = v["IEC_path"].split(".")
2758
5f79b194fa63 SVGHMI: filter out temporary variables created while generating ST code out of FBD.
Edouard Tisserant
parents: 2757
diff changeset
   245
            # ignores variables starting with _TMP_
5f79b194fa63 SVGHMI: filter out temporary variables created while generating ST code out of FBD.
Edouard Tisserant
parents: 2757
diff changeset
   246
            if path[-1].startswith("_TMP_"):
5f79b194fa63 SVGHMI: filter out temporary variables created while generating ST code out of FBD.
Edouard Tisserant
parents: 2757
diff changeset
   247
                continue
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   248
            derived = v["derived"]
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   249
            kwargs={}
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   250
            if derived == "HMI_NODE":
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   251
                # TODO : make problem if HMI_NODE used in CONFIG or RESOURCE
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   252
                name = path[-2]
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   253
                kwargs['hmiclass'] = path[-1]
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   254
            else:
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   255
                name = path[-1]
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   256
            new_node = HMITreeNode(path, name, derived, v["type"], v["vartype"], v["C_path"], **kwargs)
2965
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   257
            placement_result = hmi_tree_root.place_node(new_node)
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   258
            if placement_result is not None:
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   259
                cause, problematic_node = placement_result
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   260
                if cause == "Non_Unique":
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   261
                    message = _("HMI tree nodes paths are not unique.\nConflicting variable: {} {}").format(
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   262
                        ".".join(problematic_node.path),
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   263
                        ".".join(new_node.path))
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   264
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   265
                    last_FB = None 
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   266
                    for v in varlist:
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   267
                        if v["vartype"] == "FB":
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   268
                            last_FB = v 
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   269
                        if v["C_path"] == problematic_node:
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   270
                            break
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   271
                    if last_FB is not None:
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   272
                        failing_parent = last_FB["type"]
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   273
                        message += "\n"
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   274
                        message += _("Solution: Add HMI_NODE at beginning of {}").format(failing_parent)
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   275
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   276
                elif cause in ["Late_HMI_NODE", "Duplicate_HMI_NODE"]:
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   277
                    cause, problematic_node = placement_result
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   278
                    message = _("There must be only one occurrence of HMI_NODE before any HMI_* variable in POU.\nConflicting variable: {} {}").format(
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   279
                        ".".join(problematic_node.path),
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   280
                        ".".join(new_node.path))
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   281
8f928cee01e5 SVGHMI: Makes error when HMI tree is not well formed. Prevents multiple and non-first HMI_NODE, and ensure that all paths in HMI tree are unique.
Edouard Tisserant
parents: 2945
diff changeset
   282
                self.FatalError("SVGHMI : " + message)
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   283
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   284
        if on_hmitree_update is not None:
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   285
            on_hmitree_update()
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   286
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   287
        variable_decl_array = []
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   288
        extern_variables_declarations = []
2765
887aba5ef178 SVGHMI: svghmi.c now has mutex, iterator, and read/write buffer.
Edouard Tisserant
parents: 2764
diff changeset
   289
        buf_index = 0
2775
3b93409ba22c SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents: 2772
diff changeset
   290
        item_count = 0
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   291
        found_heartbeat = False
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   292
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   293
        hearbeat_IEC_path = ['CONFIG', 'HEARTBEAT']
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   294
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   295
        for node in hmi_tree_root.traverse():
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   296
            if not found_heartbeat and node.path == hearbeat_IEC_path:
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   297
                hmi_tree_hearbeat_index = item_count
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   298
                found_heartbeat = True
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   299
                extern_variables_declarations += [
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   300
                    "#define heartbeat_index "+str(hmi_tree_hearbeat_index)
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   301
                ]
2866
59a855c17aa6 SVGHMI: Stop ignoring HMI_NODE in HMI tree, and count it as a BOOL. Soon we use those nodes as reference for relative page jump, and as an "enable" bit for features associated to an HMI tree fragment.
Edouard Tisserant
parents: 2834
diff changeset
   302
            if hasattr(node, "iectype"):
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   303
                sz = DebugTypesSize.get(node.iectype, 0)
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   304
                variable_decl_array += [
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   305
                    "{&(" + node.cpath + "), " + node.iectype + {
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   306
                        "EXT": "_P_ENUM",
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   307
                        "IN":  "_P_ENUM",
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   308
                        "MEM": "_O_ENUM",
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   309
                        "OUT": "_O_ENUM",
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   310
                        "VAR": "_ENUM"
2765
887aba5ef178 SVGHMI: svghmi.c now has mutex, iterator, and read/write buffer.
Edouard Tisserant
parents: 2764
diff changeset
   311
                    }[node.vartype] + ", " +
2768
31785529a657 SVGHMI: Intermediate state while working on svghmi.c
Edouard Tisserant
parents: 2767
diff changeset
   312
                    str(buf_index) + ", 0, }"]
2765
887aba5ef178 SVGHMI: svghmi.c now has mutex, iterator, and read/write buffer.
Edouard Tisserant
parents: 2764
diff changeset
   313
                buf_index += sz
2775
3b93409ba22c SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents: 2772
diff changeset
   314
                item_count += 1
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   315
                if len(node.path) == 1:
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   316
                    extern_variables_declarations += [
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   317
                        "extern __IEC_" + node.iectype + "_" +
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   318
                        "t" if node.vartype is "VAR" else "p"
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   319
                        + node.cpath + ";"]
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   320
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   321
        assert(found_heartbeat)
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   322
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   323
        # TODO : filter only requiered external declarations
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   324
        for v in varlist:
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   325
            if v["C_path"].find('.') < 0:
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   326
                extern_variables_declarations += [
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   327
                    "extern %(type)s %(C_path)s;" % v]
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   328
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   329
        # TODO check if programs need to be declared separately
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   330
        # "programs_declarations": "\n".join(["extern %(type)s %(C_path)s;" %
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   331
        #                                     p for p in self._ProgramList]),
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   332
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   333
        # C code to observe/access HMI tree variables
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   334
        svghmi_c_filepath = paths.AbsNeighbourFile(__file__, "svghmi.c")
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   335
        svghmi_c_file = open(svghmi_c_filepath, 'r')
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   336
        svghmi_c_code = svghmi_c_file.read()
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   337
        svghmi_c_file.close()
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   338
        svghmi_c_code = svghmi_c_code % {
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   339
            "variable_decl_array": ",\n".join(variable_decl_array),
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   340
            "extern_variables_declarations": "\n".join(extern_variables_declarations),
2767
302347f48193 svghmi.c : deduplicated variable access code borrowed from plc_debug.c. Added targets/var_access.c.
Edouard Tisserant
parents: 2765
diff changeset
   341
            "buffer_size": buf_index,
2775
3b93409ba22c SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents: 2772
diff changeset
   342
            "item_count": item_count,
2768
31785529a657 SVGHMI: Intermediate state while working on svghmi.c
Edouard Tisserant
parents: 2767
diff changeset
   343
            "var_access_code": targets.GetCode("var_access.c"),
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   344
            "PLC_ticktime": self.GetCTR().GetTicktime(),
2789
ba0dd2ec6dc4 SVGHMI: now built.
Edouard Tisserant
parents: 2788
diff changeset
   345
            "hmi_hash_ints": ",".join(map(str,hmi_tree_root.hash()))
2764
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   346
            }
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   347
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   348
        gen_svghmi_c_path = os.path.join(buildpath, "svghmi.c")
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   349
        gen_svghmi_c = open(gen_svghmi_c_path, 'w')
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   350
        gen_svghmi_c.write(svghmi_c_code)
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   351
        gen_svghmi_c.close()
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   352
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   353
        # Python based WebSocket HMITree Server
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   354
        svghmiserverfile = open(paths.AbsNeighbourFile(__file__, "svghmi_server.py"), 'r')
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   355
        svghmiservercode = svghmiserverfile.read()
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   356
        svghmiserverfile.close()
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   357
2993
b76f303ffce6 Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents: 2984
diff changeset
   358
        runtimefile_path = os.path.join(buildpath, "runtime_00_svghmi.py")
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   359
        runtimefile = open(runtimefile_path, 'w')
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   360
        runtimefile.write(svghmiservercode)
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   361
        runtimefile.close()
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   362
3176
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   363
        # Backup HMI Tree in XML form so that it can be loaded without building
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   364
        hmitree_backup_path = os.path.join(buildpath, "hmitree.xml")
3180
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   365
        hmitree_backup_file = open(hmitree_backup_path, 'wb')
3176
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   366
        hmitree_backup_file.write(etree.tostring(hmi_tree_root.etree()))
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   367
        hmitree_backup_file.close()
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   368
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   369
        return ((["svghmi"], [(gen_svghmi_c_path, IECCFLAGS)], True), "",
2993
b76f303ffce6 Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents: 2984
diff changeset
   370
                ("runtime_00_svghmi.py", open(runtimefile_path, "rb")))
b76f303ffce6 Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents: 2984
diff changeset
   371
                #         ^
b76f303ffce6 Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents: 2984
diff changeset
   372
                # note the double zero after "runtime_", 
b76f303ffce6 Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents: 2984
diff changeset
   373
                # to ensure placement before other CTN generated code in execution order
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   374
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   375
2818
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   376
class HMITreeSelector(wx.TreeCtrl):
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   377
    def __init__(self, parent):
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   378
        global on_hmitree_update
3177
5a8abd549aa8 SVGHMI: Lighter display of HMI Tree, no more icons and use buttons. Auto expand root. Fix loading of HMI tree XML backup (hmiclass attribute wasn't kept).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3176
diff changeset
   379
        wx.TreeCtrl.__init__(self, parent, style=(
5a8abd549aa8 SVGHMI: Lighter display of HMI Tree, no more icons and use buttons. Auto expand root. Fix loading of HMI tree XML backup (hmiclass attribute wasn't kept).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3176
diff changeset
   380
            wx.TR_MULTIPLE |
5a8abd549aa8 SVGHMI: Lighter display of HMI Tree, no more icons and use buttons. Auto expand root. Fix loading of HMI tree XML backup (hmiclass attribute wasn't kept).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3176
diff changeset
   381
            wx.TR_HAS_BUTTONS |
5a8abd549aa8 SVGHMI: Lighter display of HMI Tree, no more icons and use buttons. Auto expand root. Fix loading of HMI tree XML backup (hmiclass attribute wasn't kept).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3176
diff changeset
   382
            wx.SUNKEN_BORDER |
5a8abd549aa8 SVGHMI: Lighter display of HMI Tree, no more icons and use buttons. Auto expand root. Fix loading of HMI tree XML backup (hmiclass attribute wasn't kept).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3176
diff changeset
   383
            wx.TR_LINES_AT_ROOT))
2818
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   384
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   385
        on_hmitree_update = self.SVGHMIEditorUpdater()
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   386
        self.MakeTree()
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   387
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   388
    def _recurseTree(self, current_hmitree_root, current_tc_root):
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   389
        for c in current_hmitree_root.children:
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   390
            if hasattr(c, "children"):
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   391
                display_name = ('{} (class={})'.format(c.name, c.hmiclass)) \
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   392
                               if c.hmiclass is not None else c.name
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   393
                tc_child = self.AppendItem(current_tc_root, display_name)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   394
                self.SetPyData(tc_child, None)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   395
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   396
                self._recurseTree(c,tc_child)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   397
            else:
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   398
                display_name = '{} {}'.format(c.nodetype[4:], c.name)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   399
                tc_child = self.AppendItem(current_tc_root, display_name)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   400
                self.SetPyData(tc_child, None)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   401
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   402
    def MakeTree(self):
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   403
        global hmi_tree_root
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   404
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   405
        self.Freeze()
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   406
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   407
        self.root = None
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   408
        self.DeleteAllItems()
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   409
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   410
        root_display_name = _("Please build to see HMI Tree") if hmi_tree_root is None else "HMI"
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   411
        self.root = self.AddRoot(root_display_name)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   412
        self.SetPyData(self.root, None)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   413
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   414
        if hmi_tree_root is not None:
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   415
            self._recurseTree(hmi_tree_root, self.root)
3177
5a8abd549aa8 SVGHMI: Lighter display of HMI Tree, no more icons and use buttons. Auto expand root. Fix loading of HMI tree XML backup (hmiclass attribute wasn't kept).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3176
diff changeset
   416
            self.Expand(self.root)
2818
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   417
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   418
        self.Thaw()
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   419
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   420
    def SVGHMIEditorUpdater(self):
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   421
        selfref = weakref.ref(self)
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   422
        def SVGHMIEditorUpdate():
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   423
            o = selfref()
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   424
            if o is not None:
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   425
                wx.CallAfter(o.MakeTree)
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   426
        return SVGHMIEditorUpdate
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   427
2818
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   428
class HMITreeView(wx.SplitterWindow):
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   429
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   430
    def __init__(self, parent):
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   431
        wx.SplitterWindow.__init__(self, parent,
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   432
                                   style=wx.SUNKEN_BORDER | wx.SP_3D)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   433
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   434
        self.SelectionTree = HMITreeSelector(self)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   435
        #self.Staging = wx.Panel(self)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   436
        #self.SplitHorizontally(self.SelectionTree, self.Staging, 200)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   437
        self.Initialize(self.SelectionTree)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   438
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   439
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   440
class SVGHMIEditor(ConfTreeNodeEditor):
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   441
    CONFNODEEDITOR_TABS = [
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   442
        (_("HMI Tree"), "CreateHMITreeView")]
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   443
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   444
    def CreateHMITreeView(self, parent):
2818
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   445
        #self.HMITreeView = HMITreeView(self)
3176
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   446
        global hmi_tree_root
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   447
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   448
        if hmi_tree_root is None:
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   449
            buildpath = self.Controler.GetCTRoot()._getBuildPath()
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   450
            hmitree_backup_path = os.path.join(buildpath, "hmitree.xml")
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   451
            if os.path.exists(hmitree_backup_path):
3180
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   452
                hmitree_backup_file = open(hmitree_backup_path, 'rb')
3176
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   453
                hmi_tree_root = HMITreeNode.from_etree(etree.parse(hmitree_backup_file).getroot())
81136a097012 SVGHMI: Systematically save HMI Tree in build directory as hmitree.xml when building, so that HMI Tree can be displayed when re-opening project, without having to build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3170
diff changeset
   454
2818
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   455
        return HMITreeSelector(parent)
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   456
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   457
class SVGHMI(object):
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   458
    XSD = """<?xml version="1.0" encoding="utf-8" ?>
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   459
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   460
      <xsd:element name="SVGHMI">
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   461
        <xsd:complexType>
2823
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   462
          <xsd:attribute name="OnStart" type="xsd:string" use="optional"/>
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   463
          <xsd:attribute name="OnStop" type="xsd:string" use="optional"/>
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   464
          <xsd:attribute name="OnWatchdog" type="xsd:string" use="optional"/>
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   465
          <xsd:attribute name="WatchdogInitial" type="xsd:integer" use="optional"/>
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   466
          <xsd:attribute name="WatchdogInterval" type="xsd:integer" use="optional"/>
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   467
        </xsd:complexType>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   468
      </xsd:element>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   469
    </xsd:schema>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   470
    """
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   471
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   472
    EditorType = SVGHMIEditor
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   473
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   474
    ConfNodeMethods = [
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   475
        {
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   476
            "bitmap":    "ImportSVG",
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   477
            "name":    _("Import SVG"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   478
            "tooltip": _("Import SVG"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   479
            "method":   "_ImportSVG"
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   480
        },
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   481
        {
3112
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   482
            "bitmap":    "EditSVG",  # should be something different
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   483
            "name":    _("Inkscape"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   484
            "tooltip": _("Edit HMI"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   485
            "method":   "_StartInkscape"
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   486
        },
3112
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   487
        {
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   488
            "bitmap":    "OpenPOT",  # should be something different
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   489
            "name":    _("New lang"),
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   490
            "tooltip": _("Open non translated message catalog (POT) to start new language"),
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   491
            "method":   "_OpenPOT"
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   492
        },
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   493
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   494
        {
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   495
            "bitmap":    "EditPO",  # should be something different
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   496
            "name":    _("Edit lang"),
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   497
            "tooltip": _("Edit existing message catalog (PO) for specific language"),
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   498
            "method":   "_EditPO"
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   499
        },
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   500
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   501
        # TODO : HMITree button
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   502
        #        - can drag'n'drop variabes to Inkscape
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   503
    ]
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   504
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   505
    def _getSVGpath(self, project_path=None):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   506
        if project_path is None:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   507
            project_path = self.CTNPath()
2781
fbdd0fd8ee4f SVGHMI: gui.svg -> svghmi.svg
Edouard Tisserant
parents: 2779
diff changeset
   508
        return os.path.join(project_path, "svghmi.svg")
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   509
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   510
    def _getPOTpath(self, project_path=None):
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   511
        if project_path is None:
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   512
            project_path = self.CTNPath()
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   513
        return os.path.join(project_path, "messages.pot")
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   514
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   515
    def OnCTNSave(self, from_project_path=None):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   516
        if from_project_path is not None:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   517
            shutil.copyfile(self._getSVGpath(from_project_path),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   518
                            self._getSVGpath())
3112
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   519
            shutil.copyfile(self._getPOTpath(from_project_path),
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   520
                            self._getPOTpath())
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   521
            # XXX TODO copy .PO files
2750
2694170cd88e intermediate commit, work in progress
Edouard Tisserant
parents: 2749
diff changeset
   522
        return True
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   523
2753
9a7e12e96399 SVGHMI: Added XSLT transformation, Makefile to get XSLT from ysl2 (copy of plcopen/Makefile) and a minimal stylesheet to start with.
Edouard Tisserant
parents: 2750
diff changeset
   524
    def GetSVGGeometry(self):
3170
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   525
        self.ProgressStart("inkscape", "collecting SVG geometry (Inkscape)")
2756
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   526
        # invoke inskscape -S, csv-parse output, produce elements
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   527
        InkscapeGeomColumns = ["Id", "x", "y", "w", "h"]
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   528
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   529
        inkpath = get_inkscape_path()
3052
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   530
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   531
        if inkpath is None:
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   532
            self.FatalError("SVGHMI: inkscape is not installed.")
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   533
2756
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   534
        svgpath = self._getSVGpath()
3032
2f6dfb99d094 SVGHMI: Behave when project path include spaces, and make more understandable error in case of problem extracting geometry with inkscape.
Edouard Tisserant
parents: 2993
diff changeset
   535
        status, result, _err_result = ProcessLogger(self.GetCTRoot().logger,
2f6dfb99d094 SVGHMI: Behave when project path include spaces, and make more understandable error in case of problem extracting geometry with inkscape.
Edouard Tisserant
parents: 2993
diff changeset
   536
                                                     '"' + inkpath + '" -S "' + svgpath + '"',
2756
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   537
                                                     no_stdout=True,
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   538
                                                     no_stderr=True).spin()
3032
2f6dfb99d094 SVGHMI: Behave when project path include spaces, and make more understandable error in case of problem extracting geometry with inkscape.
Edouard Tisserant
parents: 2993
diff changeset
   539
        if status != 0:
3052
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   540
            self.FatalError("SVGHMI: inkscape couldn't extract geometry from given SVG.")
3032
2f6dfb99d094 SVGHMI: Behave when project path include spaces, and make more understandable error in case of problem extracting geometry with inkscape.
Edouard Tisserant
parents: 2993
diff changeset
   541
2756
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   542
        res = []
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   543
        for line in result.split():
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   544
            strippedline = line.strip()
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   545
            attrs = dict(
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   546
                zip(InkscapeGeomColumns, line.strip().split(',')))
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   547
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   548
            res.append(etree.Element("bbox", **attrs))
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   549
3170
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   550
        self.ProgressEnd("inkscape")
2756
f94bc35a023e SVGHMI: added extraction of SVG bounding boxes, obtained from "inkscape -S", and passed to XSLT transform as variable.
Edouard Tisserant
parents: 2753
diff changeset
   551
        return res
2753
9a7e12e96399 SVGHMI: Added XSLT transformation, Makefile to get XSLT from ysl2 (copy of plcopen/Makefile) and a minimal stylesheet to start with.
Edouard Tisserant
parents: 2750
diff changeset
   552
2763
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   553
    def GetHMITree(self):
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   554
        global hmi_tree_root
3170
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   555
        self.ProgressStart("hmitree", "getting HMI tree")
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
   556
        res = [hmi_tree_root.etree(add_hash=True)]
3170
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   557
        self.ProgressEnd("hmitree")
2763
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   558
        return res
ce04d79b8e57 Pass HMITree to SVG transform. It seems it could really help to reduce JS tree binding logic in the end.
Edouard Tisserant
parents: 2762
diff changeset
   559
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   560
    def GetTranslations(self, _context, msgs):
3170
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   561
        self.ProgressStart("i18n", "getting Translations")
3113
18133b90196e SVGHMI: i18n: now loads PO filesand match translation against catalog. Refactored a bit to move i18n related code in i18n.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3112
diff changeset
   562
        messages = EtreeToMessages(msgs)
18133b90196e SVGHMI: i18n: now loads PO filesand match translation against catalog. Refactored a bit to move i18n related code in i18n.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3112
diff changeset
   563
3140
cae53fe54cf2 SVGHMI: i18n: prevent creating messages.pot if no translation
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   564
        if len(messages) == 0:
3170
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   565
            self.ProgressEnd("i18n")
3140
cae53fe54cf2 SVGHMI: i18n: prevent creating messages.pot if no translation
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   566
            return
cae53fe54cf2 SVGHMI: i18n: prevent creating messages.pot if no translation
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   567
3113
18133b90196e SVGHMI: i18n: now loads PO filesand match translation against catalog. Refactored a bit to move i18n related code in i18n.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3112
diff changeset
   568
        SaveCatalog(self._getPOTpath(), messages)
18133b90196e SVGHMI: i18n: now loads PO filesand match translation against catalog. Refactored a bit to move i18n related code in i18n.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3112
diff changeset
   569
18133b90196e SVGHMI: i18n: now loads PO filesand match translation against catalog. Refactored a bit to move i18n related code in i18n.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3112
diff changeset
   570
        translations = ReadTranslations(self.CTNPath())
18133b90196e SVGHMI: i18n: now loads PO filesand match translation against catalog. Refactored a bit to move i18n related code in i18n.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3112
diff changeset
   571
            
18133b90196e SVGHMI: i18n: now loads PO filesand match translation against catalog. Refactored a bit to move i18n related code in i18n.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3112
diff changeset
   572
        langs,translated_messages = MatchTranslations(translations, messages, 
18133b90196e SVGHMI: i18n: now loads PO filesand match translation against catalog. Refactored a bit to move i18n related code in i18n.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3112
diff changeset
   573
            errcallback=self.GetCTRoot().logger.write_warning)
18133b90196e SVGHMI: i18n: now loads PO filesand match translation against catalog. Refactored a bit to move i18n related code in i18n.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3112
diff changeset
   574
3165
2db69e2c5673 SVGHMI: Optimized overlapping geometry (widget ot page belonging) computation. Added human readable messages for progress. Includes updated XSLT.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3160
diff changeset
   575
        ret = TranslationToEtree(langs,translated_messages)
2db69e2c5673 SVGHMI: Optimized overlapping geometry (widget ot page belonging) computation. Added human readable messages for progress. Includes updated XSLT.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3160
diff changeset
   576
3170
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   577
        self.ProgressEnd("i18n")
3165
2db69e2c5673 SVGHMI: Optimized overlapping geometry (widget ot page belonging) computation. Added human readable messages for progress. Includes updated XSLT.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3160
diff changeset
   578
2db69e2c5673 SVGHMI: Optimized overlapping geometry (widget ot page belonging) computation. Added human readable messages for progress. Includes updated XSLT.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3160
diff changeset
   579
        return ret
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   580
3170
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   581
    times_msgs = {}
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   582
    indent = 1
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   583
    def ProgressStart(self, k, m):
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   584
        self.times_msgs[k] = (time.time(), m)
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   585
        self.GetCTRoot().logger.write("    "*self.indent + "Start %s...\n"%m)
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   586
        self.indent = self.indent + 1
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   587
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   588
    def ProgressEnd(self, k):
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   589
        t = time.time()
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   590
        oldt, m = self.times_msgs[k]
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   591
        self.indent = self.indent - 1
aaa203270ab0 SVGHMI: Make build log less redundant, and refactor progress information code a bit, to make it also a bit less redundant.
Edouard Tisserant
parents: 3167
diff changeset
   592
        self.GetCTRoot().logger.write("    "*self.indent + "... finished in %.3fs\n"%(t - oldt))
3156
76c0c0a524c9 SVGHMI: display progress in IDE console while building
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3140
diff changeset
   593
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   594
    def CTNGenerate_C(self, buildpath, locations):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   595
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   596
        location_str = "_".join(map(str, self.GetCurrentLocation()))
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   597
        view_name = self.BaseParams.getName()
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   598
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   599
        svgfile = self._getSVGpath()
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   600
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   601
        res = ([], "", False)
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   602
2812
68ac5bf43525 SVGHMI: various fixes to make SVGHMI behave on more versions of twisted and GCC.
Edouard Tisserant
parents: 2789
diff changeset
   603
        target_fname = "svghmi_"+location_str+".xhtml"
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   604
3180
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   605
        build_path = self._getBuildPath()
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   606
        target_path = os.path.join(build_path, target_fname)
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   607
        hash_path = os.path.join(build_path, "svghmi.md5")
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   608
3156
76c0c0a524c9 SVGHMI: display progress in IDE console while building
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3140
diff changeset
   609
        self.GetCTRoot().logger.write("SVGHMI:\n")
76c0c0a524c9 SVGHMI: display progress in IDE console while building
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3140
diff changeset
   610
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   611
        if os.path.exists(svgfile):
2753
9a7e12e96399 SVGHMI: Added XSLT transformation, Makefile to get XSLT from ysl2 (copy of plcopen/Makefile) and a minimal stylesheet to start with.
Edouard Tisserant
parents: 2750
diff changeset
   612
3180
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   613
            hasher = hashlib.md5()
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   614
            hmi_tree_root._hash(hasher)
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   615
            with open(svgfile, 'rb') as afile:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   616
                while True:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   617
                    buf = afile.read(65536)
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   618
                    if len(buf) > 0:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   619
                        hasher.update(buf)
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   620
                    else:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   621
                        break
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   622
            digest = hasher.hexdigest()
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   623
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   624
            if os.path.exists(hash_path):
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   625
                with open(hash_path, 'rb') as digest_file:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   626
                    last_digest = digest_file.read()
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   627
            else:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   628
                last_digest = None
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   629
            
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   630
            if digest != last_digest:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   631
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   632
                transform = XSLTransform(os.path.join(ScriptDirectory, "gen_index_xhtml.xslt"),
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   633
                              [("GetSVGGeometry", lambda *_ignored:self.GetSVGGeometry()),
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   634
                               ("GetHMITree", lambda *_ignored:self.GetHMITree()),
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   635
                               ("GetTranslations", self.GetTranslations),
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   636
                               ("ProgressStart", lambda _ign,k,m:self.ProgressStart(str(k),str(m))),
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   637
                               ("ProgressEnd", lambda _ign,k:self.ProgressEnd(str(k)))])
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   638
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   639
                self.ProgressStart("svg", "source SVG parsing")
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   640
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   641
                # load svg as a DOM with Etree
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   642
                svgdom = etree.parse(svgfile)
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   643
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   644
                self.ProgressEnd("svg")
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   645
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   646
                # call xslt transform on Inkscape's SVG to generate XHTML
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   647
                try: 
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   648
                    self.ProgressStart("xslt", "XSLT transform")
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   649
                    result = transform.transform(svgdom)  # , profile_run=True)
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   650
                    self.ProgressEnd("xslt")
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   651
                except XSLTApplyError as e:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   652
                    self.FatalError("SVGHMI " + view_name  + ": " + e.message)
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   653
                finally:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   654
                    for entry in transform.get_error_log():
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   655
                        message = "SVGHMI: "+ entry.message + "\n" 
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   656
                        self.GetCTRoot().logger.write_warning(message)
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   657
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   658
                target_file = open(target_path, 'wb')
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   659
                result.write(target_file, encoding="utf-8")
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   660
                target_file.close()
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   661
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   662
                # print(str(result))
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   663
                # print(transform.xslt.error_log)
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   664
                # print(etree.tostring(result.xslt_profile,pretty_print=True))
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   665
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   666
                with open(hash_path, 'wb') as digest_file:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   667
                    digest_file.write(digest)
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   668
            else:
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   669
                self.GetCTRoot().logger.write("    No changes - XSLT transformation skipped\n")
2753
9a7e12e96399 SVGHMI: Added XSLT transformation, Makefile to get XSLT from ysl2 (copy of plcopen/Makefile) and a minimal stylesheet to start with.
Edouard Tisserant
parents: 2750
diff changeset
   670
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   671
        else:
3180
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   672
            target_file = open(target_path, 'wb')
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   673
            target_file.write("""<!DOCTYPE html>
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   674
<html>
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   675
<body>
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   676
<h1> No SVG file provided </h1>
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   677
</body>
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   678
</html>
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   679
""")
3180
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   680
            target_file.close()
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   681
2772
3f1dd8312710 SVGHMI: few fixes on serving
Edouard Tisserant
parents: 2771
diff changeset
   682
        res += ((target_fname, open(target_path, "rb")),)
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   683
2823
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   684
        svghmi_cmds = {}
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   685
        for thing in ["Start", "Stop", "Watchdog"]:
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   686
             given_command = self.GetParamsAttributes("SVGHMI.On"+thing)["value"]
2824
074f43e6e114 SVGHMI : Added python fomating {port} and {name} to commands so that command can build target URL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2823
diff changeset
   687
             svghmi_cmds[thing] = (
074f43e6e114 SVGHMI : Added python fomating {port} and {name} to commands so that command can build target URL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2823
diff changeset
   688
                "Popen(" +
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   689
                repr(shlex.split(given_command.format(port="8008", name=view_name))) +
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2831
diff changeset
   690
                ")") if given_command else "pass # no command given"
2772
3f1dd8312710 SVGHMI: few fixes on serving
Edouard Tisserant
parents: 2771
diff changeset
   691
2993
b76f303ffce6 Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents: 2984
diff changeset
   692
        runtimefile_path = os.path.join(buildpath, "runtime_%s_svghmi_.py" % location_str)
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   693
        runtimefile = open(runtimefile_path, 'w')
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   694
        runtimefile.write("""
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   695
# TODO : multiple watchdog (one for each svghmi instance)
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   696
def svghmi_watchdog_trigger():
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   697
    {svghmi_cmds[Watchdog]}
2824
074f43e6e114 SVGHMI : Added python fomating {port} and {name} to commands so that command can build target URL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2823
diff changeset
   698
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   699
svghmi_watchdog = None
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   700
2993
b76f303ffce6 Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents: 2984
diff changeset
   701
def _runtime_{location}_svghmi_start():
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   702
    global svghmi_watchdog
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   703
    svghmi_root.putChild(
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   704
        '{view_name}',
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   705
        NoCacheFile('{xhtml}',
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   706
        defaultType='application/xhtml+xml'))
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   707
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   708
    {svghmi_cmds[Start]}
2824
074f43e6e114 SVGHMI : Added python fomating {port} and {name} to commands so that command can build target URL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2823
diff changeset
   709
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   710
    svghmi_watchdog = Watchdog(
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   711
        {watchdog_initial}, 
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   712
        {watchdog_interval}, 
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   713
        svghmi_watchdog_trigger)
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   714
2993
b76f303ffce6 Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents: 2984
diff changeset
   715
def _runtime_{location}_svghmi_stop():
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   716
    global svghmi_watchdog
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   717
    if svghmi_watchdog is not None:
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   718
        svghmi_watchdog.cancel()
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   719
        svghmi_watchdog = None
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   720
2824
074f43e6e114 SVGHMI : Added python fomating {port} and {name} to commands so that command can build target URL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2823
diff changeset
   721
    svghmi_root.delEntity('{view_name}')
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   722
    {svghmi_cmds[Stop]}
2824
074f43e6e114 SVGHMI : Added python fomating {port} and {name} to commands so that command can build target URL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2823
diff changeset
   723
074f43e6e114 SVGHMI : Added python fomating {port} and {name} to commands so that command can build target URL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2823
diff changeset
   724
        """.format(location=location_str,
074f43e6e114 SVGHMI : Added python fomating {port} and {name} to commands so that command can build target URL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2823
diff changeset
   725
                   xhtml=target_fname,
074f43e6e114 SVGHMI : Added python fomating {port} and {name} to commands so that command can build target URL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2823
diff changeset
   726
                   view_name=view_name,
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   727
                   svghmi_cmds=svghmi_cmds,
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   728
                   watchdog_initial = self.GetParamsAttributes("SVGHMI.WatchdogInitial")["value"],
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   729
                   watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"],
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   730
                   ))
2771
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   731
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   732
        runtimefile.close()
361366b891ca WIP on svghmi, now builds and runs. HTTP serving + WS transport ready, missing actual data to transmit and thread to collect it.
Edouard Tisserant
parents: 2768
diff changeset
   733
2993
b76f303ffce6 Python Runtime: order of execution of extension's init() and cleanup() now reflects order of appearance of extensions in configuration tree.
Edouard Tisserant
parents: 2984
diff changeset
   734
        res += (("runtime_%s_svghmi.py" % location_str, open(runtimefile_path, "rb")),)
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   735
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   736
        return res
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   737
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   738
    def _ImportSVG(self):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   739
        dialog = wx.FileDialog(self.GetCTRoot().AppFrame, _("Choose a SVG file"), os.getcwd(), "",  _("SVG files (*.svg)|*.svg|All files|*.*"), wx.OPEN)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   740
        if dialog.ShowModal() == wx.ID_OK:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   741
            svgpath = dialog.GetPath()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   742
            if os.path.isfile(svgpath):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   743
                shutil.copy(svgpath, self._getSVGpath())
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   744
            else:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   745
                self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n") % svgpath)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   746
        dialog.Destroy()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   747
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   748
    def _StartInkscape(self):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   749
        svgfile = self._getSVGpath()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   750
        open_inkscape = True
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   751
        if not self.GetCTRoot().CheckProjectPathPerm():
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   752
            dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   753
                                      _("You don't have write permissions.\nOpen Inkscape anyway ?"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   754
                                      _("Open Inkscape"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   755
                                      wx.YES_NO | wx.ICON_QUESTION)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   756
            open_inkscape = dialog.ShowModal() == wx.ID_YES
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   757
            dialog.Destroy()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   758
        if open_inkscape:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   759
            if not os.path.isfile(svgfile):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   760
                svgfile = None
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   761
            open_svg(svgfile)
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   762
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   763
    def _StartPOEdit(self, POFile):
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   764
        open_poedit = True
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   765
        if not self.GetCTRoot().CheckProjectPathPerm():
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   766
            dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   767
                                      _("You don't have write permissions.\nOpen POEdit anyway ?"),
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   768
                                      _("Open POEdit"),
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   769
                                      wx.YES_NO | wx.ICON_QUESTION)
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   770
            open_poedit = dialog.ShowModal() == wx.ID_YES
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   771
            dialog.Destroy()
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   772
        if open_poedit:
3112
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   773
            open_pofile(POFile)
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   774
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   775
    def _EditPO(self):
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   776
        """ Select a specific translation and edit it with POEdit """
3112
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   777
        project_path = self.CTNPath()
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   778
        dialog = wx.FileDialog(self.GetCTRoot().AppFrame, _("Choose a PO file"), project_path, "",  _("PO files (*.po)|*.po"), wx.OPEN)
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   779
        if dialog.ShowModal() == wx.ID_OK:
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   780
            POFile = dialog.GetPath()
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   781
            if os.path.isfile(POFile):
3113
18133b90196e SVGHMI: i18n: now loads PO filesand match translation against catalog. Refactored a bit to move i18n related code in i18n.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3112
diff changeset
   782
                if os.path.relpath(POFile, project_path) == os.path.basename(POFile):
3112
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   783
                    self._StartPOEdit(POFile)
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   784
                else:
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   785
                    self.GetCTRoot().logger.write_error(_("PO file misplaced: %s is not in %s\n") % (POFile,project_path))
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   786
            else:
3158
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   787
                self.GetCTRoot().logger.write_error(_("PO file does not exist: %s\n") % POFile)
3112
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   788
        dialog.Destroy()
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   789
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   790
    def _OpenPOT(self):
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   791
        """ Start POEdit with untouched empty catalog """
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   792
        POFile = self._getPOTpath()
3158
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   793
        if os.path.isfile(POFile):
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   794
            self._StartPOEdit(POFile)
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   795
        else:
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   796
            self.GetCTRoot().logger.write_error(_("POT file does not exist, add translatable text (label starting with '_') in Inkscape first\n"))
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   797
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   798
    def CTNGlobalInstances(self):
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   799
        # view_name = self.BaseParams.getName()
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   800
        # return [ (view_name + "_" + name, iec_type, "") for name, iec_type in SPECIAL_NODES]
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   801
        # TODO : move to library level for multiple hmi
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   802
        return [(name, iec_type, "") for name, iec_type in SPECIAL_NODES]
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2818
diff changeset
   803
3159
1d7c3d13a4df SVGHMI: Add icons
Edouard Tisserant
parents: 3158
diff changeset
   804
    def GetIconName(self):
1d7c3d13a4df SVGHMI: Add icons
Edouard Tisserant
parents: 3158
diff changeset
   805
        return "SVGHMI"