# This file is part of Beremiz runtime.
# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
# Copyright (C) 2017: Andrey Skvortsov
# See COPYING.Runtime file for copyrights details.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library 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
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from __future__ import absolute_import
from __future__ import print_function
from nevow import appserver, inevow, tags, loaders, athena
from nevow.page import renderer
from twisted.internet import reactor
import util.paths as paths
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'] = paths.AbsNeighbourFile(__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 = ctx.locate(inevow.IRequest)
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)
class statuslistener(object):
def __init__(self, site):
if state != self.oldstate:
action = {'Started': self.site.PLCStarted,
'Stopped': self.site.PLCStopped}.get(state, None)
def website_statuslistener_factory(site):
return statuslistener(site).listen