changeset 1522:69088fe2865e

more progress on paint Ignore-this: ff24e7a8e8f95bde364841c6076e839
author Drew Perttula <drewp@bigasterisk.com>
date Sat, 15 Apr 2017 19:16:32 +0000
parents 15f296550447
children 23cabb70699b
files bin/paintserver light9/paint/solve.py light9/paint/solve_test.py light9/web/paint/bg2.jpg light9/web/paint/paint-elements.coffee light9/web/paint/paint-elements.html makefile requirements.txt show/dance2017/cam/test/bg.n3 show/dance2017/cam/test/bg2-a.jpg show/dance2017/cam/test/bg2-b.jpg show/dance2017/cam/test/bg2-c.jpg show/dance2017/cam/test/bg2-d.jpg show/dance2017/cam/test/bg2-e.jpg show/dance2017/cam/test/bg2-f.jpg show/dance2017/deviceClass.n3 show/dance2017/theaterLightConfig.n3
diffstat 17 files changed, 382 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/bin/paintserver	Sat Apr 15 04:03:28 2017 +0000
+++ b/bin/paintserver	Sat Apr 15 19:16:32 2017 +0000
@@ -15,12 +15,15 @@
 import light9.paint.solve
 from lib.cycloneerr import PrettyErrorHandler
 
+
 class Solve(PrettyErrorHandler, cyclone.web.RequestHandler):
     def post(self):
         painting = json.loads(self.request.body)
         reload(light9.paint.solve)
+        solver = light9.paint.solve.Solver(self.settings.graph)
+        solver.loadSamples()
         with self.settings.stats.solve.time():
-            out = light9.paint.solve.solve(painting)
+            out = solver.solve(painting)
         self.write(json.dumps(out))
 
 class App(object):
--- a/light9/paint/solve.py	Sat Apr 15 04:03:28 2017 +0000
+++ b/light9/paint/solve.py	Sat Apr 15 19:16:32 2017 +0000
@@ -1,2 +1,47 @@
-def solve(painting):
-    return 0
+from light9.namespaces import RDF, L9
+from PIL import Image
+import scipy.misc
+import cairo
+
+class Solver(object):
+    def __init__(self, graph):
+        self.graph = graph
+        self.samples = {} # uri: Image array
+        
+    def loadSamples(self):
+        """learn what lights do from images"""
+
+        with self.graph.currentState() as g:
+            for samp in g.subjects(RDF.type, L9['LightSample']):
+                path = 'show/dance2017/cam/test/%s' % g.value(samp, L9['path'])
+                img = Image.open(path)
+                img.thumbnail((100, 100))
+                self.samples[samp] = scipy.misc.fromimage(img, mode='RGB')
+
+    def draw(self, painting, w, h):
+        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
+        ctx = cairo.Context(surface)
+        ctx.move_to(0, 0)
+        ctx.line_to(100,30)
+        
+        ctx.set_source_rgb(0.3, 0.2, 0.5)
+        ctx.set_line_width(20)
+        ctx.stroke()
+        # then blur?
+        surface.write_to_png('/tmp/surf.png')
+                
+    def solve(self, painting):
+        """
+        given strokes of colors on a photo of the stage, figure out the
+        best light settings to match the image
+        """
+        self.draw(painting, 100, 80)
+        return 0
+
+
+    def simulationLayers(self, settings):
+        """
+        how should a simulation preview approximate the light settings
+        (device attribute values) by combining photos we have?
+        """
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/light9/paint/solve_test.py	Sat Apr 15 19:16:32 2017 +0000
@@ -0,0 +1,12 @@
+import unittest
+import solve
+
+class TestSolve(unittest.TestCase):
+    def testBlack(self):
+        s = solve.Solver()
+        s.loadSamples()
+        devAttrs = s.solve({'strokes': []})
+        self.assertEqual([], devAttrs)
+
+
+        
Binary file light9/web/paint/bg2.jpg has changed
--- a/light9/web/paint/paint-elements.coffee	Sat Apr 15 04:03:28 2017 +0000
+++ b/light9/web/paint/paint-elements.coffee	Sat Apr 15 19:16:32 2017 +0000
@@ -1,7 +1,18 @@
+class Painting
+  constructor: ->
+    @strokes = []
+
+  addStroke: (pts, color) ->
+    @strokes.push({pts: pts, color: color})
+
+  getDoc: ->
+    {strokes: @strokes}
+
 class Stroke
-  constructor: (pos) ->
+  constructor: (pos, @color) ->
     @path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
     @path.setAttributeNS(null, 'd', "M #{pos[0]} #{pos[1]}")
