Changeset - 01dd3928b635
[Not reviewed]
default
0 4 0
Drew Perttula - 9 years ago 2016-06-11 06:49:25
drewp@bigasterisk.com
KC can now fade in effects, which can be read from the graph
Ignore-this: 8e45e99e677204465ed362d667e2d192
4 files changed with 52 insertions and 60 deletions:
0 comments (0 inline, 0 general)
bin/keyboardcomposer
Show inline comments
 
@@ -446,12 +446,13 @@ class KeyboardComposer(tk.Frame, SubClie
 

	
 
    def get_output_settings(self):
 
        outputSettings = []
 
        for setting in graph.objects(self.session, L9['subSetting']):
 
            effect = graph.value(setting, L9['sub'])
 
            strength = graph.value(setting, L9['level'])
 
            if strength:
 
            outputSettings.extend(
 
                self.effectEval[effect].outputFromEffect(
 
                    [(L9['strength'], strength)], songTime=time.time()))
 

	
 
        return outputSettings
 

	
light9/effect/effecteval.py
Show inline comments
 
from __future__ import division
 
from rdflib import URIRef, Literal
 
from light9.namespaces import L9, RDF
 
from webcolors import rgb_to_hex
 
from webcolors import rgb_to_hex, hex_to_rgb
 
import math
 

	
 
def literalColor(rnorm, gnorm, bnorm):
 
    return Literal(rgb_to_hex([rnorm * 255, gnorm * 255, bnorm * 255]))
 

	
 
def scale(value, strength):
 
    if isinstance(value, Literal):
 
        value = value.toPython()
 
    if isinstance(value, basestring):
 
        if value[0] == '#':
 
            r,g,b = hex_to_rgb(value)
 
            return rgb_to_hex([r * strength, g * strength, b * strength])
 
    raise NotImplementedError(repr(value))
 
    
 
class EffectEval(object):
 
    """
 
    runs one effect's code to turn effect attr settings into output
 
    device settings. No state; suitable for reload().
 
    """
 
    def __init__(self, graph, effect):
 
        self.graph = graph
 
        self.effect = effect
 
        
 
        # effect : [(dev, attr, value, isScaled)]
 
        self.effectOutputs = {}
 
        
 
        #for ds in g.objects(g.value(uri, L9['effectClass']), L9['deviceSetting']):
 
        #    self.setting = (g.value(ds, L9['device']), g.value(ds, L9['attr']))
 

	
 
        self.graph.addHandler(self.updateEffectsFromGraph)
 

	
 
    def updateEffectsFromGraph(self):
 
        self.effectOutputs = {}
 
        for effect in self.graph.subjects(RDF.type, L9['Effect']):
 
            print "found fx", effect
 
            # stash known effects
 
            settings = []
 
            for setting in self.graph.objects(effect, L9['setting']):
 
                d = self.graph.value(setting, L9['device'])
 
                a = self.graph.value(setting, L9['deviceAttr'])
 
                v = self.graph.value(setting, L9['value'])
 
                sv = self.graph.value(setting, L9['scaledValue'])
 
                if not (bool(v) ^ bool(sv)):
 
                    raise NotImplementedError
 

	
 
                settings.append((d, a, v if v is not None else sv, bool(sv)))
 

	
 
            if settings:
 
                self.effectOutputs[effect] = settings
 
                print settings
 
        
 
    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.
 
        """
 
        attr, value = effectSettings[0]
 
        value = float(value)
 
        attr, strength = effectSettings[0]
 
        strength = float(strength)
 
        assert attr == L9['strength']
 
        c = int(255 * value)
 
        color = [0, 0, 0]
 
        # if it's a known effect, do the scaling thing. :strength is an effectSetting.
 
        if self.effect == L9['effect/RedStrip']: # throwaway
 

	
 
        out = []
 
        for dev, attr, value, isScaled in self.effectOutputs.get(self.effect, []):
 
            if isScaled:
 
                value = scale(value, strength)
 
            out.append((dev, attr, value))
 
            
 
        if self.effect == L9['effect/RedStripzzz']: # throwaway
 
            mov = URIRef('http://light9.bigasterisk.com/device/moving1')
 
            col = [
 
                    (songTime + .0) % 1.0,
 
                    (songTime + .4) % 1.0,
 
                    (songTime + .8) % 1.0,
 
                    ((songTime + .0) % 1.0),
 
                    ((songTime + .4) % 1.0),
 
                    ((songTime + .8) % 1.0),
 
                ]
 
            return [
 
            out.extend([
 
                # device, attr, lev
 
                
 
                (mov, L9['color'], Literal(rgb_to_hex([value*x*255 for x in col]))),
 
                (mov, L9['color'], Literal(rgb_to_hex([strength*x*255 for x in col]))),
 
                (mov, L9['rx'], Literal(100 + 70 * math.sin(songTime*2))),
 
            ] * (value>0)
 

	
 
        elif self.effect == L9['effect/BlueStrip']:
 
            color[2] = c
 
        elif self.effect == L9['effect/WorkLight']:
 
            color[1] = c
 
            ] * (strength>0))
 
        elif self.effect == L9['effect/Curtain']:
 
            return [
 
                (L9['device/lowPattern%s' % n], L9['color'], literalColor(0*value, value, value)) for n in range(301,308+1)
 
                ]
 
            out.extend([
 
                (L9['device/lowPattern%s' % n], L9['color'], literalColor(0*strength, strength, strength)) for n in range(301,308+1)
 
                ])
 

	
 
        elif self.effect == L9['effect/Strobe']:
 
            attr, value = effectSettings[0]
 
            assert attr == L9['strength']
 
            strength = float(value)
 
            rate = 2
 
@@ -72,19 +96,12 @@ class EffectEval(object):
 
            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)),
 
            ]
 
        else:
 
            color[0] = color[1] = color[2] = c
 

	
 
        return [
 
            # device, attr, lev
 
            (URIRef('http://light9.bigasterisk.com/device/moving1'),
 
             URIRef("http://light9.bigasterisk.com/color"),
 
             Literal(rgb_to_hex(color)))
 
            ]
 
        return out
 
        
 

	
 

	
 
    
show/dance2016/effect.n3
Show inline comments
 
@@ -17,13 +17,13 @@ effect:BlueStrip a :Effect;
 
  :publishAttr :strength;
 
  :deviceSetting :ds3 .
 
:ds3 :device dev:colorStrip; :attr :blue; :value "strength" .
 

	
 
:strength rdfs:label "strength" .
 

	
 
effect:usa a :Effect;
 
effect:usa a :mockupEffect;
 
  rdfs:label "USA";
 
  :publishAttr :strength;
 
  :code "chase()";
 
  :devices dev:colorStrip, dev:moving1;
 
  :fadeShape :fadeCurve1;
 
  :chaseTempo 120;
 
@@ -59,9 +59,10 @@ effect:WorkLight a :Effect;
 
:ds4 :device dev:colorStrip; :attr :color; :value "#00ff00" .
 

	
 
effect:Curtain a :Effect; rdfs:label "curtain"; :publishAttr :strength;
 
  :deviceSetting :ds5 .
 
:ds5 :device dev:colorStrip; :attr :color; :value "#300030" .
 

	
 
:live :controls effect:WorkLight, effect:Curtain .
 
:live :controls effect:WorkLight, effect:Curtain, effect:centerSpot .
 
effect:WorkLight :group "main"; :order 1 .
 
effect:Curtain :group "main"; :order 2 .
 
effect:centerSpot :group "main"; :order 3 .
 
\ No newline at end of file
show/dance2016/song1.n3
Show inline comments
 
@@ -5,40 +5,13 @@
 
@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:n1, song:n2, song:n3 .
 

	
 
song:n0 a :Note; :curve song:n0c0; :effectClass effect:Curtain;
 
     :originTime 35.653 .
 

	
 
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:n1 a :Note; :curve song:n1c0; :effectClass effect:Curtain;
 
     :originTime 39.152 .
 

	
 
song:n1c0 a :Curve; :attr :strength; :point song:n1c0p0, song:n1c0p1, song:n1c0p2, song:n1c0p3 .
 
song:n1c0p0 :time 0.000; :value 0.000 .
 
song:n1c0p1 :time 1.000; :value 1.000 .
 
song:n1c0p2 :time 2.000; :value 1.000 .
 
song:n1c0p3 :time 3.000; :value 0.000 .
 

	
 
song:n2 a :Note; :curve song:n2c0; :effectClass effect:Curtain;
 
     :originTime 43.806 .
 

	
 
song:n2c0 a :Curve; :attr :strength; :point song:n2c0p0, song:n2c0p1, song:n2c0p2, song:n2c0p3 .
 
song:n2c0p0 :time 0.000; :value 0.000 .
 
song:n2c0p1 :time 1.000; :value 1.000 .
 
song:n2c0p2 :time 2.000; :value 1.000 .
 
song:n2c0p3 :time 3.000; :value 0.000 .
 
<http://light9.bigasterisk.com/show/dance2016/song1> :note song:n3 .
 

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

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