Added stub code for runtime WAMP client. Added runtime command line switch to select WAMP url and Nevow web site port. Web port is now fixed, next port number is not tested if bind fails.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
from nevow import rend, appserver, inevow, tags, loaders, athena
import simplejson as json
svgfile = '%(svgfile)s'
svguiWidgets = {}
currentId = 0
def getNewId():
global currentId
currentId += 1
return currentId
class SvguiWidget:
def __init__(self, classname, id, **kwargs):
self.classname = classname
self.id = id
self.attrs = kwargs.copy()
self.inputs = {}
self.outputs = {}
self.inhibit = False
self.changed = False
def setinput(self, attrname, value):
self.inputs[attrname] = value
def getinput(self, attrname, default=None):
if not self.inputs.has_key(attrname):
self.inputs[attrname] = default
return self.inputs[attrname]
def setoutput(self, attrname, value):
if self.outputs.get(attrname) != value:
self.outputs[attrname] = value
self.changed = True
self.RefreshInterface()
def updateoutputs(self, **kwargs):
for attrname, value in kwargs.iteritems():
if self.outputs.get(attrname) != value:
self.outputs[attrname] = value
self.changed = True
self.RefreshInterface()
def RefreshInterface(self):
interface = website.getHMI()
if isinstance(interface, SVGUI_HMI) and self.changed and not self.inhibit:
self.changed = False
d = interface.sendData(self)
if d is not None:
self.inhibit = True
d.addCallback(self.InterfaceRefreshed)
def InterfaceRefreshed(self, result):
self.inhibit = False
if self.changed:
self.RefreshInterface()
def get_object_init_state(obj):
# Convert objects to a dictionary of their representation
attrs = obj.attrs.copy()
attrs.update(obj.inputs)
d = { '__class__': obj.classname,
'id': obj.id,
'kwargs': json.dumps(attrs),
}
return d
def get_object_current_state(obj):
# Convert objects to a dictionary of their representation
d = { '__class__': obj.classname,
'id': obj.id,
'kwargs': json.dumps(obj.outputs),
}
return d
class SVGUI_HMI(website.PLCHMI):
jsClass = u"LiveSVGPage.LiveSVGWidget"
docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[
tags.xml(loaders.xmlfile(os.path.join(WorkingDir, svgfile))),
])
def HMIinitialisation(self):
gadgets = []
for gadget in svguiWidgets.values():
gadgets.append(unicode(json.dumps(gadget, default=get_object_init_state, indent=2), 'ascii'))
d = self.callRemote('init', gadgets)
d.addCallback(self.HMIinitialised)
def sendData(self,data):
if self.initialised:
return self.callRemote('receiveData',unicode(json.dumps(data, default=get_object_current_state, indent=2), 'ascii'))
return None
def setattr(self, id, attrname, value):
svguiWidgets[id].setinput(attrname, value)
def createSVGUIControl(*args, **kwargs):
id = getNewId()
gad = SvguiWidget(args[0], id, **kwargs)
svguiWidgets[id] = gad
gadget = [unicode(json.dumps(gad, default=get_object_init_state, indent=2), 'ascii')]
interface = website.getHMI()
if isinstance(interface, SVGUI_HMI) and interface.initialised:
interface.callRemote('init', gadget)
return id
def setAttr(id, attrname, value):
gad = svguiWidgets.get(id, None)
if gad is not None:
gad.setoutput(attrname, value)
def updateAttr(id, **kwargs):
gad = svguiWidgets.get(id, None)
if gad is not None:
gad.updateoutput(**kwargs)
def getAttr(id, attrname, default=None):
gad = svguiWidgets.get(id, None)
if gad is not None:
return gad.getinput(attrname, default)
return default