Changeset - ba24eeb2853a
[Not reviewed]
default
0 4 0
drewp@bigasterisk.com - 9 years ago 2016-06-12 19:07:00
drewp@bigasterisk.com
effects and config
Ignore-this: dccc8e21c4def7776ed23e975f7b3373
4 files changed with 46 insertions and 14 deletions:
0 comments (0 inline, 0 general)
bin/collector
Show inline comments
 
@@ -17,77 +17,77 @@ from light9.collector.collector import C
 
from light9.namespaces import L9
 
from light9 import networking
 
from light9.rdfdb.syncedgraph import SyncedGraph
 
from light9.rdfdb import clientsession
 

	
 
class WebServer(object):
 
    stats = scales.collection('/webServer',
 
                              scales.PmfStat('setAttr'))
 
    app = klein.Klein()
 
    def __init__(self, collector):
 
        self.collector = collector
 
        
 
    @app.route('/attrs', methods=['PUT'])
 
    def putAttrs(self, request):
 
        with WebServer.stats.setAttr.time():
 
            body = json.load(request.content)
 
            settings = []
 
            for device, attr, value in body['settings']:
 
                settings.append((URIRef(device), URIRef(attr), Literal(value)))
 
            self.collector.setAttrs(body['client'],
 
                                    body['clientSession'],
 
                                    settings)
 
            request.setResponseCode(202)
 

	
 
    @app.route('/stats', methods=['GET'])
 
    def getStats(self, request):
 
        return StatsResource('collector')
 
        
 
def startZmq(port, collector):
 
    stats = scales.collection('/zmqServer',
 
                              scales.PmfStat('setAttr'))
 
    
 
    zf = ZmqFactory()
 
    e = ZmqEndpoint('bind', 'tcp://*:%s' % port)
 
    s = ZmqPullConnection(zf, e)
 
    def onPull(message):
 
        with stats.setAttrZmq.time():
 
            # todo: new compressed protocol where you send all URIs up
 
            # front and then use small ints to refer to devices and
 
            # attributes in subsequent requests.
 
            message[0]
 
            collector.setAttrs()
 
    s.onPull = onPull
 

	
 
def launch(graph):
 

	
 
    # todo: drive outputs with config files
 
    outputs = [
 
        EnttecDmx(L9['output/dmx0/'], '/dev/dmx3', 80),
 
        EnttecDmx(L9['output/dmx0/'], '/dev/dmx0', 80),
 
        Udmx(L9['output/udmx/'], 510),
 
    ]
 
    c = Collector(graph, outputs)
 

	
 
    server = WebServer(c)
 
    startZmq(networking.collectorZmq.port, c)
 
    
 
    reactor.listenTCP(networking.collector.port,
 
                      Site(server.app.resource()),
 
                      interface='::')
 
    log.info('serving http on %s, zmq on %s', networking.collector.port,
 
             networking.collectorZmq.port)
 
    
 
    
 
def main():
 
    parser = optparse.OptionParser()
 
    parser.add_option("-v", "--verbose", action="store_true",
 
                      help="logging.DEBUG")
 
    (options, args) = parser.parse_args()
 
    log.setLevel(logging.DEBUG if options.verbose else logging.INFO)
 

	
 
    graph = SyncedGraph(networking.rdfdb.url, "collector")
 

	
 
    graph.initiallySynced.addCallback(lambda _: launch(graph))
 
    reactor.run()
 

	
 
if __name__ == '__main__':
 
    main()
light9/effect/effecteval.py
Show inline comments
 
@@ -68,86 +68,117 @@ class EffectEval(object):
 
        
 
    def outputFromEffect(self, effectSettings, songTime):
 
        """
 
        From effect attr settings, like strength=0.75, to output device
 
        settings like light1/bright=0.72;light2/bright=0.78. This runs
 
        the effect code.
 
        """
 
        # both callers need to apply note overrides
 
        effectSettings = dict(effectSettings) # we should make everything into nice float and Color objects too
 

	
 
        strength = float(effectSettings[L9['strength']])
 
        if strength <= 0:
 
            return []
 

	
 
        out = {} # (dev, attr): value
 

	
 
        out.update(self.simpleOutput(strength))
 

	
 
        if self.effect.startswith(L9['effect/']):
 
            tail = 'effect_' + self.effect[len(L9['effect/']):]
 
            try:
 
                func = globals()[tail]
 
            except KeyError:
 
                pass
 
            else:
 
                out.update(func(effectSettings, strength, songTime))
 

	
 
        # todo: callers should prefer the dict form too
 
        outList = [(d, a, v) for (d, a), v in out.iteritems()]
 
        outList.sort()
 
        #import pprint; pprint.pprint(outList, width=170)
 
        return outList
 
                            
 
    def simpleOutput(self, strength):
 
        out = {}
 
        for dev, attr, value, isScaled in self.effectOutputs.get(self.effect, []):
 
            if isScaled:
 
                value = scale(value, strength)
 
            out[(dev, attr)] = value
 
        return out
 
        
 

	
 

	
 
    
 

	
 
