svghmi/svghmi.py
author Edouard Tisserant <edouard.tisserant@gmail.com>
Tue, 17 May 2022 13:22:20 +0200
changeset 3465 2f5b5c14a650
parent 3405 fdc12f7d27c8
child 3481 563996733dba
permissions -rw-r--r--
Tests: No need to archive test results before uploading them as action artifacts.
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
3197
0f41c1e2c121 SVGHMI: split svghmi.py into hmi_tree.py + svghmi.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3193
diff changeset
     5
# Copyright (C) 2021: Edouard TISSERANT
2745
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
2789
ba0dd2ec6dc4 SVGHMI: now built.
Edouard Tisserant
parents: 2788
diff changeset
    12
import hashlib
2823
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
    13
import shlex
3156
76c0c0a524c9 SVGHMI: display progress in IDE console while building
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3140
diff changeset
    14
import time
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    15
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    16
import wx
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    17
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    18
from lxml import etree
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    19
from lxml.etree import XSLTApplyError
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    20
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    21
import util.paths as paths
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    22
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
    23
from docutil import open_svg, get_inkscape_path
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    24
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
    25
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
    26
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
    27
import targets
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    28
from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    29
from XSLTransform import XSLTransform
3201
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
    30
from svghmi.i18n import EtreeToMessages, SaveCatalog, ReadTranslations,\
3214
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
    31
                        MatchTranslations, TranslationToEtree, open_pofile,\
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
    32
                        GetPoFiles
3197
0f41c1e2c121 SVGHMI: split svghmi.py into hmi_tree.py + svghmi.py
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3193
diff changeset
    33
from svghmi.hmi_tree import HMI_TYPES, HMITreeNode, SPECIAL_NODES 
3201
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
    34
from svghmi.ui import SVGHMI_UI
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
    35
from svghmi.fonts import GetFontTypeAndFamilyName, GetCSSFontFaceFromFontFile
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    36
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
    37
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
    38
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
    39
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2781
diff changeset
    40
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
    41
# 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
    42
# so that CTN can use HMITree deduced in Library
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
    43
# 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
    44
#       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
    45
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
    46
hmi_tree_root = None
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    47
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
    48
on_hmitree_update = None
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
    49
3270
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
    50
maxConnectionsTotal = 0
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
    51
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    52
class SVGHMILibrary(POULibrary):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    53
    def GetLibraryPath(self):
2750
2694170cd88e intermediate commit, work in progress
Edouard Tisserant
parents: 2749
diff changeset
    54
         return paths.AbsNeighbourFile(__file__, "pous.xml")
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    55
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    56
    def Generate_C(self, buildpath, varlist, IECCFLAGS):
3270
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
    57
        global hmi_tree_root, on_hmitree_update, maxConnectionsTotal
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    58
3341
dce1d5413310 SVGHMI: force MaxConnections sum back to zero, preventing it to grow indefinitely on each build.
Edouard Tisserant
parents: 3290
diff changeset
    59
        maxConnectionsTotal = 0
dce1d5413310 SVGHMI: force MaxConnections sum back to zero, preventing it to grow indefinitely on each build.
Edouard Tisserant
parents: 3290
diff changeset
    60
3287
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    61
        already_found_watchdog = False
3290
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
    62
        found_SVGHMI_instance = False
3287
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    63
        for CTNChild in self.GetCTR().IterChildren():
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    64
            if isinstance(CTNChild, SVGHMI):
3290
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
    65
                found_SVGHMI_instance = True
3287
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    66
                # collect maximum connection total for all svghmi nodes
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    67
                maxConnectionsTotal += CTNChild.GetParamsAttributes("SVGHMI.MaxConnections")["value"]
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    68
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    69
                # spot watchdog abuse
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    70
                if CTNChild.GetParamsAttributes("SVGHMI.EnableWatchdog")["value"]:
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    71
                    if already_found_watchdog:
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    72
                        self.FatalError("SVGHMI: Only one watchdog enabled HMI allowed")
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    73
                    already_found_watchdog = True
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    74
3290
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
    75
        if not found_SVGHMI_instance:
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
    76
            self.FatalError("SVGHMI : Library is selected but not used. Please either deselect it in project config or add a SVGHMI node to project.")
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
    77
3287
70a76083c59c SVGHMI: detect watchdog abuse (more than one HMI instance with watchdog) at build time
Edouard Tisserant
parents: 3286
diff changeset
    78
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    79
        """
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    80
        PLC Instance Tree:
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    81
          prog0
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    82
           +->v1 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    83
           +->v2 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    84
           +->fb0 (type mhoo)
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
    85
           |   +->va HMI_NODE
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    86
           |   +->v3 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    87
           |   +->v4 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    88
           |
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    89
           +->fb1 (type mhoo)
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
    90
           |   +->va HMI_NODE
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    91
           |   +->v3 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    92
           |   +->v4 HMI_INT
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    93
           |
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    94
           +->fb2
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    95
               +->v5 HMI_IN
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    96
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    97
        HMI tree:
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    98
          hmi0
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
    99
           +->v1
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   100
           +->v2
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   101
           +->fb0 class:va
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   102
           |   +-> v3
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   103
           |   +-> v4
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   104
           |
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   105
           +->fb1 class:va
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   106
           |   +-> v3
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   107
           |   +-> v4
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   108
           |
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   109
           +->v5
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   110
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   111
        """
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   112
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   113
        # Filter known HMI types
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   114
        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
   115
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
   116
        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
   117
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
   118
        # 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
   119
        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
   120
            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
   121
            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
   122
            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
   123
                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
   124
                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
   125
                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
   126
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   127
        # 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
   128
        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
   129
            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
   130
            # 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
   131
            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
   132
                continue
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   133
            vartype = v["vartype"]
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   134
            # ignores external variables
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   135
            if vartype == "EXT":
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   136
                continue
