svgui/svgui_server.py
changeset 3359 2c924cf26161
parent 3358 7478d0c0dc1c
child 3360 746e3e3f6537
equal deleted inserted replaced
3358:7478d0c0dc1c 3359:2c924cf26161
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 # This file is part of Beremiz, a Integrated Development Environment for
       
     5 # programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
       
     6 #
       
     7 # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 # See COPYING file for copyrights details.
       
    10 #
       
    11 # This program is free software; you can redistribute it and/or
       
    12 # modify it under the terms of the GNU General Public License
       
    13 # as published by the Free Software Foundation; either version 2
       
    14 # of the License, or (at your option) any later version.
       
    15 #
       
    16 # This program is distributed in the hope that it will be useful,
       
    17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    19 # GNU General Public License for more details.
       
    20 #
       
    21 # You should have received a copy of the GNU General Public License
       
    22 # along with this program; if not, write to the Free Software
       
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
       
    24 
       
    25 
       
    26 from __future__ import absolute_import
       
    27 import os
       
    28 from builtins import str as text
       
    29 
       
    30 from nevow import tags, loaders
       
    31 import simplejson as json  # pylint: disable=import-error
       
    32 import runtime.NevowServer as NS
       
    33 
       
    34 svgfile = '%(svgfile)s'
       
    35 
       
    36 svguiWidgets = {}
       
    37 
       
    38 currentId = 0
       
    39 
       
    40 
       
    41 def getNewId():
       
    42     global currentId
       
    43     currentId += 1
       
    44     return currentId
       
    45 
       
    46 
       
    47 class SvguiWidget(object):
       
    48 
       
    49     def __init__(self, classname, id, **kwargs):
       
    50         self.classname = classname
       
    51         self.id = id
       
    52         self.attrs = kwargs.copy()
       
    53         self.inputs = {}
       
    54         self.outputs = {}
       
    55         self.inhibit = False
       
    56         self.changed = False
       
    57 
       
    58     def setinput(self, attrname, value):
       
    59         self.inputs[attrname] = value
       
    60 
       
    61     def getinput(self, attrname, default=None):
       
    62         if attrname not in self.inputs:
       
    63             self.inputs[attrname] = default
       
    64         return self.inputs[attrname]
       
    65 
       
    66     def setoutput(self, attrname, value):
       
    67         if self.outputs.get(attrname) != value:
       
    68             self.outputs[attrname] = value
       
    69             self.changed = True
       
    70             self.RefreshInterface()
       
    71 
       
    72     def updateoutputs(self, **kwargs):
       
    73         for attrname, value in kwargs.iteritems():
       
    74             if self.outputs.get(attrname) != value:
       
    75                 self.outputs[attrname] = value
       
    76                 self.changed = True
       
    77         self.RefreshInterface()
       
    78 
       
    79     def RefreshInterface(self):
       
    80         interface = website.getHMI()
       
    81         if isinstance(interface, SVGUI_HMI) and self.changed and not self.inhibit:
       
    82             self.changed = False
       
    83             d = interface.sendData(self)
       
    84             if d is not None:
       
    85                 self.inhibit = True
       
    86                 d.addCallback(self.InterfaceRefreshed)
       
    87 
       
    88     def InterfaceRefreshed(self, result):
       
    89         self.inhibit = False
       
    90         if self.changed:
       
    91             self.RefreshInterface()
       
    92 
       
    93 
       
    94 def get_object_init_state(obj):
       
    95     # Convert objects to a dictionary of their representation
       
    96     attrs = obj.attrs.copy()
       
    97     attrs.update(obj.inputs)
       
    98     d = {
       
    99         '__class__': obj.classname,
       
   100         'id': obj.id,
       
   101         'kwargs': json.dumps(attrs),
       
   102     }
       
   103     return d
       
   104 
       
   105 
       
   106 def get_object_current_state(obj):
       
   107     # Convert objects to a dictionary of their representation
       
   108     d = {
       
   109         '__class__': obj.classname,
       
   110         'id': obj.id,
       
   111         'kwargs': json.dumps(obj.outputs),
       
   112     }
       
   113     return d
       
   114 
       
   115 
       
   116 class SVGUI_HMI(website.PLCHMI):
       
   117     jsClass = u"LiveSVGPage.LiveSVGWidget"
       
   118 
       
   119     docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[
       
   120         tags.xml(loaders.xmlfile(os.path.join(NS.WorkingDir, svgfile))),
       
   121     ])
       
   122 
       
   123     def HMIinitialisation(self):
       
   124         gadgets = []
       
   125         for gadget in svguiWidgets.values():
       
   126             gadgets.append(text(json.dumps(gadget, default=get_object_init_state, indent=2), 'ascii'))
       
   127         d = self.callRemote('init', gadgets)
       
   128         d.addCallback(self.HMIinitialised)
       
   129 
       
   130     def sendData(self, data):
       
   131         if self.initialised:
       
   132             return self.callRemote('receiveData', text(json.dumps(data, default=get_object_current_state, indent=2), 'ascii'))
       
   133         return None
       
   134 
       
   135     def setattr(self, id, attrname, value):
       
   136         svguiWidgets[id].setinput(attrname, value)
       
   137 
       
   138 
       
   139 def createSVGUIControl(*args, **kwargs):
       
   140     id = getNewId()
       
   141     gad = SvguiWidget(args[0], id, **kwargs)
       
   142     svguiWidgets[id] = gad
       
   143     gadget = [text(json.dumps(gad, default=get_object_init_state, indent=2), 'ascii')]
       
   144     interface = website.getHMI()
       
   145     if isinstance(interface, SVGUI_HMI) and interface.initialised:
       
   146         interface.callRemote('init', gadget)
       
   147     return id
       
   148 
       
   149 
       
   150 def setAttr(id, attrname, value):
       
   151     gad = svguiWidgets.get(id, None)
       
   152     if gad is not None:
       
   153         gad.setoutput(attrname, value)
       
   154 
       
   155 
       
   156 def updateAttr(id, **kwargs):
       
   157     gad = svguiWidgets.get(id, None)
       
   158     if gad is not None:
       
   159         gad.updateoutput(**kwargs)
       
   160 
       
   161 
       
   162 def getAttr(id, attrname, default=None):
       
   163     gad = svguiWidgets.get(id, None)
       
   164     if gad is not None:
       
   165         return gad.getinput(attrname, default)
       
   166     return default