def effect_Curtain(effectSettings, strength, songTime):
 
    return {
 
        (L9['device/lowPattern%s' % n], L9['color']):
 
        literalColor(0*strength, strength, strength)
 
        literalColor(strength, strength, strength)
 
        for n in range(301,308+1)
 
        }
 
    
 
def effect_animRainbow(effectSettings, strength, songTime):
 
    out = {}
 
    tint = effectSettings.get(L9['tint'], '#ffffff')
 
    tintStrength = float(effectSettings.get(L9['tintStrength'], 0))
 
    print tint, tintStrength
 
    tr, tg, tb = hex_to_rgb(tint)
 
    for n in range(1, 5+1):
 
        scl = strength * nsin(songTime + n * .3)**3
 
        col = literalColor(
 
            scl * lerp(nsin(songTime + n * .2), tr/255, tintStrength),
 
            scl * lerp(nsin(songTime + n * .2 + .3), tg/255, tintStrength),
 
            scl * lerp(nsin(songTime + n * .3 + .6), tb/255, tintStrength))
 

	
 
        dev = L9['device/aura%s' % n]
 
        out.update({
 
            (dev, L9['color']): col,
 
            (dev, L9['zoom']): .9,
 
            })
 
        ang = songTime * 4
 
        out.update({
 
        (dev, L9['rx']): lerp(.27, .7, (n-1)/4) + .2 * math.sin(ang+n),
 
        (dev, L9['ry']): lerp(.46, .52, (n-1)/4) + .5 * math.cos(ang+n),
 
            })
 
    return out
 

	
 
def effect_orangeSearch(effectSettings, strength, songTime):
 
    dev = L9['device/auraStage']
 
    return {(dev, L9['color']): '#c1905d',
 
            (dev, L9['rx']): lerp(.31, .68, nsquare(songTime / 2.0)),
 
            (dev, L9['ry']): lerp(.32, .4,  nsin(songTime / 5)),
 
            (dev, L9['zoom']): .88,
 
            }
 
    
 
    tint = effectSettings.get(L9['tint'], '#ffffff')
 
    tintStrength = float(effectSettings.get(L9['tintStrength'], 0))
 
    print tint, tintStrength
 
    tr, tg, tb = hex_to_rgb(tint)
 
    for n in range(1, 5+1):
 
        scl = strength * nsin(songTime + n * .3)**3
 
        col = literalColor(
 
            scl * lerp(nsin(songTime + n * .2), tr/255, tintStrength),
 
            scl * lerp(nsin(songTime + n * .2 + .3), tg/255, tintStrength),
 
            scl * lerp(nsin(songTime + n * .3 + .6), tb/255, tintStrength))
 

	
 
        dev = L9['device/aura%s' % n]
 
        out.update({
 
            (dev, L9['color']): col,
 
            (dev, L9['zoom']): .9,
 
            })
 
        ang = songTime * 4
 
        out.update({
 
        (dev, L9['rx']): lerp(.27, .7, (n-1)/4) + .2 * math.sin(ang+n),
 
        (dev, L9['ry']): lerp(.46, .52, (n-1)/4) + .5 * math.cos(ang+n),
 
            })
 
    return out
 

	
 
def effect_Strobe(effectSettings, strength, songTime):
 
    rate = 2
 
    duty = .3
 
    offset = 0
 
    f = (((songTime + offset) * rate) % 1.0)
 
    c = (f < duty) * strength
 
    col = rgb_to_hex([c * 255, c * 255, c * 255])
 
    return {(L9['device/colorStrip'], L9['color']): Literal(col)}
 

	
show/dance2016/effect.n3
Show inline comments
 
@prefix : <http://light9.bigasterisk.com/> .
 
@prefix dev: <http://light9.bigasterisk.com/device/> .
 
@prefix effect: <http://light9.bigasterisk.com/effect/> .
 
@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#> .
 

	
 

	
 

	
 
#effect:usa a :mockupEffect; rdfs:label "USA"; :chaseOffset 0;
 