+    @pts = [pos]
     @lastPos = pos
 
   appendElem: (parent) ->
@@ -11,6 +22,7 @@
     if Math.hypot(pos[0] - @lastPos[0], pos[1] - @lastPos[1]) < 30
       return
     @path.attributes.d.value += " L #{pos[0]} #{pos[1]}"
+    @pts.push(pos)
     @lastPos = pos
   
 Polymer
@@ -20,6 +32,7 @@
   properties: {
   }
   ready: ->
+    @painting = new Painting()
     @$.paint.addEventListener('mousedown', @onDown.bind(@))
     @$.paint.addEventListener('mousemove', @onMove.bind(@))
     @$.paint.addEventListener('mouseup', @onUp.bind(@))
@@ -28,11 +41,12 @@
     @$.paint.addEventListener('touchend', @onUp.bind(@))
 
   evPos: (ev) ->
-    return (if ev.touches?.length? then [Math.round(ev.touches[0].clientX), Math.round(ev.touches[0].clientY)] else [ev.x, ev.y]) 
+    return (if ev.touches?.length? then [Math.round(ev.touches[0].clientX),
+                                         Math.round(ev.touches[0].clientY)] else [ev.x, ev.y]) 
 
   onDown: (ev) ->
     # if it's on an existing one, do selection
-    @stroke = new Stroke(@evPos(ev))
+    @stroke = new Stroke(@evPos(ev), '#aaaaaa')
     @stroke.appendElem(@$.paint)
     @scopeSubtree(@$.paint)
 
@@ -42,6 +56,9 @@
     @stroke.move(@evPos(ev))
 
   onUp: (ev) ->
+    @painting.addStroke(@stroke.pts, @stroke.color)
+    @$.solve.body = JSON.stringify(@painting.getDoc())
+    @$.solve.generateRequest()
     @stroke = null
 
   onResize: (ev) ->
--- a/light9/web/paint/paint-elements.html	Sat Apr 15 04:03:28 2017 +0000
+++ b/light9/web/paint/paint-elements.html	Sat Apr 15 19:16:32 2017 +0000
@@ -1,5 +1,6 @@
 <link rel="import" href="/lib/polymer/polymer.html">
 <link rel="import" href="/lib/iron-resizable-behavior/iron-resizable-behavior.html">
+<link rel="import" href="/lib/iron-ajax/iron-ajax.html">
 
 <dom-module id="light9-paint">
   <template>
@@ -25,9 +26,9 @@
          stroke-miterlimit:4;
      }
     </style>
-    
+    <iron-ajax id="solve" method="POST" url="../paintServer/solve"></iron-ajax>
     <div id="parent">
-      <img src="bg1.jpg">
+      <img src="bg2.jpg">
       <svg id="paint" viewBox="0 0 500 221">
         <defs id="defs12751">
           <filter
--- a/makefile	Sat Apr 15 04:03:28 2017 +0000
+++ b/makefile	Sat Apr 15 19:16:32 2017 +0000
@@ -1,4 +1,4 @@
-NOSEARGS="--no-path-adjustment light9.rdfdb.rdflibpatch light9.rdfdb.patch light9.effecteval.test_effect light9.collector light9.rdfdb.graphfile_test"
+NOSEARGS="--no-path-adjustment light9.rdfdb.rdflibpatch light9.rdfdb.patch light9.effecteval.test_effect light9.collector light9.rdfdb.graphfile_test light9.paint"
 
 tests:
 	eval env/bin/nosetests -x $(NOSEARGS)
@@ -71,7 +71,7 @@
 	sudo aptitude install python-gi gir1.2-gst-plugins-base-1.0 libgirepository-1.0-1 gir1.2-gstreamer-1.0 gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-pulseaudio python-gst0.10 python-gst-1.0 python-pygoocanvas gir1.2-goocanvas-2.0
 
 packages:
-	sudo aptitude install coffeescript normalize-audio audacity python-pygame libffi-dev tix libzmq3-dev python-dev libssl-dev python-opencv
+	sudo aptitude install coffeescript normalize-audio audacity python-pygame libffi-dev tix libzmq3-dev python-dev libssl-dev python-opencv python-cairo
 
 bower:
 	cd light9/web/lib; bower install
--- a/requirements.txt	Sat Apr 15 04:03:28 2017 +0000
+++ b/requirements.txt	Sat Apr 15 19:16:32 2017 +0000
@@ -21,6 +21,7 @@
 pyusb==1.0.0
 rdflib==4.2.2
 restkit==4.2.2
+scipy==0.19.0
 service_identity==16.0.0
 statprof==0.1.2
 toposort==1.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/show/dance2017/cam/test/bg.n3	Sat Apr 15 19:16:32 2017 +0000
