--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/dmx-web.py Fri Apr 11 21:45:26 2014 +0300
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+import pvl.args
+import pvl.web.args
+import qmsk.dmx
+import qmsk.dmx.web
+
+import logging; log = logging.getLogger('dmx')
+
+import optparse
+
+def main (argv) :
+ """
+ DMX web control.
+ """
+
+ parser = optparse.OptionParser(main.__doc__)
+ parser.add_option_group(pvl.args.parser(parser))
+ parser.add_option_group(pvl.web.args.parser(parser))
+
+ parser.add_option('--dmx-serial', default=qmsk.dmx.DMX.SERIAL,
+ help="Path to /dev/tty*")
+
+ options, args = parser.parse_args(argv[1:])
+
+ pvl.args.apply(options)
+
+ # dmx
+ dmx = qmsk.dmx.DMX.open(options.dmx_serial)
+ dmx.zero()
+
+ # app
+ app = qmsk.dmx.web.DMXWebApplication(dmx)
+
+ pvl.web.args.main(options, app)
+
+if __name__ == '__main__':
+ pvl.args.main(main)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk/dmx/web.py Fri Apr 11 21:45:26 2014 +0300
@@ -0,0 +1,106 @@
+import pvl.web
+from pvl.web import urls, html
+
+import logging; log = logging.getLogger('qmsk.dmx.web')
+
+class Handler (pvl.web.Handler) :
+ # Bootstrap
+ DOCTYPE = 'html'
+ HTML_XMLNS = None
+ HTML_LANG = 'en'
+ CSS = (
+ '//code.jquery.com/ui/1.10.4/themes/ui-darkness/jquery-ui.css',
+ '//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css',
+ )
+ JS = (
+ '//code.jquery.com/jquery-2.1.0.js',
+ '//code.jquery.com/ui/1.10.4/jquery-ui.js',
+ '//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js',
+ )
+
+ STYLE = """
+body {
+ padding-top: 2em;
+ text-align: center;
+}
+
+.container {
+ padding: 2em 1em;
+ text-align: left;
+}
+
+.panel {
+ width: 30em;
+ margin: 1em auto;
+ }
+ """
+
+ # test
+ TITLE = u"Hello World"
+
+ def process (self) :
+ self.color = (
+ self.request.form.get('r'),
+ self.request.form.get('g'),
+ self.request.form.get('b'),
+ )
+
+ self.color = tuple((int(x, 16) if x else None) for x in self.color)
+
+ if self.request.method == 'POST' :
+ r, g, b = self.color
+
+ self.app.dmx_color(r, g, b, 255)
+
+ log.info("%s", self.color)
+
+ def render (self) :
+ r, g, b = self.color
+
+ def color_input (name, value) :
+ color = dict(r=0, g=0, b=0)
+ bgcolor = dict(r=0, g=0, b=0)
+
+ if value :
+ color[name] = value
+ bgcolor[name] = 255
+
+ return html.input(type='text', name=name, class_='form-control', placeholder=name,
+ value = '{:02x}'.format(value),
+ #style = 'background-color: #{r:02x}{g:02x}{b:02x}'.format(**color),
+ style = 'background-color: rgba({r}, {g}, {b}, {a})'.format(a=value, **bgcolor),
+ )
+
+ return html.div(class_='container')(
+ html.div(class_='panel')(
+ html.form(action='.', method='POST', class_='form-horizontal')(
+ html.div(class_='form-group')(
+ html.label(for_='color', class_='control-label')("Color"),
+ color_input('r', r),
+ color_input('g', g),
+ color_input('b', b),
+ ),
+ html.div(class_='form-group')(
+ html.button(type='submit', class_='btn btn-primary')("Go"),
+ ),
+ )
+ )
+ )
+
+class DMXWebApplication (pvl.web.Application) :
+ URLS = urls.Map((
+ urls.rule('/', Handler),
+ ))
+
+ def __init__ (self, dmx, **opts) :
+ super(DMXWebApplication, self).__init__(**opts)
+
+ self.dmx = dmx
+
+ def dmx_color (self, r, g, b, a=255) :
+ for c in (1, 30) :
+ self.dmx[c + 0:c + 26:3] = r
+ self.dmx[c + 1:c + 26:3] = g
+ self.dmx[c + 2:c + 26:3] = b
+ self.dmx[c + 28] = 255
+