changeset 1418:5a4e90b2bcc3

redo live control, DeviceClass Ignore-this: 9d5b1ac3614d583e29f4d3b7043e432d
author Drew Perttula <drewp@bigasterisk.com>
date Fri, 10 Jun 2016 19:50:31 +0000
parents 9db73555b129
children d3ad831e198e
files light9/collector/device.py light9/web/live/index.html light9/web/live/live.coffee light9/web/rdfdb-synced-graph.html light9/web/rdfdbclient.coffee show/dance2016/deviceClass.n3 show/dance2016/theaterLightConfig.n3
diffstat 7 files changed, 223 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/light9/collector/device.py	Fri Jun 10 16:54:34 2016 +0000
+++ b/light9/collector/device.py	Fri Jun 10 19:50:31 2016 +0000
@@ -2,6 +2,7 @@
 import logging
 import math
 from light9.namespaces import L9, RDF, DEV
+from rdflib import Literal
 from webcolors import hex_to_rgb, rgb_to_hex
 
 log = logging.getLogger('device')
@@ -28,9 +29,13 @@
         goboShake
         imageAim (configured with a file of calibration data)
     """
-
+def clamp255(x):
+    return min(255, max(0, x))
+    
 def _8bit(f):
-    return min(255, max(0, int(f * 255)))
+    if not isinstance(f, float):
+        raise TypeError(repr(f))
+    return clamp255(int(f * 255))
 
 def resolve(deviceType, deviceAttr, values):
     """
