qmsk.dmx.web
authorTero Marttila <terom@paivola.fi>
Fri, 11 Apr 2014 21:45:26 +0300
changeset 75 baa33d32308e
parent 74 9031dafa39d6
child 76 ca10547ba9db
qmsk.dmx.web
bin/dmx-web.py
qmsk/dmx/web.py
--- /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
+