svghmi/svghmi.py
author Edouard Tisserant
Thu, 18 Jul 2019 14:09:33 +0200
branchsvghmi
changeset 2749 2769b3aed34d
parent 2747 e96aa2e3231e
child 2750 2694170cd88e
permissions -rw-r--r--
Use a POU Library's Generate_C to collect all variables in SVGHMI.
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     1
#!/usr/bin/env python
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     2
# -*- coding: utf-8 -*-
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     3
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     4
# This file is part of Beremiz
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     5
# Copyright (C) 2019: Edouard TISSERANT
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     6
#
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     7
# See COPYING file for copyrights details.
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     8
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
     9
from __future__ import absolute_import
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    10
import os
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    11
import shutil
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    12
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    13
import wx
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    14
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    15
import util.paths as paths
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    16
from POULibrary import POULibrary
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    17
from docutil import open_svg
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    18
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    19
HMI_TYPES_DESC = {
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    20
    "HMI_CLASS":{},
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    21
    "HMI_LABEL":{},
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    22
    "HMI_STRING":{},
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    23
    "HMI_INT":{},
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    24
    "HMI_REAL":{}
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    25
}
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    26
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    27
HMI_TYPES = HMI_TYPES_DESC.keys()
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    28
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    29
class SVGHMILibrary(POULibrary):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    30
    def GetLibraryPath(self):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    31
        return paths.AbsNeighbourFile(__file__, "pous.xml")
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    32
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    33
    def Generate_C(self, buildpath, varlist, IECCFLAGS):
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    34
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    35
        # Filter known HMI types
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    36
        hmi_types_instances = [v for v in varlist if v["derived"] in HMI_TYPES]
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    37
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    38
        # TODO deduce HMI tree
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    39
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    40
        # TODO generate C code to observe/access HMI tree variables
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    41
        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
    42
        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
    43
        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
    44
        svghmi_c_file.close()
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    45
        svghmi_c_code = svghmi_c_code % { "the code": "/* TODO */"}
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    46
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    47
        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
    48
        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
    49
        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
    50
        gen_svghmi_c.close()
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    51
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
    52
        return (["svghmi"], [(gen_svghmi_c_path, IECCFLAGS)], True), ""
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    53
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    54
class SVGHMI(object):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    55
    XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    56
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    57
      <xsd:element name="SVGHMI">
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    58
        <xsd:complexType>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    59
          <xsd:attribute name="enableHTTP" type="xsd:boolean" use="optional" default="false"/>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    60
          <xsd:attribute name="bindAddress" type="xsd:string" use="optional" default="localhost"/>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    61
          <xsd:attribute name="port" type="xsd:string" use="optional" default="8080"/>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    62
        </xsd:complexType>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    63
      </xsd:element>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    64
    </xsd:schema>
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    65
    """
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    66
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    67
    ConfNodeMethods = [
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    68
        {
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    69
            "bitmap":    "ImportSVG",
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    70
            "name":    _("Import SVG"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    71
            "tooltip": _("Import SVG"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    72
            "method":   "_ImportSVG"
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    73
        },
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    74
        {
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    75
            "bitmap":    "ImportSVG",  # should be something different
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    76
            "name":    _("Inkscape"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    77
            "tooltip": _("Edit HMI"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    78
            "method":   "_StartInkscape"
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    79
        },
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    80
    ]
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    81
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    82
    def _getSVGpath(self, project_path=None):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    83
        if project_path is None:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    84
            project_path = self.CTNPath()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    85
        # define name for SVG file containing gui layout
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    86
        return os.path.join(project_path, "gui.svg")
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    87
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    88
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    89
    def OnCTNSave(self, from_project_path=None):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    90
        if from_project_path is not None:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    91
            shutil.copyfile(self._getSVGpath(from_project_path),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    92
                            self._getSVGpath())
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    93
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    94
    def CTNGenerate_C(self, buildpath, locations):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    95
        """
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    96
        Return C code generated by iec2c compiler
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    97
        when _generate_softPLC have been called
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    98
        @param locations: ignored
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
    99
        @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   100
        """
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   101
2749
2769b3aed34d Use a POU Library's Generate_C to collect all variables in SVGHMI.
Edouard Tisserant
parents: 2747
diff changeset
   102
        # TODO fetch HMI tree from library
2745
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   103
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   104
        svgfile = self._getSVGpath()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   105
        if os.path.exists(svgfile):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   106
            # TODO : call xslt transform on Inkscape's SVG to generate
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   107
            #   - Errors on HMI semantics
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   108
            #   - Target XHTML as a DOM
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   109
            #   - ... maybe something to have a global view of what is declared in SVG.
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   110
            pass
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   111
        else:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   112
            # TODO : use default svg that expose the HMI tree as-is 
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   113
            pass
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   114
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   115
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   116
        res = ([], "", False)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   117
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   118
        targetpath = os.path.join(self._getBuildPath(), "target.xhtml")
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   119
        targetfile = open(targetpath, 'w')
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   120
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   121
        # TODO : DOM to string
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   122
        targetfile.write("TODO")
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   123
        targetfile.close()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   124
        res += (("target.js", open(targetpath, "rb")),)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   125
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   126
        # TODO add C code to expose HMI tree variables to shared memory
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   127
        # TODO generate a description of shared memory (xml or CSV) 
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   128
        #      that can be loaded by svghmi QTWeb* app or svghmi server
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   129
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   130
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   131
        return res
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   132
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   133
    def _ImportSVG(self):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   134
        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
   135
        if dialog.ShowModal() == wx.ID_OK:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   136
            svgpath = dialog.GetPath()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   137
            if os.path.isfile(svgpath):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   138
                shutil.copy(svgpath, self._getSVGpath())
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   139
            else:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   140
                self.GetCTRoot().logger.write_error(_("No such SVG file: %s\n") % svgpath)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   141
        dialog.Destroy()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   142
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   143
    def _StartInkscape(self):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   144
        svgfile = self._getSVGpath()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   145
        open_inkscape = True
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   146
        if not self.GetCTRoot().CheckProjectPathPerm():
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   147
            dialog = wx.MessageDialog(self.GetCTRoot().AppFrame,
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   148
                                      _("You don't have write permissions.\nOpen Inkscape anyway ?"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   149
                                      _("Open Inkscape"),
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   150
                                      wx.YES_NO | wx.ICON_QUESTION)
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   151
            open_inkscape = dialog.ShowModal() == wx.ID_YES
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   152
            dialog.Destroy()
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   153
        if open_inkscape:
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   154
            if not os.path.isfile(svgfile):
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   155
                svgfile = None
535eb0b8bd9d Skeleton for svghmi extension
Edouard Tisserant
parents:
diff changeset
   156
            open_svg(svgfile)