svghmi/svghmi.py
author Edouard Tisserant
Fri, 09 Sep 2022 09:45:27 +0200
changeset 3599 0d7c41546854
parent 3499 72ee59ff959c
child 3526 074046800624
child 3647 7c427418396f
permissions -rw-r--r--
SVGHMI: fix ToggleButton not always reflecting current state
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
3499
72ee59ff959c SVGHMI: Adapt to Inkscape 0.92 "-e" replaced by "-o" in 1.2, and workaround access right problem when generating thumbnails.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3498
diff changeset
   285
    def __init__(self, parent, controler, window):
72ee59ff959c SVGHMI: Adapt to Inkscape 0.92 "-e" replaced by "-o" in 1.2, and workaround access right problem when generating thumbnails.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3498
diff changeset
   286
        ConfTreeNodeEditor.__init__(self, parent, controler, window)
72ee59ff959c SVGHMI: Adapt to Inkscape 0.92 "-e" replaced by "-o" in 1.2, and workaround access right problem when generating thumbnails.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3498
diff changeset
   287
        self.Controler = controler
72ee59ff959c SVGHMI: Adapt to Inkscape 0.92 "-e" replaced by "-o" in 1.2, and workaround access right problem when generating thumbnails.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3498
diff changeset
   288
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
   289
    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
   290
        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
   291
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
   292
        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
   293
            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
   294
            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
   295
            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
   296
                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
   297
                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
   298
3499
72ee59ff959c SVGHMI: Adapt to Inkscape 0.92 "-e" replaced by "-o" in 1.2, and workaround access right problem when generating thumbnails.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3498
diff changeset
   299
        ret = SVGHMI_UI(parent, self.Controler, Register_SVGHMI_UI_for_HMI_tree_updates)
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
   300
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
   301
        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
   302
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
   303
        return ret
2818
65f32c94d7ec SVGHMI: re-implemented tree view with classic wxTreeCtl
Edouard Tisserant
parents: 2817
diff changeset
   304
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
   305
if wx.Platform == '__WXMSW__':
3498
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   306
    default_cmds={
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   307
        "launch":"cmd.exe /c 'start msedge {url}'",
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   308
        "watchdog":"cmd.exe /k 'echo watchdog for {url} !'"}
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
   309
else:
3498
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   310
    default_cmds={
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   311
        "launch":"chromium {url}",
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   312
        "watchdog":"echo Watchdog for {name} !"}
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
   313
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   314
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
   315
    XSD = """<?xml version="1.0" encoding="utf-8" ?>
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   316
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   317
      <xsd:element name="SVGHMI">
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   318
        <xsd:complexType>
3498
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   319
          <xsd:attribute name="OnStart" type="xsd:string" use="optional" default="%(launch)s"/>
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
   320
          <xsd:attribute name="OnStop" type="xsd:string" use="optional" default=""/>
3498
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   321
          <xsd:attribute name="OnWatchdog" type="xsd:string" use="optional" default="%(watchdog)s"/>
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
   322
          <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
   323
          <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
   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="600"/>
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>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   331
          <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
   332
            <xsd:simpleType>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   333
                <xsd:restriction base="xsd:integer">
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   334
                    <xsd:minInclusive value="2"/>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   335
                    <xsd:maxInclusive value="60"/>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   336
                </xsd:restriction>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   337
            </xsd:simpleType>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   338
          </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
   339
          <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
   340
          <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
   341
          <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
   342
          <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
   343
            <xsd:simpleType>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   344
                <xsd:restriction base="xsd:integer">
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   345
                    <xsd:minInclusive value="1"/>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   346
                    <xsd:maxInclusive value="1024"/>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   347
                </xsd:restriction>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   348
            </xsd:simpleType>
8e81e4ce9bc6 SVGHMI: set some boundaries for watchdog timings and max connection count.
Edouard Tisserant
parents: 3274
diff changeset
   349
          </xsd:attribute>
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   350
        </xsd:complexType>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   351
      </xsd:element>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   352
    </xsd:schema>
3498
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   353
    """%default_cmds