2814
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   137
            derived = v["derived"]
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   138
            kwargs={}
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   139
            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
   140
                # 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
   141
                name = path[-2]
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   142
                kwargs['hmiclass'] = path[-1]
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   143
            else:
2cabc4773885 SVGHMI: HMI_LABEL and HMI_CLASS become HMI_NODE.
Edouard Tisserant
parents: 2812
diff changeset
   144
                name = path[-1]
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   145
            new_node = HMITreeNode(path, name, derived, v["type"], 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
   146
            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
   147
            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
   148
                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
   149
                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
   150
                    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
   151
                        ".".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
   152
                        ".".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
   153
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
   154
                    last_FB = None 
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   155
                    for _v in varlist:
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   156
                        if _v["vartype"] == "FB":
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   157
                            last_FB = _v 
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   158
                        if _v["C_path"] == problematic_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
   159
                            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
   160
                    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
   161
                        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
   162
                        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
   163
                        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
   164
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
   165
                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
   166
                    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
   167
                    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
   168
                        ".".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
   169
                        ".".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
   170
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
   171
                self.FatalError("SVGHMI : " + message)
2757
c901baa36bb3 SVGHMI: added deduction of HMI tree from list of HMI_* instances.
Edouard Tisserant
parents: 2756
diff changeset
   172
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   173
        if on_hmitree_update is not None:
3201
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   174
            on_hmitree_update(hmi_tree_root)
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   175
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
   176
        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
   177
        extern_variables_declarations = []
2765
887aba5ef178 SVGHMI: svghmi.c now has mutex, iterator, and read/write buffer.
Edouard Tisserant
parents: 2764
diff changeset
   178
        buf_index = 0
2775
3b93409ba22c SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents: 2772
diff changeset
   179
        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
   180
        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
   181
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
        hearbeat_IEC_path = ['CONFIG', 'HEARTBEAT']
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   183
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
   184
        for node in hmi_tree_root.traverse():
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   185
            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
   186
                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
   187
                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
   188
                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
   189
                    "#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
   190
                ]
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
   191
            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
   192
                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
   193
                variable_decl_array += [
3399
95e0b926a8c3 SVGHMI: optimization of C part : stop traversing the whole HMI tree, use dual linked list for subscriptions and single linked list for changes from HMI. Intermediate commit, still crashing in some cases.
Edouard Tisserant
parents: 3381
diff changeset
   194
                    "HMITREE_ITEM_INITIALIZER(" + 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
   195
                        "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
   196
                        "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
   197
                        "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
   198
                        "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
   199
                        "VAR": "_ENUM"
2765
887aba5ef178 SVGHMI: svghmi.c now has mutex, iterator, and read/write buffer.
Edouard Tisserant
parents: 2764
diff changeset
   200
                    }[node.vartype] + ", " +
3399
95e0b926a8c3 SVGHMI: optimization of C part : stop traversing the whole HMI tree, use dual linked list for subscriptions and single linked list for changes from HMI. Intermediate commit, still crashing in some cases.
Edouard Tisserant
parents: 3381
diff changeset
   201
                    str(buf_index) + ")"]
2765
887aba5ef178 SVGHMI: svghmi.c now has mutex, iterator, and read/write buffer.
Edouard Tisserant
parents: 2764
diff changeset
   202
                buf_index += sz
2775
3b93409ba22c SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents: 2772
diff changeset
   203
                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
   204
                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
   205
                    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
   206
                        "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
   207
                        "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
   208
                        + node.cpath + ";"]
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   209
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
   210
        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
   211
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   212
        # TODO : filter only requiered external declarations
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   213
        for v in varlist:
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   214
            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
   215
                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
   216
                    "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
   217
b75cc2cf4e50 SVGHMI: draft for svghmi.c. It has all PLC variables pointed in HMI tree in an array.
Edouard Tisserant
parents: 2763
diff changeset
   218
        # 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
   219
        # "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
   220
        #                                     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
   221
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
   222
        # 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
   223
        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
   224
        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
   225
        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
   226
        svghmi_c_file.close()
2817
45bbfb2e120f Non significant changes, whitespaces, etc.
Edouard Tisserant
parents: 2816
diff changeset
   227
        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
   228
            "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
   229
            "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
   230
            "buffer_size": buf_index,
2775
3b93409ba22c SVGHMI: WIP for python<->C data exchange
Edouard Tisserant
parents: 2772
diff changeset
   231
            "item_count": item_count,
2768
31785529a657 SVGHMI: Intermediate state while working on svghmi.c
Edouard Tisserant
parents: 2767
diff changeset
   232
            "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
   233
            "PLC_ticktime": self.GetCTR().GetTicktime(),
