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), |