@@ -0,0 +1,40 @@
+@prefix : <http://light9.bigasterisk.com/> .
+@prefix dev: <http://light9.bigasterisk.com/device/> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xml: <http://www.w3.org/XML/1998/namespace> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+@prefix set: <http://light9.bigasterisk.com/setting/> .
+
+
+:sample0 a :LightSample; :path "bg2-a.jpg"; :setting 
+[ :device dev:aura1; :deviceAttr :color;     :scaledValue "#ffffff" ],
+[ :device dev:aura1; :deviceAttr :rx;     :value 0.2 ],
+[ :device dev:aura1; :deviceAttr :ry;     :value 0.573 ] .
+
+:sample1 a :LightSample; :path "bg2-b.jpg"; :setting 
+[ :device dev:aura1; :deviceAttr :color;     :scaledValue "#ffffff" ],
+[ :device dev:aura1; :deviceAttr :rx;     :value 0.3 ],
+[ :device dev:aura1; :deviceAttr :ry;     :value 0.573 ] .
+
+:sample2 a :LightSample; :path "bg2-c.jpg"; :setting 
+[ :device dev:aura1; :deviceAttr :color;     :scaledValue "#ffffff" ],
+[ :device dev:aura1; :deviceAttr :rx;     :value 0.4 ],
+[ :device dev:aura1; :deviceAttr :ry;     :value 0.573 ] .
+
+:sample3 a :LightSample; :path "bg2-d.jpg"; :setting 
+[ :device dev:aura1; :deviceAttr :color;     :scaledValue "#ffffff" ],
+[ :device dev:aura1; :deviceAttr :rx;     :value 0.5 ],
+[ :device dev:aura1; :deviceAttr :ry;     :value 0.573 ] .
+
+:sample4 a :LightSample; :path "bg2-e.jpg"; :setting 
+[ :device dev:aura1; :deviceAttr :color;     :scaledValue "#ffffff" ],
+[ :device dev:aura1; :deviceAttr :rx;     :value 0.6 ],
+[ :device dev:aura1; :deviceAttr :ry;     :value 0.573 ] .
+
+:sample5 a :LightSample; :path "bg2-f.jpg"; :setting 
+[ :device dev:aura1; :deviceAttr :color;     :scaledValue "#ffffff" ],
+[ :device dev:aura1; :deviceAttr :rx;     :value 0.7 ],
+[ :device dev:aura1; :deviceAttr :ry;     :value 0.573 ] .
+
Binary file show/dance2017/cam/test/bg2-a.jpg has changed
Binary file show/dance2017/cam/test/bg2-b.jpg has changed
Binary file show/dance2017/cam/test/bg2-c.jpg has changed
Binary file show/dance2017/cam/test/bg2-d.jpg has changed
Binary file show/dance2017/cam/test/bg2-e.jpg has changed
Binary file show/dance2017/cam/test/bg2-f.jpg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/show/dance2017/deviceClass.n3	Sat Apr 15 19:16:32 2017 +0000
@@ -0,0 +1,141 @@
+@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 .
+:zoom               a :DeviceAttr; :dataType :scalar ;
+  rdfs:comment "maybe make this a separate 'wide to narrow' type" .
+:focus              a :DeviceAttr; :dataType :scalar .
+:iris               a :DeviceAttr; :dataType :scalar .
+:prism              a :DeviceAttr; :dataType :scalar .
+:strobe             a :DeviceAttr; :dataType :scalar;
+  rdfs:comment "0=none, 1=fastest" .
+:goboSpeed          a :DeviceAttr; :dataType :scalar ;
+  rdfs:comment "0=stopped, 1=rotate the fastest".
+:quantumGoboChoice  a :DeviceAttr; :dataType :choice;
+  :choice :open, :spider, :windmill, :limbo, :brush, :whirlpool, :stars .
+
+: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 ] .
+
+:Source4LedSeries2 a :DeviceClass;
+  :docs <https://www.etcconnect.com/WorkArea/DownloadAsset.aspx?id=10737483869>;
+  :deviceAttr :color;
+  :attr
+    [ :dmxOffset 0; :outputAttr :red ],
+    [ :dmxOffset 1; :outputAttr :green ],
+    [ :dmxOffset 2; :outputAttr :blue ],
+    [ :dmxOffset 4; :outputAttr :strobe ],
+    [ :dmxOffset 7; :outputAttr :fixed255 ],
+    [ :dmxOffset 8; :outputAttr :fixed128_0 ],
+    [ :dmxOffset 9; :outputAttr :fixed128_1 ],
+    [ :dmxOffset 10; :outputAttr :fixed128_2 ],
+    [ :dmxOffset 11; :outputAttr :fixed128_3 ],
+    [ :dmxOffset 12; :outputAttr :fixed128_4 ],
+    [ :dmxOffset 13; :outputAttr :fixed128_5 ],
+    [ :dmxOffset 14; :outputAttr :fixed128_6 ] .
+    
+
+: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";
+  :deviceAttr :color, :rx, :ry, :zoom;
+  :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>;
+  :deviceAttr :color, :rx, :ry, :zoom, :focus, :iris, :prism, :quantumGoboChoice, :goboSpeed, :strobe;
+  :attr
+    [ :dmxOffset 0; :outputAttr :shutter ],
+    [ :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 ] .
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/show/dance2017/theaterLightConfig.n3	Sat Apr 15 19:16:32 2017 +0000
@@ -0,0 +1,112 @@
+@prefix : <http://light9.bigasterisk.com/> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix dev: <http://light9.bigasterisk.com/device/> .
+@prefix udmxB: <http://light9.bigasterisk.com/output/udmx/> .
+@prefix dmxA: <http://light9.bigasterisk.com/output/dmx0/> .
+
+#dev:colorStrip a :ChauvetColorStrip; :dmxUniverse dmxA:; :dmxBase 87 .
+#dev:moving1 a :Mini15; rdfs:label "moving1"; :dmxUniverse udmxB:; :dmxBase 5 .
+
+dev:houseSide a :SimpleDimmer; rdfs:label "house-side"; :dmxUniverse dmxA:; :dmxBase 68 .
+dev:house1 a :SimpleDimmer; rdfs:label "house1"; :dmxUniverse dmxA:; :dmxBase 69 .
+dev:house4 a :SimpleDimmer; rdfs:label "house4"; :dmxUniverse dmxA:; :dmxBase 70 .
+dev:house3 a :SimpleDimmer; rdfs:label "house3"; :dmxUniverse dmxA:; :dmxBase 71 .
+dev:house2 a :SimpleDimmer; rdfs:label "house2"; :dmxUniverse dmxA:; :dmxBase 72 .
+
+dev:f1 a :SimpleDimmer; :dmxUniverse dmxA:; :dmxBase 4 .
+dev:f2 a :SimpleDimmer; :dmxUniverse dmxA:; :dmxBase 8 .
+dev:f3 a :SimpleDimmer; :dmxUniverse dmxA:; :dmxBase 10 .
+
+dev:cycR a :SimpleDimmer; :dmxUniverse dmxA:; :dmxBase 42 .
+dev:cycL a :SimpleDimmer; :dmxUniverse dmxA:; :dmxBase 44 .
+
+dev:q1 a :MacQuantum; :dmxUniverse udmxB:; :dmxBase 325 .
+dev:q1 :outputAttrRange dev:q1rx . dev:q1rx :outputAttr :rx; :start 0.143; :end 0.271 .
+dev:q1 :outputAttrRange dev:q1ry . dev:q1ry :outputAttr :ry; :start 0.71; :end 0.821 .
+dev:q2 a :MacQuantum; :dmxUniverse udmxB:; :dmxBase 352 .
+dev:q2 :outputAttrRange dev:q2rx . dev:q2rx :outputAttr :rx; :start 0.097; :end 0.227 .
+dev:q2 :outputAttrRange dev:q2ry . dev:q2ry :outputAttr :ry; :start 0.739; :end 0.824 .
+dev:q3 a :MacQuantum; :dmxUniverse udmxB:; :dmxBase 379 .
+dev:q3 :outputAttrRange dev:q3rx . dev:q3rx :outputAttr :rx; :start 0.064; :end 0.198 .
+dev:q3 :outputAttrRange dev:q3ry . dev:q3ry :outputAttr :ry; :start 0.765; :end 0.822 .
+
+dev:aura1 a :MacAura; :dmxUniverse udmxB:; :dmxBase 406 .
+dev:aura2 a :MacAura; :dmxUniverse udmxB:; :dmxBase 420 .
+dev:aura3 a :MacAura; :dmxUniverse udmxB:; :dmxBase 434 .
+dev:aura4 a :MacAura; :dmxUniverse udmxB:; :dmxBase 448 .
+dev:aura5 a :MacAura; :dmxUniverse udmxB:; :dmxBase 462 .
+
+dev:aura1 :outputAttrRange dev:aura1rx . dev:aura1rx :outputAttr :rx; :start 0.145; :end 0.275 .
+dev:aura2 :outputAttrRange dev:aura2rx . dev:aura2rx :outputAttr :rx; :start 0.096; :end 0.259 .
+dev:aura3 :outputAttrRange dev:aura3rx . dev:aura3rx :outputAttr :rx; :start 0.068; :end 0.25 .
+dev:aura4 :outputAttrRange dev:aura4rx . dev:aura4rx :outputAttr :rx; :start 0.065; :end 0.21 .
+dev:aura5 :outputAttrRange dev:aura5rx . dev:aura5rx :outputAttr :rx; :start 0.06; :end 0.194 .
+
+dev:aura1 :outputAttrRange dev:aura1ry . dev:aura1ry :outputAttr :ry; :start 0.239; :end 0.153 .
+dev:aura2 :outputAttrRange dev:aura2ry . dev:aura2ry :outputAttr :ry; :start 0.248; :end 0.148 .
+dev:aura3 :outputAttrRange dev:aura3ry . dev:aura3ry :outputAttr :ry; :start 0.260; :end 0.151 .
+dev:aura4 :outputAttrRange dev:aura4ry . dev:aura4ry :outputAttr :ry; :start 0.250; :end 0.153 .
+dev:aura5 :outputAttrRange dev:aura5ry . dev:aura5ry :outputAttr :ry; :start 0.241; :end 0.151 .
+
+
+dev:auraStage a :MacAura; :dmxUniverse udmxB:; :dmxBase 476; rdfs:comment "rx=.5 ry<.45" .
+
+dev:down2 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 157 .
+dev:down3 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 193 .
+dev:down4 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 169 .
+dev:down5Edge a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 175 .
+dev:backlight1 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 241 .
+dev:backlight2 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 247 .
+dev:backlight3 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 253 .
+dev:backlight4 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 259 .
+dev:backlight5 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 265 .
+dev:hexLow3 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 223 .
+dev:hexLow5 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 229 .
+dev:hexLowBacklight1 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 211 .
+dev:hexLowBacklight6 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 235 .
+dev:hexSlant a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 319 .
+dev:lip1 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 121 .
+dev:lip2 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 127 .
+dev:lip3 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 133 . 
+dev:lip4 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 139 .
+dev:lip5 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 145 . 
+dev:postL1 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 289 .
+dev:postL2 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 295 .
+dev:postL3 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 301 .
+dev:postR1 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 271 .
+dev:postR2 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 277 .
+dev:postR3 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 283 .
+dev:upCenter a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 313 .
+dev:veryLow1 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 151 .
+dev:veryLow2 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 187 .
+dev:veryLow22 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 217 .
+dev:veryLow3 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 163 .
+dev:veryLow4 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 199 .
+dev:veryLow5 a :ChauvetHex12; :dmxUniverse udmxB:; :dmxBase 205 .
+
+
+dev:lowPattern301 a :Source4LedSeries2; :dmxUniverse udmxB:; :dmxBase 1 .
+dev:lowPattern302 a :Source4LedSeries2; :dmxUniverse udmxB:; :dmxBase 16 .
+dev:lowPattern303 a :Source4LedSeries2; :dmxUniverse udmxB:; :dmxBase 31 .
+dev:lowPattern304 a :Source4LedSeries2; :dmxUniverse udmxB:; :dmxBase 46 .
+dev:lowPattern305 a :Source4LedSeries2; :dmxUniverse udmxB:; :dmxBase 61 .
+dev:lowPattern306 a :Source4LedSeries2; :dmxUniverse udmxB:; :dmxBase 76 .
+dev:lowPattern307 a :Source4LedSeries2; :dmxUniverse udmxB:; :dmxBase 91 .
+dev:lowPattern308 a :Source4LedSeries2; :dmxUniverse udmxB:; :dmxBase 106 .
+
+# [ :name "oran1"; :output dmx:c21 ] .
+# [ :name "oran2"; :output dmx:c25 ] .
+# [ :name "oran3"; :output dmx:c29 ] .
+# [ :name "oran4"; :output dmx:c33 ] .
+# [ :name "gree1"; :output dmx:c22 ] .
+# [ :name "gree2"; :output dmx:c26 ] .
+# [ :name "gree3"; :output dmx:c30 ] .
+# [ :name "gree4"; :output dmx:c34 ] .
+# [ :name "blue1"; :output dmx:c23 ] .
+# [ :name "blue2"; :output dmx:c27 ] .
+# [ :name "blue3"; :output dmx:c31 ] .
+# [ :name "blue4"; :output dmx:c35 ] .
+# [ :name "red1"; :output dmx:c24 ] .
+# [ :name "red2"; :output dmx:c28 ] .
+# [ :name "red3"; :output dmx:c32 ] .
+# [ :name "red4"; :output dmx:c36 ] .