3270
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   234
            "hmi_hash_ints": ",".join(map(str,hmi_tree_root.hash())),
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   235
            "max_connections": maxConnectionsTotal
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
   236
            }
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   237
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   238
        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
   239
        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
   240
        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
   241
        gen_svghmi_c.close()
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   242
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
   243
        # 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
   244
        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
   245
        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
   246
        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
   247
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
   248
        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
   249
        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
   250
        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
   251
        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
   252
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
   253
        # 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
   254
        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
   255
        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
   256
        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
   257
        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
   258
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
   259
        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
   260
                ("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
   261
                #         ^
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
   262
                # 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
   263
                # to ensure placement before other CTN generated code in execution order
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   264
3267
5f20f391ae31 SVGHMI: Prepare accepting multiple clients on multiple HMI: Use POULibrary new capability to add variables to PLC Configuration. Now heartbeat and HMI tree root are added by the library part of SVGHMI, and not by each instance.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3218
diff changeset
   265
    def GlobalInstances(self):
5f20f391ae31 SVGHMI: Prepare accepting multiple clients on multiple HMI: Use POULibrary new capability to add variables to PLC Configuration. Now heartbeat and HMI tree root are added by the library part of SVGHMI, and not by each instance.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3218
diff changeset
   266
        """ Adds HMI tree root and hearbeat to PLC Configuration's globals """
5f20f391ae31 SVGHMI: Prepare accepting multiple clients on multiple HMI: Use POULibrary new capability to add variables to PLC Configuration. Now heartbeat and HMI tree root are added by the library part of SVGHMI, and not by each instance.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3218
diff changeset
   267
        return [(name, iec_type, "") for name, iec_type in SPECIAL_NODES]
5f20f391ae31 SVGHMI: Prepare accepting multiple clients on multiple HMI: Use POULibrary new capability to add variables to PLC Configuration. Now heartbeat and HMI tree root are added by the library part of SVGHMI, and not by each instance.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3218
diff changeset
   268
5f20f391ae31 SVGHMI: Prepare accepting multiple clients on multiple HMI: Use POULibrary new capability to add variables to PLC Configuration. Now heartbeat and HMI tree root are added by the library part of SVGHMI, and not by each instance.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3218
diff changeset
   269
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   270
3201
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   271
def Register_SVGHMI_UI_for_HMI_tree_updates(ref):
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   272
    global on_hmitree_update
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   273
    def HMITreeUpdate(_hmi_tree_root):
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   274
        obj = ref()
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   275
        if obj is not None:
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   276
            obj.HMITreeUpdate(_hmi_tree_root)
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   277
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   278
    on_hmitree_update = HMITreeUpdate
2818
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   279
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   280
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   281
class SVGHMIEditor(ConfTreeNodeEditor):
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   282
    CONFNODEEDITOR_TABS = [
3201
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   283
        (_("HMI Tree"), "CreateSVGHMI_UI")]
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   284
6dadc1690284 SVGHMI: split svghmi.py into svghmi.py (Config Tree Node + code gen) and ui.py (UI for HMI tree and Widget picking)
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3197
diff changeset
   285
    def CreateSVGHMI_UI(self, parent):
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
   286
        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
   287
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
   288
        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
   289
            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
   290
            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
   291
            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
   292
                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
   293
                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
   294
3208
b5330d76e225 SVGHMI: Fix update of HMI tree in UI when loading from XML at start. Removed some dead code left after split of svghmi.py into svghmi.py+ui.py.
Edouard Tisserant
parents: 3201
diff changeset
   295
        ret = SVGHMI_UI(parent, Register_SVGHMI_UI_for_HMI_tree_updates)
b5330d76e225 SVGHMI: Fix update of HMI tree in UI when loading from XML at start. Removed some dead code left after split of svghmi.py into svghmi.py+ui.py.
Edouard Tisserant
parents: 3201
diff changeset
   296
b5330d76e225 SVGHMI: Fix update of HMI tree in UI when loading from XML at start. Removed some dead code left after split of svghmi.py into svghmi.py+ui.py.
Edouard Tisserant
parents: 3201
diff changeset
   297
        on_hmitree_update(hmi_tree_root)
b5330d76e225 SVGHMI: Fix update of HMI tree in UI when loading from XML at start. Removed some dead code left after split of svghmi.py into svghmi.py+ui.py.
Edouard Tisserant
parents: 3201
diff changeset
   298
b5330d76e225 SVGHMI: Fix update of HMI tree in UI when loading from XML at start. Removed some dead code left after split of svghmi.py into svghmi.py+ui.py.
Edouard Tisserant
parents: 3201
diff changeset
   299
        return ret
2818
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   300
3348
cfac764413dd IDE/windows: Avoid exception on quit caused by runtime being killed without disconnecting.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3341
diff changeset
   301
if wx.Platform == '__WXMSW__':
cfac764413dd IDE/windows: Avoid exception on quit caused by runtime being killed without disconnecting.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3341
diff changeset
   302
    browser_launch_cmd="cmd.exe /c 'start msedge {url}'"
cfac764413dd IDE/windows: Avoid exception on quit caused by runtime being killed without disconnecting.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3341
diff changeset
   303
else:
cfac764413dd IDE/windows: Avoid exception on quit caused by runtime being killed without disconnecting.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3341
diff changeset
   304
    browser_launch_cmd="chromium {url}"
cfac764413dd IDE/windows: Avoid exception on quit caused by runtime being killed without disconnecting.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3341
diff changeset
   305
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   306
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
   307
    XSD = """<?xml version="1.0" encoding="utf-8" ?>
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   308
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   309
      <xsd:element name="SVGHMI">
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   310
        <xsd:complexType>
3348
cfac764413dd IDE/windows: Avoid exception on quit caused by runtime being killed without disconnecting.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3341
diff changeset
   311
          <xsd:attribute name="OnStart" type="xsd:string" use="optional" default="%s"/>
cfac764413dd IDE/windows: Avoid exception on quit caused by runtime being killed without disconnecting.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3341
diff changeset
   312
          <xsd:attribute name="OnStop" type="xsd:string" use="optional" default=""/>
cfac764413dd IDE/windows: Avoid exception on quit caused by runtime being killed without disconnecting.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3341
diff changeset
   313
          <xsd:attribute name="OnWatchdog" type="xsd:string" use="optional" default=""/>
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   314
          <xsd:attribute name="EnableWatchdog" type="xsd:boolean" use="optional" default="false"/>
3277
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   315
          <xsd:attribute name="WatchdogInitial" use="optional" default="30">
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   316
            <xsd:simpleType>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   317
                <xsd:restriction base="xsd:integer">
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   318
                    <xsd:minInclusive value="2"/>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   319
                    <xsd:maxInclusive value="600"/>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   320
                </xsd:restriction>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   321
            </xsd:simpleType>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   322
          </xsd:attribute>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   323
          <xsd:attribute name="WatchdogInterval" use="optional" default="5">
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   324
            <xsd:simpleType>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   325
                <xsd:restriction base="xsd:integer">
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   326
                    <xsd:minInclusive value="2"/>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   327
                    <xsd:maxInclusive value="60"/>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   328
                </xsd:restriction>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   329
            </xsd:simpleType>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   330
          </xsd:attribute>
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   331
          <xsd:attribute name="Port" type="xsd:integer" use="optional" default="8008"/>
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   332
          <xsd:attribute name="Interface" type="xsd:string" use="optional" default="localhost"/>
3270
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   333
          <xsd:attribute name="Path" type="xsd:string" use="optional" default="{name}"/>
3277
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   334
          <xsd:attribute name="MaxConnections" use="optional" default="16">
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   335
            <xsd:simpleType>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   336
                <xsd:restriction base="xsd:integer">
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   337
                    <xsd:minInclusive value="1"/>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   338
                    <xsd:maxInclusive value="1024"/>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   339
                </xsd:restriction>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   340
            </xsd:simpleType>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   341
          </xsd:attribute>
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   342
        </xsd:complexType>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   343
      </xsd:element>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   344
    </xsd:schema>
3348
cfac764413dd IDE/windows: Avoid exception on quit caused by runtime being killed without disconnecting.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3341
diff changeset
   345
    """%browser_launch_cmd
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   346
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   347
    EditorType = SVGHMIEditor
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   348
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   349
    ConfNodeMethods = [
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   350
        {
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   351
            "bitmap":    "ImportSVG",
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   352
            "name":    _("Import SVG"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   353
            "tooltip": _("Import SVG"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   354
            "method":   "_ImportSVG"
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   355
        },
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   356
        {
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   357
            "bitmap":    "EditSVG",
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   358
            "name":    _("Inkscape"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   359
            "tooltip": _("Edit HMI"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   360
            "method":   "_StartInkscape"
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   361
        },
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
   362
        {
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   363
            "bitmap":    "OpenPOT",
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
   364
            "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
   365
            "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
   366
            "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
   367
        },
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
   368
        {
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   369
            "bitmap":    "EditPO",
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
   370
            "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
   371
            "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
   372
            "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
   373
        },
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   374
        {
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   375
            "bitmap":    "AddFont",
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   376
            "name":    _("Add Font"),
3211
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   377
            "tooltip": _("Add TTF, OTF or WOFF font to be embedded in HMI"),
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   378
            "method":   "_AddFont"
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   379
        },
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   380
        {
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   381
            "bitmap":    "DelFont",
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   382
            "name":    _("Delete Font"),
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   383
            "tooltip": _("Remove font previously added to HMI"),
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   384
            "method":   "_DelFont"
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   385
        },
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   386
    ]
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   387
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   388
    def _getSVGpath(self, project_path=None):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   389
        if project_path is None:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   390
            project_path = self.CTNPath()
2781
fbdd0fd8ee4f SVGHMI: gui.svg -> svghmi.svg
Edouard Tisserant
parents: 2779
diff changeset
   391
        return os.path.join(project_path, "svghmi.svg")
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   392
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   393
    def _getPOTpath(self, project_path=None):
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   394
        if project_path is None:
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   395
            project_path = self.CTNPath()
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   396
        return os.path.join(project_path, "messages.pot")
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   397
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   398
    def OnCTNSave(self, from_project_path=None):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   399
        if from_project_path is not None:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   400
            shutil.copyfile(self._getSVGpath(from_project_path),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   401
                            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
   402
            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
   403
                            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
   404
            # XXX TODO copy .PO files
2750
2694170cd88e intermediate commit, work in progress
Edouard Tisserant
parents: 2749
diff changeset
   405
        return True
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   406
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
   407
    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
   408
        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
   409
        # 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
   410
        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
   411
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
   412
        inkpath = get_inkscape_path()
3052
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   413
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   414
        if inkpath is None:
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   415
            self.FatalError("SVGHMI: inkscape is not installed.")
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   416
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
   417
        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
   418
        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
   419
                                                     '"' + 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
   420
                                                     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
   421
                                                     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
   422
        if status != 0:
3052
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   423
            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
   424
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
   425
        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
   426
        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
   427
            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
   428
            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
   429
                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
   430
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
   431
            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
   432
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
   433
        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
   434
        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
   435
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
   436
    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
   437
        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
   438
        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
   439
        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
   440
        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
   441
        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
   442
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   443
    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
   444
        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
   445
        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
   446
3140
cae53fe54cf2 SVGHMI: i18n: prevent creating messages.pot if no translation
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   447
        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
   448
            self.ProgressEnd("i18n")
3140
cae53fe54cf2 SVGHMI: i18n: prevent creating messages.pot if no translation
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   449
            return
cae53fe54cf2 SVGHMI: i18n: prevent creating messages.pot if no translation
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   450
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
   451
        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
   452
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
   453
        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
   454
            
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
   455
        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
   456
            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
   457
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
   458
        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
   459
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
   460
        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
   461
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
   462
        return ret
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   463
3214
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   464
    def GetFontsFiles(self):
3211
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   465
        project_path = self.CTNPath()
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   466
        fontdir = os.path.join(project_path, "fonts") 
3214
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   467
        if os.path.isdir(fontdir):
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   468
            return [os.path.join(fontdir,f) for f in sorted(os.listdir(fontdir))]
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   469
        return []
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   470
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   471
    def GetFonts(self, _context):
3211
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   472
        css_parts = []
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   473
3214
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   474
        for fontfile in self.GetFontsFiles():
3211
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   475
            if os.path.isfile(fontfile):
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   476
                css_parts.append(GetCSSFontFaceFromFontFile(fontfile))
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   477
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   478
        return "".join(css_parts)
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   479
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
   480
    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
   481
    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
   482
    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
   483
        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
   484
        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
   485
        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
   486
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
   487
    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
   488
        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
   489
        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
   490
        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
   491
        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
   492
3286
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   493
    def get_SVGHMI_options(self):
3290
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
   494
        name = self.BaseParams.getName()
3286
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   495
        port = self.GetParamsAttributes("SVGHMI.Port")["value"]
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   496
        interface = self.GetParamsAttributes("SVGHMI.Interface")["value"]
3290
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
   497
        path = self.GetParamsAttributes("SVGHMI.Path")["value"].format(name=name)
3286
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   498
        if path and path[0]=='/':
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   499
            path = path[1:]
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   500
        enable_watchdog = self.GetParamsAttributes("SVGHMI.EnableWatchdog")["value"]
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   501
        url="http://"+interface+("" if port==80 else (":"+str(port))
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   502
            ) + (("/"+path) if path else ""
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   503
            ) + ("#watchdog" if enable_watchdog else "")
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   504
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   505
        return dict(
3290
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
   506
            name=name,
3286
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   507
            port=port,
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   508
            interface=interface,
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   509
            path=path,
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   510
            enable_watchdog=enable_watchdog,
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   511
            url=url)
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   512
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   513
    def CTNGenerate_C(self, buildpath, locations):
3290
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
   514
        global hmi_tree_root
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
   515
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
   516
        if hmi_tree_root is None:
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
   517
            self.FatalError("SVGHMI : Library is not selected. Please select it in project config.")
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   518
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
   519
        location_str = "_".join(map(str, self.GetCurrentLocation()))
3286
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   520
        svghmi_options = self.get_SVGHMI_options()
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
   521
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   522
        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
   523
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
   524
        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
   525
2812
68ac5bf43525 SVGHMI: various fixes to make SVGHMI behave on more versions of twisted and GCC.
Edouard Tisserant
parents: 2789
diff changeset
   526
        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
   527
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
   528
        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
   529
        target_path = os.path.join(build_path, target_fname)
3375
aa25c89a8845 SVGHMI: prevent systematic rebuild when there are multiple instances of SVGHMI CTN.
Edouard Tisserant
parents: 3372
diff changeset
   530
        hash_path = os.path.join(build_path, "svghmi_"+location_str+".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
   531
3156
76c0c0a524c9 SVGHMI: display progress in IDE console while building
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3140
diff changeset
   532
        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
   533
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   534
        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
   535
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
   536
            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
   537
            hmi_tree_root._hash(hasher)
3218
76f1cd1291f4 SVGHMI: Fixed last i18n changes meant to allow checking changes in PO files. Was making build exception when no PO files available.
Edouard Tisserant
parents: 3214
diff changeset
   538
            pofiles = GetPoFiles(self.CTNPath())
3214
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   539
            filestocheck = [svgfile] + \
3218
76f1cd1291f4 SVGHMI: Fixed last i18n changes meant to allow checking changes in PO files. Was making build exception when no PO files available.
Edouard Tisserant
parents: 3214
diff changeset
   540
                           (list(zip(*pofiles)[1]) if pofiles else []) + \
3214
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   541
                           self.GetFontsFiles()
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   542
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   543
            for filetocheck in filestocheck:
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   544
                with open(filetocheck, 'rb') as afile:
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   545
                    while True:
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   546
                        buf = afile.read(65536)
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   547
                        if len(buf) > 0:
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   548
                            hasher.update(buf)
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   549
                        else:
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   550
                            break
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
   551
            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
   552
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
   553
            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
   554
                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
   555
                    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
   556
            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
   557
                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
   558
            
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
   559
            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
   560
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
   561
                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
   562
                              [("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
   563
                               ("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
   564
                               ("GetTranslations", self.GetTranslations),
3211
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   565
                               ("GetFonts", self.GetFonts),
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
   566
                               ("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
   567
                               ("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
   568
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
   569
                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
   570
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
   571
                # 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
   572
                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
   573
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
   574
                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
   575
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
   576
                # 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
   577
                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
   578
                    self.ProgressStart("xslt", "XSLT transform")
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   579
                    result = transform.transform(
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   580
                        svgdom, instance_name=location_str)  # , profile_run=True)
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
   581
                    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
   582
                except XSLTApplyError as e:
3290
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
   583
                    self.FatalError("SVGHMI " + svghmi_options["name"] + ": " + e.message)
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
   584
                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
   585
                    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
   586
                        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
   587
                        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
   588
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
   589
                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
   590
                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
   591
                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
   592
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
   593
                # 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
   594
                # 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
   595
                # 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
   596
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
   597
                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
   598
                    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
   599
            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
   600
                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
   601
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   602
        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
   603
            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
   604
            target_file.write("""<!DOCTYPE html>
3274
16066300b254 SVGHMI: default library path, default page when starting a SVGHMI project, error page when no SVG present
Edouard Tisserant
parents: 3270
diff changeset
   605
<html xmlns="http://www.w3.org/1999/xhtml">
16066300b254 SVGHMI: default library path, default page when starting a SVGHMI project, error page when no SVG present
Edouard Tisserant
parents: 3270
diff changeset
   606
<head>
16066300b254 SVGHMI: default library path, default page when starting a SVGHMI project, error page when no SVG present
Edouard Tisserant
parents: 3270
diff changeset
   607
<title>SVGHMI</title>
16066300b254 SVGHMI: default library path, default page when starting a SVGHMI project, error page when no SVG present
Edouard Tisserant
parents: 3270
diff changeset
   608
</head>
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
   609
<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
   610
<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
   611
</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
   612
</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
   613
""")
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
   614
            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
   615
3372
e5cb7447320c SVGHMI: prevents watchdog being triggered when SVGHMI is empty.
Edouard Tisserant
parents: 3348
diff changeset
   616
            # In case no SVG is given, watchdog is useless
e5cb7447320c SVGHMI: prevents watchdog being triggered when SVGHMI is empty.
Edouard Tisserant
parents: 3348
diff changeset
   617
            svghmi_options["enable_watchdog"] = False
e5cb7447320c SVGHMI: prevents watchdog being triggered when SVGHMI is empty.
Edouard Tisserant
parents: 3348
diff changeset
   618
2772
3f1dd8312710 SVGHMI: few fixes on serving
Edouard Tisserant
parents: 2771
diff changeset
   619
        res += ((target_fname, open(target_path, "rb")),)
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   620
2823
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   621
        svghmi_cmds = {}
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   622
        for thing in ["Start", "Stop", "Watchdog"]:
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   623
             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
   624
             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
   625
                "Popen(" +
3286
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   626
                repr(shlex.split(given_command.format(**svghmi_options))) +
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
   627
                ")") if given_command else "pass # no command given"
2772
3f1dd8312710 SVGHMI: few fixes on serving
Edouard Tisserant
parents: 2771
diff changeset
   628
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
   629
        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
   630
        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
   631
        runtimefile.write("""
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   632
# TODO : multiple watchdog (one for each svghmi instance)
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   633
def svghmi_{location}_watchdog_trigger():
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   634
    {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
   635
3270
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   636
max_svghmi_sessions = {maxConnections_total}
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   637
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
   638
def _runtime_{location}_svghmi_start():
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   639
    global svghmi_watchdog, svghmi_servers
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   640
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   641
    srv = svghmi_servers.get("{interface}:{port}", None)
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   642
    if srv is not None:
3270
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   643
        svghmi_root, svghmi_listener, path_list = srv
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   644
        if '{path}' in path_list:
3290
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
   645
            raise Exception("SVGHMI {name}: path {path} already used on {interface}:{port}")
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   646
    else:
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   647
        svghmi_root = Resource()
3270
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   648
        factory = HMIWebSocketServerFactory()
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   649
        factory.setProtocolOptions(maxConnections={maxConnections})
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   650
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   651
        svghmi_root.putChild("ws", WebSocketResource(factory))
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   652
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   653
        svghmi_listener = reactor.listenTCP({port}, Site(svghmi_root), interface='{interface}')
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   654
        path_list = []
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   655
        svghmi_servers["{interface}:{port}"] = (svghmi_root, svghmi_listener, path_list)
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   656
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   657
    svghmi_root.putChild(
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   658
        '{path}',
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   659
        NoCacheFile('{xhtml}',
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   660
            defaultType='application/xhtml+xml'))
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   661
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   662
    path_list.append("{path}")
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   663
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   664
    {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
   665
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   666
    if {enable_watchdog}:
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   667
        if svghmi_watchdog is None:
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   668
            svghmi_watchdog = Watchdog(
3270
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   669
                {watchdog_initial},
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   670
                {watchdog_interval},
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   671
                svghmi_{location}_watchdog_trigger)
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   672
        else:
3290
f0c97422b34a SVGHMI: Fix detection of library without instance and instances without library. Added one more widget in the widget library. Renamed "view_name" in "name" in commands substitutions.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3289
diff changeset
   673
            raise Exception("SVGHMI {name}: only one watchdog allowed")
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   674
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   675
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
   676
def _runtime_{location}_svghmi_stop():
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   677
    global svghmi_watchdog, svghmi_servers
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   678
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   679
    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
   680
        svghmi_watchdog.cancel()
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   681
        svghmi_watchdog = None
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   682
3269
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   683
    svghmi_root, svghmi_listener, path_list = svghmi_servers["{interface}:{port}"]
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   684
    svghmi_root.delEntity('{path}')
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   685
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   686
    path_list.remove('{path}')
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   687
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   688
    if len(path_list)==0:
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   689
        svghmi_root.delEntity("ws")
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   690
        svghmi_listener.stopListening()
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   691
        svghmi_servers.pop("{interface}:{port}")
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   692
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   693
    {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
   694
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
   695
        """.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
   696
                   xhtml=target_fname,
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   697
                   svghmi_cmds=svghmi_cmds,
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   698
                   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
   699
                   watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"],
3270
38f7122ccbf9 SVGHMI: Implemented multiserver+multiclient, but only tested with single client and single server for now. To be continued...
Edouard Tisserant
parents: 3269
diff changeset
   700
                   maxConnections = self.GetParamsAttributes("SVGHMI.MaxConnections")["value"],
3286
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   701
                   maxConnections_total = maxConnectionsTotal,
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   702
                   **svghmi_options
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   703
        ))
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
   704
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
   705
        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
   706
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
   707
        res += (("runtime_%s_svghmi.py" % location_str, open(runtimefile_path, "rb")),)
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   708
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   709
        return res
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   710
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   711
    def _ImportSVG(self):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   712
        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
   713
        if dialog.ShowModal() == wx.ID_OK:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   714
            svgpath = dialog.GetPath()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   715
            if os.path.isfile(svgpath):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   716
                shutil.copy(svgpath, self._getSVGpath())
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   717
            else:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   718
                self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n") % svgpath)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   719
        dialog.Destroy()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   720
3286
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   721
    def getDefaultSVG(self):
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   722
        return os.path.join(ScriptDirectory, "default.svg")
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   723
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   724
    def _StartInkscape(self):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   725
        svgfile = self._getSVGpath()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   726
        open_inkscape = True
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   727
        if not self.GetCTRoot().CheckProjectPathPerm():
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   728
            dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   729
                                      _("You don't have write permissions.\nOpen Inkscape anyway ?"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   730
                                      _("Open Inkscape"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   731
                                      wx.YES_NO | wx.ICON_QUESTION)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   732
            open_inkscape = dialog.ShowModal() == wx.ID_YES
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   733
            dialog.Destroy()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   734
        if open_inkscape:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   735
            if not os.path.isfile(svgfile):
3274
16066300b254 SVGHMI: default library path, default page when starting a SVGHMI project, error page when no SVG present
Edouard Tisserant
parents: 3270
diff changeset
   736
                # make a copy of default svg from source
3286
5a135e635bfa SVGHMI: code refactoring allowing more in depth customization for substitution on start/stop/restart commands, and default SVG choice.
Edouard Tisserant
parents: 3277
diff changeset
   737
                default = self.getDefaultSVG()
3274
16066300b254 SVGHMI: default library path, default page when starting a SVGHMI project, error page when no SVG present
Edouard Tisserant
parents: 3270
diff changeset
   738
                shutil.copyfile(default, svgfile)
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   739
            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
   740
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   741
    def _StartPOEdit(self, POFile):
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   742
        open_poedit = True
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   743
        if not self.GetCTRoot().CheckProjectPathPerm():
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   744
            dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   745
                                      _("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
   746
                                      _("Open POEdit"),
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   747
                                      wx.YES_NO | wx.ICON_QUESTION)
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   748
            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
   749
            dialog.Destroy()
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   750
        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
   751
            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
   752
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
   753
    def _EditPO(self):
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   754
        """ 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
   755
        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
   756
        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
   757
        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
   758
            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
   759
            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
   760
                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
   761
                    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
   762
                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
   763
                    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
   764
            else:
3158
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   765
                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
   766
        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
   767
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
   768
    def _OpenPOT(self):
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   769
        """ Start POEdit with untouched empty catalog """
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   770
        POFile = self._getPOTpath()
3158
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   771
        if os.path.isfile(POFile):
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   772
            self._StartPOEdit(POFile)
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   773
        else:
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   774
            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
   775
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   776
    def _AddFont(self):
3211
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   777
        dialog = wx.FileDialog(
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   778
            self.GetCTRoot().AppFrame,
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   779
            _("Choose a font"),
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   780
            os.path.expanduser("~"),
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   781
            "",
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   782
            _("Font files (*.ttf;*.otf;*.woff;*.woff2)|*.ttf;*.otf;*.woff;*.woff2"), wx.OPEN)
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   783
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   784
        if dialog.ShowModal() == wx.ID_OK:
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   785
            fontfile = dialog.GetPath()
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   786
            if os.path.isfile(fontfile):
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   787
                familyname, uniquename, formatname, mimetype = GetFontTypeAndFamilyName(fontfile)
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   788
            else:
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   789
                self.GetCTRoot().logger.write_error(
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   790
                    _('Selected font %s is not a readable file\n')%fontfile)
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   791
                return
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   792
            if familyname is None or uniquename is None or formatname is None or mimetype is None:
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   793
                self.GetCTRoot().logger.write_error(
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   794
                    _('Selected font file %s is invalid or incompatible\n')%fontfile)
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   795
                return
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   796
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   797
            project_path = self.CTNPath()
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   798
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   799
            fontfname = uniquename + "." + mimetype.split('/')[1]
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   800
            fontdir = os.path.join(project_path, "fonts") 
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   801
            newfontfile = os.path.join(fontdir, fontfname) 
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   802
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   803
            if not os.path.exists(fontdir):
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   804
                os.mkdir(fontdir)
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   805
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   806
            shutil.copyfile(fontfile, newfontfile)
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   807
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   808
            self.GetCTRoot().logger.write(
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   809
                _('Added font %s as %s\n')%(fontfile,newfontfile))
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   810
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   811
    def _DelFont(self):
3211
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   812
        project_path = self.CTNPath()
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   813
        fontdir = os.path.join(project_path, "fonts") 
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   814
        dialog = wx.FileDialog(
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   815
            self.GetCTRoot().AppFrame,
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   816
            _("Choose a font to remove"),
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   817
            fontdir,
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   818
            "",
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   819
            _("Font files (*.ttf;*.otf;*.woff;*.woff2)|*.ttf;*.otf;*.woff;*.woff2"), wx.OPEN)
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   820
        if dialog.ShowModal() == wx.ID_OK:
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   821
            fontfile = dialog.GetPath()
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   822
            if os.path.isfile(fontfile):
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   823
                if os.path.relpath(fontfile, fontdir) == os.path.basename(fontfile):
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   824
                    os.remove(fontfile) 
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   825
                    self.GetCTRoot().logger.write(
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   826
                        _('Removed font %s\n')%fontfile)
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   827
                else:
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   828
                    self.GetCTRoot().logger.write_error(
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   829
                        _("Font to remove %s is not in %s\n") % (fontfile,fontdir))
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   830
            else:
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   831
                self.GetCTRoot().logger.write_error(
938b55abe946 SVGHMI: Implemented "Add Font" and "Remove Font", add font embedding in CSS at build time, tested ok with some OTF for now.
Edouard Tisserant
parents: 3210
diff changeset
   832
                    _("Font file does not exist: %s\n") % fontfile)
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   833
        
3381
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   834
    def CTNGlobalInstances(self):
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   835
        location_str = "_".join(map(str, self.GetCurrentLocation()))
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   836
        return [("CURRENT_PAGE_"+location_str, "HMI_STRING", "")]
3a0908b0319d SVGHMI: add CURRENT_PAGE_{location} global variable to reflect currently visible page. If PLC wites some valid page reference in that variable, it triggers page switch. Additionally, fixed /HEARTBEAT being subscribed systematically by JS code even when wtchdog is not enabled.
Edouard Tisserant
parents: 3375
diff changeset
   837
3267
5f20f391ae31 SVGHMI: Prepare accepting multiple clients on multiple HMI: Use POULibrary new capability to add variables to PLC Configuration. Now heartbeat and HMI tree root are added by the library part of SVGHMI, and not by each instance.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3218
diff changeset
   838
    ## In case one day we support more than one heartbeat
5f20f391ae31 SVGHMI: Prepare accepting multiple clients on multiple HMI: Use POULibrary new capability to add variables to PLC Configuration. Now heartbeat and HMI tree root are added by the library part of SVGHMI, and not by each instance.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3218
diff changeset
   839
    #     view_name = self.BaseParams.getName()
5f20f391ae31 SVGHMI: Prepare accepting multiple clients on multiple HMI: Use POULibrary new capability to add variables to PLC Configuration. Now heartbeat and HMI tree root are added by the library part of SVGHMI, and not by each instance.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3218
diff changeset
   840
    #     return [(view_name + "_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
   841
3159
1d7c3d13a4df SVGHMI: Add icons
Edouard Tisserant
parents: 3158
diff changeset
   842
    def GetIconName(self):
1d7c3d13a4df SVGHMI: Add icons
Edouard Tisserant
parents: 3158
diff changeset
   843
        return "SVGHMI"