2816
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   354
d813ecfe8941 SVGHMI: Added simple HMI Tree View.
Edouard Tisserant
parents: 2815
diff changeset
   355
    EditorType = SVGHMIEditor
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   356
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   357
    ConfNodeMethods = [
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   358
        {
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   359
            "bitmap":    "ImportSVG",
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   360
            "name":    _("Import SVG"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   361
            "tooltip": _("Import SVG"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   362
            "method":   "_ImportSVG"
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   363
        },
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   364
        {
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   365
            "bitmap":    "EditSVG",
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   366
            "name":    _("Inkscape"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   367
            "tooltip": _("Edit HMI"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   368
            "method":   "_StartInkscape"
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   369
        },
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
        {
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   371
            "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
   372
            "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
   373
            "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
   374
            "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
   375
        },
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
   376
        {
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   377
            "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
   378
            "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
   379
            "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
   380
            "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
   381
        },
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   382
        {
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   383
            "bitmap":    "AddFont",
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   384
            "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
   385
            "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
   386
            "method":   "_AddFont"
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   387
        },
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   388
        {
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   389
            "bitmap":    "DelFont",
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   390
            "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
   391
            "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
   392
            "method":   "_DelFont"
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   393
        },
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   394
    ]
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   395
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   396
    def _getSVGpath(self, project_path=None):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   397
        if project_path is None:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   398
            project_path = self.CTNPath()
2781
fbdd0fd8ee4f SVGHMI: gui.svg -> svghmi.svg
Edouard Tisserant
parents: 2779
diff changeset
   399
        return os.path.join(project_path, "svghmi.svg")
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   400
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   401
    def _getPOTpath(self, project_path=None):
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   402
        if project_path is None:
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   403
            project_path = self.CTNPath()
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   404
        return os.path.join(project_path, "messages.pot")
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   405
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   406
    def OnCTNSave(self, from_project_path=None):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   407
        if from_project_path is not None:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   408
            shutil.copyfile(self._getSVGpath(from_project_path),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   409
                            self._getSVGpath())
3498
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   410
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   411
            potpath = self._getPOTpath(from_project_path)
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   412
            if os.path.isfile(potpath):
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   413
                shutil.copyfile(potpath, self._getPOTpath())
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   414
                # copy .PO files
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   415
                for _name, pofile in GetPoFiles(from_project_path):
cf4e6a7d40f8 Various fixes to make svghmi_traffic_light example bahave on windows.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3399
diff changeset
   416
                    shutil.copy(pofile, self.CTNPath())
2750
2694170cd88e intermediate commit, work in progress
Edouard Tisserant
parents: 2749
diff changeset
   417
        return True
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   418
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
   419
    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
   420
        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
   421
        # 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
   422
        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
   423
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
   424
        inkpath = get_inkscape_path()
3052
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   425
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   426
        if inkpath is None:
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   427
            self.FatalError("SVGHMI: inkscape is not installed.")
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   428
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
   429
        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
   430
        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
   431
                                                     '"' + 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
   432
                                                     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
   433
                                                     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
   434
        if status != 0:
3052
ffce85221ea5 SVGHMI: Better error message when inkscape is not installed.
Edouard Tisserant
parents: 3051
diff changeset
   435
            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
   436
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
   437
        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
   438
        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
   439
            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
   440
            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
   441
                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
   442
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
   443
            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
   444
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
   445
        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
   446
        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
   447
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
   448
    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
   449
        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
   450
        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
   451
        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
   452
        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
   453
        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
   454
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   455
    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
   456
        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
   457
        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
   458
3140
cae53fe54cf2 SVGHMI: i18n: prevent creating messages.pot if no translation
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   459
        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
   460
            self.ProgressEnd("i18n")
3140
cae53fe54cf2 SVGHMI: i18n: prevent creating messages.pot if no translation
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   461
            return
cae53fe54cf2 SVGHMI: i18n: prevent creating messages.pot if no translation
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3137
diff changeset
   462
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
   463
        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
   464
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
   465
        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
   466
            
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
   467
        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
   468
            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
   469
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
   470
        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
   471
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
   472
        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
   473
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
   474
        return ret
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   475
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
   476
    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
   477
        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
   478
        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
   479
        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
   480
            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
   481
        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
   482
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   483
    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
   484
        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
   485
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
   486
        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
   487
            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
   488
                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
   489
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
   490
        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
   491
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
   492
    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
   493
    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
   494
    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
   495
        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
   496
        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
   497
        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
   498
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
   499
    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
   500
        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
   501
        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
   502
        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
   503
        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
   504
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
   505
    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
   506
        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
   507
        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
   508
        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
   509
        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
   510
        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
   511
            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
   512
        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
   513
        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
   514
            ) + (("/"+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
   515
            ) + ("#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
   516
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
   517
        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
   518
            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
   519
            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
   520
            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
   521
            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
   522
            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
   523
            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
   524
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   525
    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
   526
        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
   527
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
   528
        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
   529
            self.FatalError("SVGHMI : Library is not selected. Please select it in project config.")
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   530
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
        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
   532
        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
   533
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   534
        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
   535
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
   536
        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
   537
2812
68ac5bf43525 SVGHMI: various fixes to make SVGHMI behave on more versions of twisted and GCC.
Edouard Tisserant
parents: 2789
diff changeset
   538
        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
   539
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
   540
        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
   541
        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
   542
        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
   543
3156
76c0c0a524c9 SVGHMI: display progress in IDE console while building
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3140
diff changeset
   544
        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
   545
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   546
        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
   547
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
   548
            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
   549
            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
   550
            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
   551
            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
   552
                           (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
   553
                           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
   554
bb314cdfc656 SVGHMI: force svghmi build if any change in fonts or translation (.PO) files
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3211
diff changeset
   555
            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
   556
                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
   557
                    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
   558
                        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
   559
                        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
   560
                            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
   561
                        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
   562
                            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
   563
            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
   564
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
   565
            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
   566
                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
   567
                    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
   568
            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
   569
                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
   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
            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
   572
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
                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
   574
                              [("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
   575
                               ("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
   576
                               ("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
   577
                               ("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
   578
                               ("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
   579
                               ("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
   580
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.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
   582
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
   583
                # 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
   584
                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
   585
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
                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
   587
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
                # 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
   589
                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
   590
                    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
   591
                    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
   592
                        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
   593
                    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
   594
                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
   595
                    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
   596
                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
   597
                    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
   598
                        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
   599
                        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
   600
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
   601
                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
   602
                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
   603
                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
   604
c059026d8626 SVGHMI: do not do XSLT transform if both SVGHMI and HMI Tree didn't change since last build
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3177
diff changeset
   605
                # 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
   606
                # 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
   607
                # 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
   608
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
   609
                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
   610
                    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
   611
            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
   612
                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
   613
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   614
        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
   615
            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
   616
            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
   617
<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
   618
<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
   619
<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
   620
</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
   621
<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
   622
<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
   623
</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
   624
</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
   625
""")
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
   626
            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
   627
3372
e5cb7447320c SVGHMI: prevents watchdog being triggered when SVGHMI is empty.
Edouard Tisserant
parents: 3348
diff changeset
   628
            # 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
   629
            svghmi_options["enable_watchdog"] = False
e5cb7447320c SVGHMI: prevents watchdog being triggered when SVGHMI is empty.
Edouard Tisserant
parents: 3348
diff changeset
   630
2772
3f1dd8312710 SVGHMI: few fixes on serving
Edouard Tisserant
parents: 2771
diff changeset
   631
        res += ((target_fname, open(target_path, "rb")),)
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   632
2823
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   633
        svghmi_cmds = {}
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   634
        for thing in ["Start", "Stop", "Watchdog"]:
d631f8671c75 SVGHMI : add on Start, Stop and Watchdog command fields to configuration
Edouard Tisserant
parents: 2822
diff changeset
   635
             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
   636
             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
   637
                "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
   638
                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
   639
                ")") if given_command else "pass # no command given"
2772
3f1dd8312710 SVGHMI: few fixes on serving
Edouard Tisserant
parents: 2771
diff changeset
   640
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
   641
        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
   642
        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
   643
        runtimefile.write("""
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   644
# 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
   645
def svghmi_{location}_watchdog_trigger():
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   646
    {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
   647
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
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
   649
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
   650
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
   651
    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
   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
    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
   654
    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
   655
        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
   656
        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
   657
            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
   658
    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
   659
        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
   660
        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
   661
        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
   662
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
   663
        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
   664
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   665
        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
   666
        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
   667
        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
   668
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   669
    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
   670
        '{path}',
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   671
        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
   672
            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
   673
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
    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
   675
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   676
    {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
   677
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
   678
    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
   679
        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
   680
            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
   681
                {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
   682
                {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
   683
                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
   684
        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
   685
            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
   686
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   687
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
   688
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
   689
    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
   690
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   691
    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
   692
        svghmi_watchdog.cancel()
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   693
        svghmi_watchdog = None
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   694
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
   695
    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
   696
    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
   697
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   698
    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
   699
5d174cdf4d98 SVGHMI: More configuration parameters : network interface, TCP port, URL path and watchdog enabling.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3267
diff changeset
   700
    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
   701
        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
   702
        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
   703
        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
   704
2828
be947a338760 SVGHMI : cosmetic
Edouard Tisserant
parents: 2826
diff changeset
   705
    {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
   706
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
   707
        """.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
   708
                   xhtml=target_fname,
2831
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   709
                   svghmi_cmds=svghmi_cmds,
6c9cfdbe94dc SVGHMI : watchdog is now taking an initial and interval duration as CTN fields.
Edouard Tisserant
parents: 2830
diff changeset
   710
                   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
   711
                   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
   712
                   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
   713
                   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
   714
                   **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
   715
        ))
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
   716
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
   717
        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
   718
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
   719
        res += (("runtime_%s_svghmi.py" % location_str, open(runtimefile_path, "rb")),)
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   720
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   721
        return res
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   722
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   723
    def _ImportSVG(self):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   724
        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
   725
        if dialog.ShowModal() == wx.ID_OK:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   726
            svgpath = dialog.GetPath()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   727
            if os.path.isfile(svgpath):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   728
                shutil.copy(svgpath, self._getSVGpath())
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   729
            else:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   730
                self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n") % svgpath)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   731
        dialog.Destroy()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   732
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
   733
    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
   734
        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
   735
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   736
    def _StartInkscape(self):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   737
        svgfile = self._getSVGpath()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   738
        open_inkscape = True
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   739
        if not self.GetCTRoot().CheckProjectPathPerm():
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   740
            dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   741
                                      _("You don't have write permissions.\nOpen Inkscape anyway ?"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   742
                                      _("Open Inkscape"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   743
                                      wx.YES_NO | wx.ICON_QUESTION)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   744
            open_inkscape = dialog.ShowModal() == wx.ID_YES
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   745
            dialog.Destroy()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   746
        if open_inkscape:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   747
            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
   748
                # 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
   749
                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
   750
                shutil.copyfile(default, svgfile)
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   751
            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
   752
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   753
    def _StartPOEdit(self, POFile):
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   754
        open_poedit = True
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   755
        if not self.GetCTRoot().CheckProjectPathPerm():
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   756
            dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   757
                                      _("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
   758
                                      _("Open POEdit"),
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   759
                                      wx.YES_NO | wx.ICON_QUESTION)
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   760
            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
   761
            dialog.Destroy()
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   762
        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
   763
            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
   764
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
   765
    def _EditPO(self):
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   766
        """ 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
   767
        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
   768
        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
   769
        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
   770
            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
   771
            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
   772
                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
   773
                    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
   774
                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
   775
                    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
   776
            else:
3158
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   777
                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
   778
        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
   779
bd20f9112014 SVGHMI: still WIP, now POT file is properly generated with utf-8 encoding and POEdit is launched when pressing button.
Edouard Tisserant
parents: 3108
diff changeset
   780
    def _OpenPOT(self):
3108
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   781
        """ Start POEdit with untouched empty catalog """
079419e7228d SVGHMI: Intermediate commit while implementing i18n. WIP.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3068
diff changeset
   782
        POFile = self._getPOTpath()
3158
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   783
        if os.path.isfile(POFile):
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   784
            self._StartPOEdit(POFile)
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   785
        else:
4171f7dd109a SVGHMI: Fixed/extended error message when failing to launch POEdit.
Edouard Tisserant
parents: 3140
diff changeset
   786
            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
   787
3210
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   788
    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
   789
        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
   790
            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
   791
            _("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
   792
            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
   793
            "",
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
            _("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
   795
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
        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
   797
            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
   798
            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
   799
                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
   800
            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
   801
                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
   802
                    _('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
   803
                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
   804
            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
   805
                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
   806
                    _('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
   807
                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
   808
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
            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
   810
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
   811
            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
   812
            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
   813
            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
   814
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
            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
   816
                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
   817
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
            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
   819
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
            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
   821
                _('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
   822
0ddefd20ca2b SVGHMI: Add font management buttons and icons, doing nothing for now
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3208
diff changeset
   823
    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
   824
        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
   825
        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
   826
        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
   827
            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
   828
            _("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
   829
            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
            "",
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
            _("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
   832
        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
   833
            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
   834
            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
   835
                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
   836
                    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
   837
                    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
   838
                        _('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
   839
                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
   840
                    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
   841
                        _("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
   842
            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
   843
                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
   844
                    _("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
   845
        
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
   846
    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
   847
        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
   848
        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
   849
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
   850
    ## 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
   851
    #     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
   852
    #     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
   853
3159
1d7c3d13a4df SVGHMI: Add icons
Edouard Tisserant
parents: 3158
diff changeset
   854
    def GetIconName(self):
1d7c3d13a4df SVGHMI: Add icons
Edouard Tisserant
parents: 3158
diff changeset
   855
        return "SVGHMI"