Changeset - 5a4e90b2bcc3
[Not reviewed]
default
0 6 1
Drew Perttula - 9 years ago 2016-06-10 19:50:31
drewp@bigasterisk.com
redo live control, DeviceClass
Ignore-this: 9d5b1ac3614d583e29f4d3b7043e432d
7 files changed with 223 insertions and 62 deletions:
0 comments (0 inline, 0 general)
light9/collector/device.py
Show inline comments
 
from __future__ import division
 
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')
 

	
 
class Device(object):
 
    def setAttrs():
 
@@ -25,15 +26,19 @@ class Mini15(Device):
 
        rx, ry
 
        color
 
        gobo
 
        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):
 
    """
 
    return one value to use for this attr, given a set of them that
 
    have come in simultaneously. len(values) >= 1.
 
    """
 
@@ -48,35 +53,40 @@ def resolve(deviceType, deviceAttr, valu
 
def toOutputAttrs(deviceType, deviceAttrSettings):
 
    """
 
    Given device attr settings like {L9['color']: Literal('#ff0000')},
 
    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)
 
        return {
 
            L9['mode']: 215,
 
            L9['red']: r,
 
            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
 
        ry8 = float(inp.get(L9['ry'], 0)) / 240 * 255
 
        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,
 
            L9['red']: r,
 
            L9['green']: g,
 
            L9['blue']: b,
light9/web/live/index.html
Show inline comments
 
@@ -10,87 +10,103 @@
 
    <link rel="import" href="/lib/iron-ajax/iron-ajax.html">
 
    <link rel="import" href="../light9-collector-client.html">
 

	
 
    <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>
 
    
 
       
 
    <dom-module id="light9-live-control">
 
      <template>
 
        <style>
 
         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"
 
                 value="{{pickedColor}}">
 
        </template>
 
      </template>
 
     
 
    </dom-module>
 
    
 
    <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
 
                   client="{{client}}"
 
                   device="http://light9.bigasterisk.com/device/moving1"
 
                   attr="http://light9.bigasterisk.com/rx" max="540"
 
               ></light9-live-control>
 
            ry <light9-live-control
 
                   client="{{client}}"
 
                   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>    
 

	
 
    <script src="live.js"></script>   
 
  </body>
light9/web/live/live.coffee
Show inline comments
 
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
light9/web/rdfdb-synced-graph.html
Show inline comments
 
@@ -22,12 +22,14 @@
 
           graph: {type: Object, notify: true},
 
           status: {type: String, notify: true}
 
       },
 
       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;
 
       }
 
   });
 
  </script>
light9/web/rdfdbclient.coffee
Show inline comments
 
@@ -80,13 +80,14 @@ class window.RdfDbClient
 
    console.log('queue patch to server ', patchSizeSummary(patch))
 
    @_patchesToSend.push(patch)
 
    @_updateStatus()
 
    @_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)
 

	
 
    @ws.onopen = =>
 
      log('connected to', fullUrl)
 
      @_updateStatus()
show/dance2016/deviceClass.n3
Show inline comments
 
new file 100644
 
@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 ] .
show/dance2016/theaterLightConfig.n3
Show inline comments
 
@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 ] .
 
# [ :name "cyc-left"; :output dmx:c44 ] .
 
# [ :name "oran1"; :output dmx:c21 ] .
 
# [ :name "oran2"; :output dmx:c25 ] .
0 comments (0 inline, 0 general)