runtime/NevowServer.py
branchnevow_service_rework
changeset 2210 81949104291d
parent 2209 ee2675e4778d
child 2214 b9cdbcc992d5
equal deleted inserted replaced
2209:ee2675e4778d 2210:81949104291d
    30 from nevow import appserver, inevow, tags, loaders, athena, url, rend
    30 from nevow import appserver, inevow, tags, loaders, athena, url, rend
    31 from nevow.page import renderer
    31 from nevow.page import renderer
    32 from formless import annotate
    32 from formless import annotate
    33 from formless import webform
    33 from formless import webform
    34 from formless import configurable
    34 from formless import configurable
    35 
       
    36 from twisted.internet import reactor
    35 from twisted.internet import reactor
       
    36 
    37 import util.paths as paths
    37 import util.paths as paths
       
    38 from runtime.loglevels import LogLevels, LogLevelsDict
    38 
    39 
    39 PAGE_TITLE = 'Beremiz Runtime Web Interface'
    40 PAGE_TITLE = 'Beremiz Runtime Web Interface'
    40 
    41 
    41 xhtml_header = '''<?xml version="1.0" encoding="utf-8"?>
    42 xhtml_header = '''<?xml version="1.0" encoding="utf-8"?>
    42 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    43 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    43 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    44 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    44 '''
    45 '''
    45 
    46 
    46 WorkingDir = None
    47 WorkingDir = None
       
    48 _PySrv = None
    47 
    49 
    48 
    50 
    49 class PLCHMI(athena.LiveElement):
    51 class PLCHMI(athena.LiveElement):
    50 
    52 
    51     initialised = False
    53     initialised = False
   123 
   125 
   124     def detachFragmentChildren(self):
   126     def detachFragmentChildren(self):
   125         for child in self.liveFragmentChildren[:]:
   127         for child in self.liveFragmentChildren[:]:
   126             child.detach()
   128             child.detach()
   127 
   129 
   128 lastKnownConfig = {
       
   129     'net': {
       
   130         'mode': 'DHCP',
       
   131         'IP': '192.168.1.42',
       
   132         'gateway': '192.168.1.1',
       
   133         'mask': '255.255.255.0',
       
   134         'DNS': '8.8.8.8'},
       
   135     'wamp': {}
       
   136 }
       
   137 
       
   138 def defaultVal(category):
       
   139     def _defaultVal(ctx,argument):
       
   140         return lastKnownConfig[category].get(argument.name, None)
       
   141     return _defaultVal
       
   142 
       
   143 
       
   144 class ConfigurableBindings(configurable.Configurable):
   130 class ConfigurableBindings(configurable.Configurable):
   145 
   131 
   146     def __init__(self):
   132     def __init__(self):
   147         configurable.Configurable.__init__(self, None)
   133         configurable.Configurable.__init__(self, None)
   148         self.bindingsNames = []
   134         self.bindingsNames = []
   149 
   135 
   150     def getBindingNames(self, ctx):
   136     def getBindingNames(self, ctx):
   151         return self.bindingsNames
   137         return self.bindingsNames
   152 
   138 
   153     def addExtension(self, name, desc, fields, callback):
   139     def addExtension(self, name, desc, fields, btnlabel, callback):
   154         print(name, fields, callback)
       
   155         def _bind(ctx):
   140         def _bind(ctx):
   156             return annotate.MethodBinding(
   141             return annotate.MethodBinding(
   157                 'action_'+name,
   142                 'action_'+name,
   158                 annotate.Method(arguments=[
   143                 annotate.Method(arguments=[
   159                     annotate.Argument(name, fieldtype)
   144                     annotate.Argument(name, fieldtype)
   160                     for fieldname,fieldtype in fields],
   145                     for fieldname,fieldtype in fields],
   161                     label = desc),
   146                     label = desc),
   162                 action = _("Set"))
   147                 action = btnlabel))
   163         setattr(self, 'bind_'+name, _bind)
   148         setattr(self, 'bind_'+name, _bind)
   164             
   149             
   165         def _action(**kw):
   150         setattr(self, 'action_'+name, callback)
   166            callback(**kw) 
       
   167 
       
   168         setattr(self, 'action_'+name, _action)
       
   169 
   151 
   170         self.bindingsNames.append(name)
   152         self.bindingsNames.append(name)
   171 
   153 
   172 ConfigurableSettings = ConfigurableBindings()
   154 ConfigurableSettings = ConfigurableBindings()
   173 
   155 
   174 class ISettings(annotate.TypedInterface):
   156 class ISettings(annotate.TypedInterface):
   175     def networkConfig(
   157     def sendLogMessage(
   176         ctx = annotate.Context(),
   158         ctx = annotate.Context(),
   177         mode = annotate.Choice(["DHCP", "Static"],
   159         level = annotate.Choice(LogLevels,
   178                                required=True, 
   160                                 required=True, 
   179                                label=_("Configuration type"), 
   161                                 label=_("Log message level")),
   180                                default=defaultVal('net')),
   162         message = annotate.String(label=_("Message text"))):
   181         IP = annotate.String(label=_("IP address"),default=defaultVal('net')),
       
   182         gateway = annotate.String(label=_("Gateway address"),
       
   183                                   default=defaultVal('net')),
       
   184         mask = annotate.String(label=_("Network mask"),default=defaultVal('net')),
       
   185         DNS = annotate.String(label=_("DNS address"),default=defaultVal('net'))):
       
   186             pass
   163             pass
   187 
   164     sendLogMessage = annotate.autocallable(sendLogMessage, 
   188     networkConfig = annotate.autocallable(networkConfig, label=_("Network settings"), action=_("Set"))
   165                                            label=_("Send a message to the log"),
       
   166                                            action=_("Send"))
   189 
   167 
   190 
   168 
   191 class SettingsPage(rend.Page):
   169 class SettingsPage(rend.Page):
   192     # We deserve a slash
   170     # We deserve a slash
   193     addSlash = True
   171     addSlash = True
   218     def configurable_staticSettings(self, ctx):
   196     def configurable_staticSettings(self, ctx):
   219         return configurable.TypedInterfaceConfigurable(self)
   197         return configurable.TypedInterfaceConfigurable(self)
   220 
   198 
   221     def configurable_dynamicSettings(self, ctx):
   199     def configurable_dynamicSettings(self, ctx):
   222         return ConfigurableSettings
   200         return ConfigurableSettings
   223 
   201     
   224     def networkConfig(self, *args, **kwargs):
   202     def sendLogMessage(self, level, message, **kwargs):
   225         # TODO do the settings
   203         level = LogLevelsDict[level]
   226         print(kwargs)
   204         if _PySrv.plcobj is not None:
   227         lastKnownConfig['net'] = kwargs
   205             _PySrv.plcobj.LogMessage(level, "Web form log message: " + message )
   228         ConfigurableSettings.addExtension(
       
   229             "wamp", 
       
   230             "wamp DEscription", 
       
   231             [("Host",annotate.String(label=_("IP address")))], 
       
   232             lambda**k:print(k))
       
   233 
   206 
   234 
   207 
   235 class WebInterface(athena.LivePage):
   208 class WebInterface(athena.LivePage):
   236 
   209 
   237     docFactory = loaders.stan([tags.raw(xhtml_header),
   210     docFactory = loaders.stan([tags.raw(xhtml_header),
   311 
   284 
   312     reactor.listenTCP(port, site)
   285     reactor.listenTCP(port, site)
   313     print(_('HTTP interface port :'), port)
   286     print(_('HTTP interface port :'), port)
   314     return website
   287     return website
   315 
   288 
       
   289 
   316 class statuslistener(object):
   290 class statuslistener(object):
   317     def __init__(self, site):
   291     def __init__(self, site):
   318         self.oldstate = None
   292         self.oldstate = None
   319         self.site = site
   293         self.site = site
   320 
   294 
   329 
   303 
   330 def website_statuslistener_factory(site):
   304 def website_statuslistener_factory(site):
   331     return statuslistener(site).listen
   305     return statuslistener(site).listen
   332 
   306 
   333 
   307 
   334 
   308 def SetServer(pysrv):
   335 
   309     global _PySrv
       
   310     _PySrv = pysrv
       
   311