# This file is part of Beremiz, a Integrated Development Environment for
# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
# See COPYING file for copyrights details.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from nevow import rend, appserver, inevow, tags, loaders, athena
from nevow.page import renderer
from twisted.python import util
from twisted.internet import reactor
xhtml_header = '''<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
class PLCHMI(athena.LiveElement):
def HMIinitialised(self, result):
def HMIinitialisation(self):
self.HMIinitialised(None)
class DefaultPLCStartedHMI(PLCHMI):
docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[
tags.h1["PLC IS NOW STARTED"],
class PLCStoppedHMI(PLCHMI):
docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[
tags.h1["PLC IS STOPPED"],
class MainPage(athena.LiveElement):
jsClass = u"WebInterface.PLC"
docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[
tags.div(render = tags.directive('PLCElement')),
def __init__(self, *a, **kw):
athena.LiveElement.__init__(self, *a, **kw)
self.resetPLCStartedHMI()
def setPLCState(self, state):
self.callRemote('updateHMI')
def setPLCStartedHMI(self, hmi):
self.PLCStartedHMIClass = hmi
def resetPLCStartedHMI(self):
self.PLCStartedHMIClass = DefaultPLCStartedHMI
def HMIexec(self, function, *args, **kwargs):
getattr(self.HMI, function, lambda:None)(*args, **kwargs)
def PLCElement(self, ctx, data):
return self.getPLCElement()
self.detachFragmentChildren()
f = self.PLCStartedHMIClass()
f.setFragmentParent(self)
athena.expose(getPLCElement)
def detachFragmentChildren(self):
for child in self.liveFragmentChildren[:]:
class WebInterface(athena.LivePage):
docFactory = loaders.stan([tags.raw(xhtml_header),
tags.html(xmlns="http://www.w3.org/1999/xhtml")[
tags.head(render=tags.directive('liveglue')),
tags.div( render = tags.directive( "MainPage" ))
def __init__(self, plcState=False, *a, **kw):
super(WebInterface, self).__init__(*a, **kw)
self.jsModules.mapping[u'WebInterface'] = util.sibpath(__file__, 'webinterface.js')
self.MainPage.setPLCState(plcState)
return self.MainPage.getHMI()
def LoadHMI(self, hmi, jsmodules):
for name, path in jsmodules.iteritems():
self.jsModules.mapping[name] = os.path.join(WorkingDir, path)
self.MainPage.setPLCStartedHMI(hmi)
self.MainPage.resetPLCStartedHMI()
self.MainPage.setPLCState(True)
self.MainPage.setPLCState(False)
def renderHTTP(self, ctx):
Force content type to fit with SVG
req = inevow.IRequest(ctx)
req.setHeader('Content-type', 'application/xhtml+xml')
return super(WebInterface, self).renderHTTP(ctx)
def render_MainPage(self, ctx, data):
f.setFragmentParent(self)
self.MainPage.detachFragmentChildren()
return WebInterface(plcState=self.plcState)
def beforeRender(self, ctx):
d = self.notifyOnDisconnect()
d.addErrback(self.disconnected)
def disconnected(self, reason):
#print "We will be called back when the client disconnects"
def RegisterWebsite(port):
site = appserver.NevowSite(website)
reactor.listenTCP(port, site)
print _("HTTP interface port :"), port
def __init__(self, site):
if state != self.oldstate:
action = {'Started': self.site.PLCStarted,
'Stopped': self.site.PLCStopped}.get(state, None)
if action is not None: action ()
def website_statuslistener_factory(site):
return statuslistener(site).listen