#     :chaseTempo 120; :code "chase()"; :devices dev:colorStrip, dev:moving1;
 
#     :fadeShape :fadeCurve1; :palette "#0000ff", "#ff0000", "#ffffff";
 
#     :publishAttr :strength .
 

	
 
effect:Strobe a :Effect; rdfs:label "strobe"; :publishAttr :duty, :offset, :rate, :strength .
 

	
 

	
 
effect:animRainbow a :Effect; rdfs:label "animRainbow"; :publishAttr :strength, :rate .
 

	
 

	
 
effect:animRainbow a :Effect; rdfs:label "animRainbow"; :publishAttr :strength, :rate ; :group "anim".
 

	
 
effect:usa a :mockupEffect; rdfs:label "USA"; :chaseOffset 0;
 
     :chaseTempo 120; :code "chase()"; :devices dev:colorStrip, dev:moving1;
 
     :fadeShape :fadeCurve1; :palette "#0000ff", "#ff0000", "#ffffff";
 
     :publishAttr :strength .
 
effect:orangeSearch a :Effect; :publishAttr :strength ; :group "anim".
 

	
 
effect:house :group "main" .
 
effect:cyc :group "main" .
 

	
 
effect:centerSpot a :Effect; rdfs:label "center spot";
 
     :group "main"; :order 3; :publishAttr :strength;
 
     :setting effect:centerSpots0, effect:centerSpots1, effect:centerSpots2, effect:centerSpots3, effect:centerSpots4 .
 
effect:centerSpots0 :device dev:q2; :deviceAttr :color;
 
     :scaledValue "#ffffff" .
 
effect:centerSpots1 :device dev:q2; :deviceAttr :focus;
 
     :value 0.31 .
 
effect:centerSpots2 :device dev:q2; :deviceAttr :rx;
 
     :value 0.50 .
 
effect:centerSpots3 :device dev:q2; :deviceAttr :ry;
 
     :value 0.26 .
 
effect:centerSpots4 :device dev:q2; :deviceAttr :zoom;
 
     :value 0.42 .
 

	
 

	
 
:fadeCurve1 a :Curve; :point :fc1p0, :fc1p1, :fc1p2, :fc1p3 .
 
:fc1p0 :time 0.00; :value 0 .
 
:fc1p1 :time 0.02; :value 1 .
 
:fc1p2 :time 0.10; :value 1 .
 
:fc1p3 :time 0.15; :value 0 .
 
:strength rdfs:label "strength" .
show/dance2016/song1.n3
Show inline comments
 
@prefix : <http://light9.bigasterisk.com/> .
 
@prefix dev: <http://light9.bigasterisk.com/device/> .
 
@prefix effect: <http://light9.bigasterisk.com/effect/> .
 
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
@prefix song: <http://light9.bigasterisk.com/show/dance2016/song1/> .
 
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
 
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 

	
 
:a01 :effectAttr :chaseOffset; :value 0.12 .
 
:ao0 :effectAttr :chaseTempo; :value 100 .
 
<http://light9.bigasterisk.com/show/dance2016/song1> :note song:n0, song:n3 .
 

	
 
song:n0 a :Note; :curve song:n0c0; :effectClass effect:centerSpot;
 
     :originTime 30.398 .
 
     :originTime 30.836 .
 

	
 
song:n0c0 a :Curve; :attr :strength; :point song:n0c0p0, song:n0c0p1, song:n0c0p2, song:n0c0p3 .
 
song:n0c0p0 :time 0.000; :value 0.000 .
 
song:n0c0p1 :time 1.000; :value 1.000 .
 
song:n0c0p2 :time 2.000; :value 1.000 .
 
song:n0c0p3 :time 3.000; :value 0.000 .
 
song:n0c0p2 :time 4.170; :value 1.000 .
 
song:n0c0p3 :time 5.772; :value 0.000 .
 

	
 
song:n3 a :Note; :curve song:n3c0; :effectClass effect:Curtain;
 
     :originTime 32.297 .
 
     :originTime 32.932 .
 

	
 
song:n3c0 a :Curve; :attr :strength; :point song:n3c0p0, song:n3c0p1, song:n3c0p2, song:n3c0p3 .
 
song:n3c0p0 :time 0.153; :value 0.000 .
 
song:n3c0p1 :time 1.000; :value 1.000 .
 
song:n3c0p2 :time 2.000; :value 1.000 .
 
song:n3c0p3 :time 2.928; :value 0.000 .
 
song:n3c0p3 :time 3.236; :value 0.000 .
0 comments (0 inline, 0 general)