@@ -51,6 +56,12 @@
     return a similar dict where the keys are output attrs (like
     L9['red']) and the values are suitable for Collector.setAttr
     """
+    def floatAttr(attr, default=0):
+        out = deviceAttrSettings.get(attr)
+        if out is None:
+            return default
+        return float(out.toPython())
+        
     if deviceType == L9['ChauvetColorStrip']:
         color = deviceAttrSettings.get(L9['color'], '#000000')
         r, g, b = hex_to_rgb(color)
@@ -60,9 +71,8 @@
             L9['green']: g,
             L9['blue']: b
             }
-    elif deviceType == L9['Dimmer']:
-        return {L9['brightness']:
-                _8bit(deviceAttrSettings.get(L9['brightness'], 0))}
+    elif deviceType == L9['SimpleDimmer']:
+        return {L9['level']: _8bit(floatAttr(L9['brightness']))}
     elif deviceType == L9['Mini15']:
         inp = deviceAttrSettings
         rx8 = float(inp.get(L9['rx'], 0)) / 540 * 255
@@ -70,10 +80,10 @@
         r, g, b = hex_to_rgb(inp.get(L9['color'], '#000000'))
 
         return {
-            L9['xRotation']: int(math.floor(rx8)),
+            L9['xRotation']: clamp255(int(math.floor(rx8))),
             # didn't find docs on this, but from tests it looks like 64 fine steps takes you to the next coarse step
             L9['xFine']: _8bit(1 - (rx8 % 1.0)),
-            L9['yRotation']: int(math.floor(ry8)),
+            L9['yRotation']: clamp255(int(math.floor(ry8))),
             L9['yFine']: _8bit((ry8 % 1.0) / 4),
             L9['rotationSpeed']: 0,
             L9['dimmer']: 255,
--- a/light9/web/live/index.html	Fri Jun 10 16:54:34 2016 +0000
+++ b/light9/web/live/index.html	Fri Jun 10 19:50:31 2016 +0000
@@ -13,7 +13,7 @@
     <script src="/lib/d3/build/d3.min.js"></script>
     <script src="/lib/N3.js-pull61/browser/n3-browser.js"></script>
     <script src="/lib/async/dist/async.js"></script>
-    
+    <script src="/lib/underscore/underscore-min.js"></script>
     <link rel="import" href="../rdfdb-synced-graph.html">
   </head>
   <body>
@@ -25,15 +25,15 @@
          paper-slider { width: 100%; }
         </style>
 
-        <template is="dom-if" if="{{useSlider}}">
+        <template is="dom-if" if="{{deviceAttr.useSlider}}">
           <paper-slider min="0"
-                        max="{{max}}"
+                        max="{{deviceAttr.max}}"
                         step=".01"
                         editable
                         content-type="application/json"
                         immediate-value="{{immediateSlider}}"></paper-slider>
         </template>
-        <template is="dom-if" if="{{useColor}}">
+        <template is="dom-if" if="{{deviceAttr.useColor}}">
           <input type="color"
                  id="col"
                  on-input="onPickedColor"
@@ -46,21 +46,48 @@
     <dom-module id="light9-live-controls">
       <template>
         <style>
+         .device {
+             border: 2px solid gray;
+             border: 2px solid gray;
+             margin: 9px;
+             padding: 5px;
+             background: #171717;
+         }
+         .deviceAttr {
+             border-top: 1px solid #ffffff26;
+             margin-top: 6px;
+             padding-top: 4px;
+         }
+         h2 {
+             font-size: 122%;
+             padding: 4px;
+             background: #1f1f1f;
+         }
         </style>
         <rdfdb-synced-graph graph="{{graph}}"></rdfdb-synced-graph>
 
         <light9-collector-client self="{{client}}"></light9-collector-client>
         <h1>live</h1>
 
+        <template is="dom-repeat" items="{{devices}}" as="device">
+          <div class="device">
+            <h2><a href="{{device.uri}}">{{device.label}}</a></h2>
+            device is
+            <a href="{{device.deviceClass}}">{{device.deviceClass}}</a>
+            <template is="dom-repeat" items="{{device.deviceAttrs}}" as="dattr">
+              <div class="deviceAttr">
+                attr <a href="{{dattr.uri}}">{{dattr.uri}}</a>
+                <light9-live-control
+                    client="{{client}}"
+                    device="{{device.uri}}"
+                    device-attr="{{dattr}}"></light9-live-control>
+              </div>
+            </template>
+          </div>
+        </template>
+        
         <ul>
-          <li>
-            <h2>colorstrip</h2>
-            <light9-live-control
-                client="{{client}}"
-                device="http://light9.bigasterisk.com/device/colorStrip"
-                attr="http://light9.bigasterisk.com/color"
-            ></light9-live-control>
-          </li>
+        
           <li>
             <h2>moving</h2>
             rx <light9-live-control
@@ -73,21 +100,10 @@
                    device="http://light9.bigasterisk.com/device/moving1"
                    attr="http://light9.bigasterisk.com/ry" max="240"
                ></light9-live-control>
-            color <light9-live-control
-                      client="{{client}}"
-                      device="http://light9.bigasterisk.com/device/moving1"
-                      attr="http://light9.bigasterisk.com/color"
-                  ></light9-live-control>
+          
           </li>
         </ul>
       </template>
-      <script>
-       HTMLImports.whenReady(function () {
-           Polymer({
-               is: "light9-live-controls",
-           });
-       });
-      </script>
     </dom-module>
     
     <light9-live-controls></light9-live-controls>    
--- a/light9/web/live/live.coffee	Fri Jun 10 16:54:34 2016 +0000
+++ b/light9/web/live/live.coffee	Fri Jun 10 19:50:31 2016 +0000
@@ -1,21 +1,61 @@
+log = console.log
 
 Polymer
   is: 'light9-live-control'
   properties:
     client: { type: Object }
     device: { type: String }
-    attr: { type: String }
+    deviceAttr: { type: Object }
     max: { type: Number, value: 1 }
     immediateSlider: { notify: true, observer: 'onChange' }
-    useSlider: { type: Boolean, computed: '_useSlider(attr)' }
-    useColor: { type: Boolean, computed: '_useColor(attr)' }
     pickedColor: { observer: 'onPickedColor' }
   ready: ->
   onPickedColor: (ev) ->
     @onChange ev.target.value
   onChange: (lev) ->
-    @client.send([[@device, @attr, lev]])
-  _useSlider: (attr) ->
-    attr != 'http://light9.bigasterisk.com/color'
-  _useColor: (attr) ->
-    attr == 'http://light9.bigasterisk.com/color'
+    @client.send([[@device, @deviceAttr.uri, lev]])
+  
+Polymer
+  is: "light9-live-controls"
+  properties:
+    graph: { type: Object, notify: true }
+    devices: { type: Array, notify: true }
+  observers: [
+    'onGraph(graph)'
+    ]
+  onGraph: ->
+    @graph.runHandler(@update.bind(@))
+  update: ->
+    U = (x) -> @graph.Uri(x)
+
+    @set('devices', [])
+    for dc in _.sortBy(@graph.subjects(U('rdf:type'), U(':DeviceClass')))
+      log('dc', dc)      
+      for dev in _.sortBy(@graph.subjects(U('rdf:type'), dc))
+        log('dev', dev)
+        row = {uri: dev, label: (try
+            @graph.stringValue(dev, U('rdfs:label'))
+          catch
+            dev), deviceClass: dc}
+        row.deviceAttrs = []
+        for da in _.sortBy(@graph.objects(dc, U(':deviceAttr')))
+          dataType = @graph.uriValue(da, U(':dataType'))
+          daRow = {
+            uri: da
+            dataType: dataType
+            showColorPicker: dataType == U(':color')
+            }
+          if da == 'http://light9.bigasterisk.com/color'
+            daRow.useColor = true
+            daRow.useSlider = false
+          else
+            daRow.useColor = false
+            daRow.useSlider = true
+            daRow.max = 1
+            if dataType == U(':angle')
+              # varies
+              daRow.max = 360
+          
+          row.deviceAttrs.push(daRow)
+        
+        @push('devices', row)
\ No newline at end of file
--- a/light9/web/rdfdb-synced-graph.html	Fri Jun 10 16:54:34 2016 +0000
+++ b/light9/web/rdfdb-synced-graph.html	Fri Jun 10 19:50:31 2016 +0000
@@ -25,6 +25,8 @@
        ready: function() {
            this.graph = new SyncedGraph('/rdfdb/syncedGraph', {
                '': 'http://light9.bigasterisk.com/',
+               'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
+               'rdfs': 'http://www.w3.org/2000/01/rdf-schema#',
                'xsd': 'http://www.w3.org/2001/XMLSchema#',
            }, function(s) { this.status = s; }.bind(this));
            window.graph = this.graph;
--- a/light9/web/rdfdbclient.coffee	Fri Jun 10 16:54:34 2016 +0000
+++ b/light9/web/rdfdbclient.coffee	Fri Jun 10 19:50:31 2016 +0000
@@ -83,7 +83,8 @@
     @_continueSending()           
 
   _newConnection: ->
-    fullUrl = 'ws://' + window.location.host + @patchSenderUrl
+    wsOrWss = window.location.protocol.replace('http', 'ws')
+    fullUrl = wsOrWss + '//' + window.location.host + @patchSenderUrl
     @ws.close() if @ws?
     @ws = new WebSocket(fullUrl)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/show/dance2016/deviceClass.n3	Fri Jun 10 19:50:31 2016 +0000
@@ -0,0 +1,110 @@
+@prefix : <http://light9.bigasterisk.com/> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+:color a :DeviceAttr; :dataType :color .
+:rx a :DeviceAttr; :dataType :angle .
+:ry a :DeviceAttr; :dataType :angle .
+:uv a :DeviceAttr; :dataType :scalar .
+:brightness a :DeviceAttr; :dataType :scalar .
+
+:SimpleDimmer a :DeviceClass;
+  :deviceAttr :brightness;
+  :attr
+    [ :outputAttr :level; :dmxOffset 0 ] .
+
+:ChauvetColorStrip a :DeviceClass;
+  :deviceAttr :color;
+  :attr
+    [ :outputAttr :mode;  :dmxOffset 0 ],
+    [ :outputAttr :red;   :dmxOffset 1 ],
+    [ :outputAttr :green; :dmxOffset 2 ],
+    [ :outputAttr :blue;  :dmxOffset 3 ] .
+
+:Mini15 a :DeviceClass;
+  :deviceAttr :color, :rx, :ry;
+  :attr
+    [ :outputAttr :xRotation;     :dmxOffset 0 ],
+    [ :outputAttr :xFine;         :dmxOffset 1 ],
+    [ :outputAttr :yRotation;     :dmxOffset 2 ],
+    [ :outputAttr :yFine;         :dmxOffset 3 ],
+    [ :outputAttr :rotationSpeed; :dmxOffset 4 ],
+    [ :outputAttr :dimmer;        :dmxOffset 5 ],
+    [ :outputAttr :red;           :dmxOffset 6 ],
+    [ :outputAttr :green;         :dmxOffset 7 ],
+    [ :outputAttr :blue;          :dmxOffset 8 ],
+    [ :outputAttr :colorChange;   :dmxOffset 9 ],
+    [ :outputAttr :colorSpeed;    :dmxOffset 10 ],
+    [ :outputAttr :goboShake;     :dmxOffset 11 ],
+    [ :outputAttr :goboChoose;    :dmxOffset 12 ] .
+
+:ChauvetHex12 a :DeviceClass;
+  :deviceAttr :color, :uv;
+  :docs <https://www.chauvetprofessional.com/wp-content/uploads/2015/06/COLORdash_Par-Hex_12_QRG_Rev4_ML4_WO.pdf>;
+  :attr
+    [ :outputAttr :red; :dmxOffset 0 ],
+    [ :outputAttr :green; :dmxOffset 1 ],
+    [ :outputAttr :blue; :dmxOffset 2 ],
+    [ :outputAttr :amber; :dmxOffset 3 ],
+    [ :outputAttr :white; :dmxOffset 4 ],
+    [ :outputAttr :uv; :dmxOffset 5 ] .
+
+:MacAura a :DeviceClass;
+  :docs <http://www.martin.com/Martin.Download.aspx?file=/files/files/productdocuments/11_MANUALS/999/UM_MACAura_EN_B.pdf>;
+  rdfs:comment "note- manual counts dmx from 1; :dmxOffset is from 0";
+  :attr
+    [ :dmxOffset 0 ; :outputAttr :shutter ], # use 22
+    [ :dmxOffset 1 ; :outputAttr :dimmer ],
+    [ :dmxOffset 2 ; :outputAttr :zoom ],
+    [ :dmxOffset 3 ; :outputAttr :pan ],
+    [ :dmxOffset 4 ; :outputAttr :panFine ],
+    [ :dmxOffset 5 ; :outputAttr :tilt ],
+    [ :dmxOffset 6 ; :outputAttr :tiltFine ],
+    [ :dmxOffset 7 ; :outputAttr :fixtureControl ], # use 0
+    [ :dmxOffset 8 ; :outputAttr :colorWheel ], # use 0
+    [ :dmxOffset 9 ; :outputAttr :red ],
+    [ :dmxOffset 10 ; :outputAttr :green ],
+    [ :dmxOffset 11 ; :outputAttr :blue ],
+    [ :dmxOffset 12 ; :outputAttr :white ],
+    [ :dmxOffset 13 ; :outputAttr :colorTemperature ],
+    [ :dmxOffset 14 ; :outputAttr :fx1Select ],
+    [ :dmxOffset 15 ; :outputAttr :fx1Adjust ],
+    [ :dmxOffset 16 ; :outputAttr :fx2Select ],
+    [ :dmxOffset 17 ; :outputAttr :fx2Adjust ],
+    [ :dmxOffset 18 ; :outputAttr :fxSync ],
+    [ :dmxOffset 19 ; :outputAttr :auraShutter ], # use 22
+    [ :dmxOffset 20 ; :outputAttr :auraDimmer ],
+    [ :dmxOffset 21 ; :outputAttr :auraColorWheel ],
+    [ :dmxOffset 22 ; :outputAttr :auraRed ],
+    [ :dmxOffset 23 ; :outputAttr :auraGreen ],
+    [ :dmxOffset 24 ; :outputAttr :auraBlue ] .
+
+:MacQuantum a :DeviceClass; 
+  :docs <http://www.martin.com/Martin.Download.aspx?file=/files/files/productdocuments/11_MANUALS/999/35000279b%20UM_MACQuantumProfile_EN_B.pdf>;
+  :attr
+    [ :dmxOffset 0; :outputAttr :shutter ; rdfs:comment "use 30" ],
+    [ :dmxOffset 1; :outputAttr :dimmerFadeHi ],
+    [ :dmxOffset 2; :outputAttr :dimmerFadeLo ],
+    [ :dmxOffset 3; :outputAttr :cyan ],
+    [ :dmxOffset 4; :outputAttr :magenta ],
+    [ :dmxOffset 5; :outputAttr :yellow ],
+    [ :dmxOffset 6; :outputAttr :colorWheel ; rdfs:comment "use 0" ],
+    [ :dmxOffset 7; :outputAttr :goboChoice ],
+    [ :dmxOffset 8; :outputAttr :goboSpeedHi ],
+    [ :dmxOffset 9; :outputAttr :goboSpeedLo ],
+    [ :dmxOffset 10; :outputAttr :goboStaticRotate ],
+    [ :dmxOffset 11; :outputAttr :prismRotation ],
+    [ :dmxOffset 12; :outputAttr :iris ],
+    [ :dmxOffset 13; :outputAttr :zoomHi ],
+    [ :dmxOffset 14; :outputAttr :zoomLo ],
+    [ :dmxOffset 15; :outputAttr :focusHi ],
+    [ :dmxOffset 16; :outputAttr :focusLo ],
+    [ :dmxOffset 17; :outputAttr :panHi ],
+    [ :dmxOffset 18; :outputAttr :panLo ],
+    [ :dmxOffset 19; :outputAttr :tiltHi ],
+    [ :dmxOffset 20; :outputAttr :tiltLo ],
+    [ :dmxOffset 21; :outputAttr :fixtureControl ; rdfs:comment "use 0" ],
+    [ :dmxOffset 22; :outputAttr :fx1Select ],
+    [ :dmxOffset 23; :outputAttr :fx1Adjust ],
+    [ :dmxOffset 24; :outputAttr :fx2Select ],
+    [ :dmxOffset 25; :outputAttr :fx2Adjust ],
+    [ :dmxOffset 26; :outputAttr :fxSync ] .
--- a/show/dance2016/theaterLightConfig.n3	Fri Jun 10 16:54:34 2016 +0000
+++ b/show/dance2016/theaterLightConfig.n3	Fri Jun 10 19:50:31 2016 +0000
@@ -1,32 +1,14 @@
 @prefix : <http://light9.bigasterisk.com/> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 @prefix dev: <http://light9.bigasterisk.com/device/> .
 @prefix udmx: <http://light9.bigasterisk.com/output/udmx/> .
 @prefix dmx0: <http://light9.bigasterisk.com/output/dmx0/> .
 
-:ChauvetColorStrip a :DeviceClass .
-:ChauvetColorStrip :attr :ccsa0 . :ccsa0 :outputAttr :mode;  :dmxOffset 0 .
-:ChauvetColorStrip :attr :ccsa1 . :ccsa1 :outputAttr :red;   :dmxOffset 1 .
-:ChauvetColorStrip :attr :ccsa2 . :ccsa2 :outputAttr :green; :dmxOffset 2 .
-:ChauvetColorStrip :attr :ccsa3 . :ccsa3 :outputAttr :blue;  :dmxOffset 3 .
-
-:Mini15 a :DeviceClass .
-:Mini15 :attr :Mini15a0 .  :Mini15a0  :outputAttr :xRotation;     :dmxOffset 0 .
-:Mini15 :attr :Mini15a1 .  :Mini15a1  :outputAttr :xFine;         :dmxOffset 1 .
-:Mini15 :attr :Mini15a2 .  :Mini15a2  :outputAttr :yRotation;     :dmxOffset 2 .
-:Mini15 :attr :Mini15a3 .  :Mini15a3  :outputAttr :yFine;         :dmxOffset 3 .
-:Mini15 :attr :Mini15a4 .  :Mini15a4  :outputAttr :rotationSpeed; :dmxOffset 4 .
-:Mini15 :attr :Mini15a5 .  :Mini15a5  :outputAttr :dimmer;        :dmxOffset 5 .
-:Mini15 :attr :Mini15a6 .  :Mini15a6  :outputAttr :red;           :dmxOffset 6 .
-:Mini15 :attr :Mini15a7 .  :Mini15a7  :outputAttr :green;         :dmxOffset 7 .
-:Mini15 :attr :Mini15a8 .  :Mini15a8  :outputAttr :blue;          :dmxOffset 8 .
-:Mini15 :attr :Mini15a9 .  :Mini15a9  :outputAttr :colorChange;   :dmxOffset 9 .
-:Mini15 :attr :Mini15a10 . :Mini15a10 :outputAttr :colorSpeed;    :dmxOffset 10 .
-:Mini15 :attr :Mini15a11 . :Mini15a11 :outputAttr :goboShake;     :dmxOffset 11 .
-:Mini15 :attr :Mini15a12 . :Mini15a12 :outputAttr :goboChoose;    :dmxOffset 12 .
-
 dev:colorStrip a :ChauvetColorStrip; :dmxUniverse dmx0:; :dmxBase 87 .
 
-dev:moving1 a :Mini15; :dmxUniverse udmx:; :dmxBase 1 .
+dev:moving1 a :Mini15; rdfs:label "moving1"; :dmxUniverse udmx:; :dmxBase 5 .
+
+dev:cyc a :SimpleDimmer; rdfs:label "cyc"; :dmxUniverse udmx:; :dmxBase 40 .
 
 # [ :name "cyc-right"; :output dmx:c42 ] .
 # [ :name "cyc-mid"; :output dmx:c43 ] .